使用ffmpeg剪切视频


333

我正在用ffmpeg切出像这样的大文件的一部分:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

-ss部分工作正常,但-t被忽略。它会正确删除指定的初始指定秒数,-ss但会一直到副本输入的末尾。

有没有一种方法可以使用ffmpeg切断视频的结尾而无需重新编码?


1
这种语法是正确的。
jiggunjer 2015年

Answers:


393

您可以使用该-ss选项指定开始时间戳记,并使用该-t选项指定编码持续时间。时间戳记必须采用HH:MM:SS.xxx格式或秒数(s.msec)。

下面的代码将剪切前30秒,然后剪切10秒之后的所有内容:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

请注意,这-t是一个输出选项,始终需要在之后 指定-i

一些技巧:

  • 对于较旧的ffmpeg版本,如果使用-ssafter -i,则可以获得更准确的查找,但要以完全缓慢的执行为代价。另请参阅:使用FFmpeg进行搜索
  • 您可以使用-to代替-t来指定要剪切的时间戳。因此,代替-i <input> -ss 30 -t 10您也可以做到-i <input> -ss 30 -to 40相同的事情。

  • 如果您的ffmpeg不支持-c-to,则可能非常过时。自己编译一个新版本,或从其主页下载静态版本。其实并不复杂。


1
@Mondain实际上,将-ss放在后面会获得更高的准确性。slhck在此处 blog.superuser.com/2012/02/24/… 也在ffmpeg文档中提供了-ss的内容,并提到了在此之前或之后的区别。
barlop

5
+1我来这里想知道如何在开始的35秒后忽略所有内容,谢谢:ffmpeg -i input.wmv -c copy -t 35 output.wmv
karlphillip 2014年

2
这对我不起作用(mp4)。它只会产生5秒的黑屏:frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s
Clocksmith

2
这在我的视频剪辑的开头产生了3-4秒的黑屏。克里斯(Chris)省略-c copy了修改,删除了最初的黑屏,有关详细信息,请参见他的答案。
joelostblom '16

4
您输入“以下内容将剪切前30秒,然后剪切10秒之后的所有内容:” <-这是什么意思?剪辑是指包含?'cos剪辑可能意味着剪辑出来。假设您的意思包括。您是说从30秒开始,仅包括10秒?如果是这样,那么我建议您写得更清楚一些。
barlop

94

正如其他人所提到的,-ss在(快得多)之前或之后(更准确)-i进行放置会产生很大的不同。ffmpeg查找页面上的“快速准确查找”部分介绍了如何同时获得这两种方法,而我已经用过它了,这有很大的不同。基本上,您将-ssAND 放在之前-i,只需确保在要开始切割的地方留出足够的时间,以得到另一个关键帧。示例:如果要在Video.mp4中制作从9min0sec到10min 0sec的1分钟剪辑,则可以使用以下命令快速而准确地进行剪辑:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

第一个-ss快速搜索到(大约)8min0sec,然后第二个-ss精确搜索到9min0sec,并-t 00:01:00取出一个1min0sec的剪辑。

还要注意该页面上的这一要点:“如果-ss与一起使用-c:v copy,则最终的比特流可能会变得断断续续,无法播放或与音频流不同步,因为ffmpeg仅被迫在i帧上使用/分割。 ”

这意味着即使您只想复制视频,也需要对其重新编码,否则可能会导致视频断断续续和不同步。您可以先尝试一下-c copy,但是如果视频不好,则需要重新进行操作。


同样的警告也适用-c:a copy于这种寻求方式。
jiggunjer 2015年

1
最好的答案,这种方式对我来说效果最好。
OndraŽižka16年

3
似乎在ffmpeg 2.1+中,“-ss”现在又快速又准确,而无需指定两次。 trac.ffmpeg.org/wiki/Seeking
康拉德·迈耶

25

我发现,-ss加上-c copy导致开始时出现了半秒的斩波。

为避免这种情况,您必须删除-c copy(必须进行转码)。


4
还有另一个涉及准确性的答案。使用默认选项重新编码通常不是您想要的!
Tomasz Gandor

好点@TomaszGandor
克里斯

1
我根本不理解@TomaszGandor的回复,但是删除了-c copy它。
Iulian Onofrei

14

手动

在将逐帧前进的媒体播放器中打开文件,并使用以下数据播放AVISynth文件

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

然后以精确时间格式剪切:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

现在用视频文件制作一个txt文件,其内容如下:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

运行ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"

9

对我而言,-t选项无效,但-vframes有效。我更喜欢使用#frames,因为我更喜欢使用I帧,并且使用找出了视频的GOP ffprobe

对我有用的命令行是:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

顺便说一句,放在-ss最前面-i会大大缩短执行时间。


1
实际上-vframes(或-frames:v)应该紧随其后,-i因为它是一个输出选项。
slhck

5

与user225366一样,-t选项不适用于短视频,但适用于较长的视频。对于短片,似乎-frames:v更好。这对我有用。

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

如果视频有音频,则需要添加-acodec复制,如其他答案所示。


0

我看不到很多提及(我不是专家,所以也许有收获),但是如果您的文件包含其他流(如字幕)和其他元数据(如章节等),则可以剪切/修剪并保留所有流。以下命令

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

随着-map 0你把所有的数据流文件中,并与-c copy您复制所有这些,因为它们。
使用-to省略开始过孔-ss将把输入视频从开始剪切到60秒。

map如果只希望将特定的流保留在剪辑中(可能不需要文件中的所有音频源,也不需要某些字幕),则进行整理也很有用。

当我需要分割无法存储在FAT32存储中的大MKV文件时,会使用此文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.