我在查找可以获取视频文件(最好是avi,mkv和mp4)的cli应用程序时遇到麻烦,并且可以精确地切出很短的剪辑(2-6秒)。我尝试了ffmpeg,mencoder,avidemux和mp4box,但它们都在关键帧上剪切,这会创建6个以上的第二个剪辑。有没有一种工具可以对输入文件进行重新编码并削减准确的时间,或者不正确地剪切,重新编码然后进行准确的削减?
-ss
参数放置在之后 -i
),它应该会更加准确。
我在查找可以获取视频文件(最好是avi,mkv和mp4)的cli应用程序时遇到麻烦,并且可以精确地切出很短的剪辑(2-6秒)。我尝试了ffmpeg,mencoder,avidemux和mp4box,但它们都在关键帧上剪切,这会创建6个以上的第二个剪辑。有没有一种工具可以对输入文件进行重新编码并削减准确的时间,或者不正确地剪切,重新编码然后进行准确的削减?
-ss
参数放置在之后 -i
),它应该会更加准确。
Answers:
ffmpeg
您可以使用FFmpeg准确剪切视频。从2.5版开始,这非常容易。例如,从0分钟,3秒和123毫秒开始,这将减少10秒。
ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4
位置和时间可以是秒,也可以是hh:mm:ss[.xxx]
形式。
请注意,在这些示例中,将使用x264编码器对视频进行重新编码。音频被复制。
您也可以使用-to
而不是-t
指定终点而不是持续时间。但是,在这种情况下,-to
等效于-t
,因为ffmpeg 通过将放在的-ss
前面-i
,将首先搜索到该点,然后开始输出。
另请参阅寻求 Wiki条目。
ffmpeg
版本如果您使用的是ffmpeg的旧版本,则为了进行精确查找,您需要放置-ss
after -i
,这会使编码过程稍慢一些,因为必须首先对整个视频进行解码:
ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4
在这里,-to
和-t
不同的表现。-t 10
将创建一个十秒钟长的剪辑,而-to 10
将创建一个七秒钟长的剪辑。
-c:v libx264 -c:a libfaac
我认为我们可以使用-acodec copy -vcodec copy
ffmpeg来检测和使用与原始文件相同的编解码器,而不是我想。谁能确认?
-c:a aac -strict experimental
。那是最简单的解决方案。
到目前为止,我发现的唯一可以精确切割帧(或精确到帧)的Linux命令行工具是melt
(sudo apt-get install melt
)。
假设您有一个inputvid.mp4
-首先使用说说检查其编码设置ffmpeg
(在这里,我只是说我想再次将其编码为-f mp4
,但是作为文件,/dev/null
因此输出被丢弃;我重定向了stderr以便可以grep通过它-注意中间,该命令会提示,并且您应该y
使用ENTER进行回答,因此该过程将继续进行并转储有用的信息;这是在Ubuntu 14上的ffmpeg 3.3.3):
ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
encoder : Lavf57.71.100
Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
encoder : Lavc57.89.100 libx264
Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
encoder : Lavc57.89.100 aac
好的,这样我们就可以看到该视频的ffmpeg
选择libx264
和aac
编码器;然后我们可以输入melt
:
melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264
....,melt
并将第7235和7349帧之间的片段剪切为一个新文件cut.mp4
。然后要检查cut.mp4
循环是否正确,请melt
再次使用它播放两次-并将其播放到SDL窗口中:
melt cut.mp4 cut.mp4 -consumer sdl
...这是ffmpeg
该文件的内容:
ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder' encoder : Lavf54.20.4
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
encoder : Lavf57.71.100
Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
encoder : Lavc57.89.100 libx264
Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
encoder : Lavc57.89.100 aac
的视频编码设置cut.mp4
似乎与以下相同,inputvid.mp4
除了视频比特率从389 kb / s更改为526 kb / s,音频编码设置几乎相同,不同之处在于采样率从44100 Hz更改为48000 Hz。尽管可以通过以下方式进行调节:
melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k
...但是,即使这样,对我来说最终的视频比特率最终还是337 kb / s。仍然,当循环播放时,cuts循环很好(并且包括音频),所以我想这确实是帧准确的...
melt
重新编码视频,并使用下面的FFmpeg库。如果允许重新编码,则ffmpeg可以产生相同的输出。
melt
使用FFmpeg库的情况),很高兴知道!
就像鲍达德在评论中说的那样(我发帖是因为要快速阅读并不容易),更好的方法是通过ffmpeg自动检测音频/视频编码器,因此:
ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4