使用一行命令提取视频的部分内容

如果我有一个视频,通常是avi格式,但也可能是其他格式,我想创建另一个同样格式的视频,只包含原视频中从第i秒到第f秒的部分,那么如何用一行命令来实现这个功能?
4个回答

这可以使用 mencoderffmpeg 来完成。

mencoder

假设你想要从原始文件的00:00:30开始剪切一个长度为5秒的部分,并且不需要重新编码(如果你想要重新编码,你需要将 copy 替换为音频和视频编解码器,可以通过输入 mencoder -oac help 查看可用的音频编解码器列表,通过输入 mencoder -ovc help 查看可用的视频编解码器列表),然后你可以执行以下命令:

mencoder -ss 00:30:00 -endpos 00:00:05 -oac pcm -ovc copy originalfile -o newfile

你需要用实际的文件名替换orginalfilenewfile,后者是创建用于保存剪切部分的文件的名称。

ffmpeg

假设你想从原始文件的00:00:30开始剪切一个长度为5秒的部分,并且不希望重新编码(如果你想重新编码,你需要用音频和视频编解码器替换copy,要获取可用编解码器的列表,请输入ffmpeg -formats -E),然后你可以执行以下命令:

ffmpeg -ss 00:00:30 -i orginalfile -t 00:00:05 -vcodec copy -acodec copy newfile

你需要用实际的文件名替换orginalfilenewfile,后者是创建用于保存剪切部分的文件的名称。

参考http://lazyxiong-tech.blogspot.com/2007/05/using-mencoder-to-cut-out-pieces-of.htmlhttp://segfault.in/2010/10/ffmpeg-tricks-you-should-know-about/中的"7. Copy Only A Part Of Video"。


我尝试了,但失败了。你可以告诉我使用典型编解码器、针对 avi、flv 和 mpg 文件的命令是什么吗?我列举了那些编解码器,但无法很好地理解它们。 - Strapakowsky
@strapakowsky 这取决于输入文件和您安装的编解码器。也许您应该提出一个新问题,并附上关于您拥有的文件以及尝试的命令的信息。 - N.N.
@strapakowsky 我也无法让ffmpeg正常工作,但是所有关于使用ffmpeg剪辑视频的指南都表明它应该可以在某种程度上起作用,所以我将保留这个建议在我的回答中。不过,我还添加了一个mencoder命令行,我成功地让它工作了。 - N.N.
刚刚使用了这个版本。它对你不起作用是因为-ss ... -t ...需要放在-i infile选项之前。请参考这个答案获取真正的一行命令。你差点就成功了,只是顺序不对... - Hendy
1@Hendy 已经相应地进行了编辑 - N.N.
不对。-t标志必须放在-i选项之后。来源:http://superuser.com/questions/138331/using-ffmpeg-to-cut-up-video - Marco Sulla
也适用于avconv。如果您希望从开始点到视频结束,那么不需要使用-t选项。 - Antonios Hadjigeorgalis
请注意,mecoder默认会生成一个avi容器,如果负载通常不出现在avi容器中,这可能会让解码器感到困惑。您可以尝试选择libavformat容器(请参阅手册)。使用mplayer时也可能遇到各种奇怪的格式问题,但mplayer对此比较宽容。我建议您在分发之前使用像iTunes、Windows Media Player等简单的工具来测试您的视频。 - Craig Ringer
使用mplayer-2:1.2.1-1ubuntu1.1无法正确生成剪辑,但是ffmpeg-7:2.8.15-0ubuntu0.16.04.1完美运行:谢谢! - Tomislav Nakic-Alfirevic
需要添加扩展名,例如: ffmpeg -ss 00:00:30 -i orginalfile.mp4 -t 00:00:05 -vcodec copy -acodec copy newfile.mp4 - Salma Gomaa

你需要使用重新编码或不使用重新编码模式来剪辑视频吗? 你可以尝试以下命令。
简介: ffmpeg -i [输入文件] -ss [开始时间(秒)] -t [持续时间(秒)] [输出文件] 使用FFmpeg剪辑mp4视频而不重新编码
Example:
ffmpeg -i source.mp4 -ss 00:00:05 -t 00:00:10 -c copy cut_video.mp4

使用FFmpeg剪切mp4视频并重新编码。
Example:
ffmpeg -i source.mp4 -ss 00:00:05 -t 00:00:10 -async 1 -strict -2 cut_video.mp4

如果你想从开头剪切一段,只需在命令中去掉-t 00:00:10

2有一些需要考虑的事情:“在使用 -ss 作为输入选项时与 -c:v copy 一起使用可能不准确,因为ffmpeg被强制只能使用/分割i帧。尽管它会(如果可能的话)调整流的开始时间为负值来进行补偿。基本上,如果你指定“第157秒”,并且直到第159秒都没有关键帧,它将在开头包含两秒的音频(没有视频),然后从第一个关键帧开始。因此,在拆分和进行编解码复制时要小心。” https://trac.ffmpeg.org/wiki/Seeking 我通过省略 -c copy 得到了更准确的切割结果。 - joe
为什么需要使用“-async 1 -strict -2”?似乎没有它们也能正常工作。这条推文是否相关?https://twitter.com/ffmpeg/status/943266612047577089 - joe
“Cut” 的意思是什么?是指在原始文件中剪切并留下一个“空洞”,还是仅仅复制原始文件的某个部分? - chx101

medipack是一个非常简单的命令行应用程序,作为ffmpeg的包装器。

您可以使用以下命令来裁剪视频:

medipack trim input.mp4 -s 01:04 -e 14:08 -o output.mp4
medipack trim input.mp4 -s 01:04 -t 13:04 -o output.mp4

您可以查看 trim 子命令的选项:
srb@srb-pc:$ medipack trim -h
usage: medipack trim [-h] [-s START] [-e END | -t TIME] [-o OUTPUT] [inp]

positional arguments:
  inp                   input video file ex: input.mp4

optional arguments:
  -h, --help            show this help message and exit
  -s START, --start START
                        start time for cuting in format hh:mm:ss or mm:ss
  -e END, --end END     end time for cuting in format hh:mm:ss or mm:ss
  -t TIME, --time TIME  clip duration in format hh:mm:ss or mm:ss
  -o OUTPUT, --output OUTPUT

你还可以使用medipack -h来探索其他选项。
srb@srb-pc:$ medipack --help
usage: medipack.py [-h] [-v] {trim,crop,resize,extract} ...

positional arguments:
  {trim,crop,resize,extract}

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         Display version number

你可以访问https://github.com/srbcheema1/medipack并在README中查看示例。

更准确地说,你可以: 手动操作 在一个能够逐帧播放的媒体播放器中打开文件(我最喜欢的是PotPlayer,但MPC-HC也可以),并播放一个包含数据的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"

如果你想加入,请创建一个文本文件,其中包含视频文件的内容,例如:
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"

我写了一个程序,但是没有10级来展示它,抱歉。