我正在关注如何使用ffmpeg concatenate文件的文档,但在此过程中我看到很多警告,输出视频在第一个块之后停止,但音频继续播放。
这是我用来连接文件的命令:
ffmpeg -f concat -i mylist.txt -c copy output.webm
这是我看到的警告:
[concat @ 0x7fee11822a00] DTS 0 < 2500 out of order
[webm @ 0x7fee11011000] Non-monotonous DTS in output stream 0:0; previous: 2500, current: 0; changing to 2500. This may result in incorrect timestamps in the output file.
视频文件来自外部来源。我目前的解决方案是将每个文件重新编码为mp4,然后将它们连接在一起,然后将整个文件重新编码回webm。原因是,这需要一些重要的时间,但我找不到另一种解决方案。
答案 0 :(得分:6)
您的问题是由-c copy
复制参数引起的。正如参数的名称所暗示的那样,它将复制源编码。由于每个文件都有不同的时间戳,可能从零开始,因此会收到很多警告。 concat demuxer在输入文件中也需要相同的编解码器,因此请确保它们不会混合。
解决方案是通过指定要用于输出的编解码器来重新编码,例如。 -c:v libvpx-vp9 -c:a libopus
。
答案 1 :(得分:3)
经过几天的调查,我发现让视频具有相同的fps将解决这个问题。
如果a.mp4和b.mp4有不同的fps,请用30(自定义)fps更新它们
ffmpeg -i a.mp4 -vcodec mpeg4 -vf fps=30 a.output.mp4
ffmpeg -i b.mp4 -vcodec mpeg4 -vf fps=30 b.output.mp4
将视频路径写入一个文件
echo "file a.output.mp4" > videos.txt;
echo "file b.output.mp4" > videos.txt;
联系
ffmpeg -f concat -i videos.txt -c copy final.mp4
答案 2 :(得分:2)
我修复了我的问题,我没有使用ffmpeg,而是使用mkvmerge命令使用mkvtoolnix。
答案 3 :(得分:1)
以下是连接一组mp4视频文件时解决“DTS乱序”错误的方法。它还避免重新编码。
虽然在处理过程中您通常仍会看到控制台窗口中报告的“乱序”错误消息,但串联仍然会成功(并且不会丢失同步)。
在批处理文件中运行此代码。我是在运行Windows 7的机器上写的。
:: *** Concatenate .MP4 files : Stream Copy ***
:: You can't concatenate .mp4 files. You have to convert them to an
:: intermediate format that can be concatenated, such as .mpg:
::
:: 1. Convert the .mp4 videos to .mpg, using ffmpeg.
:: 2. Then run a file level concatenation command on
:: the .mpg files, to create a combined .mpg file.
:: 3. Convert the concatenated .mpg file to .mp4,
:: using ffmpeg.
:: If the mp4 files contain a h264 stream, use the .TS format (MPEG-TS)
:: as the intermediate format (instead of .MPG)
:: Convert the .MP4 files to intermediate .TS
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input2.ts
ffmpeg -i input3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input3.ts
ffmpeg -i input4.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input4.ts
ffmpeg -i input5.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input5.ts
:: MP4 Options
SET options=-bsf:a aac_adtstoasc -movflags faststart
:: Concatenate the TS files & Convert the output back to MP4
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts|input4.ts|input5.ts" -c copy -video_track_timescale 25 %options% -f mp4 -threads 1 output.mp4
:: Report
echo. & ffmpeg -i input1.mp4 -f nul
echo. & ffmpeg -i input1.ts -f nul
echo. & ffmpeg -i output.mp4 -f nul
答案 4 :(得分:0)
所有用于FFMPEG的视频都应具有匹配的编码,fps等,否则您将得到意想不到的结果。 我想,如果您的视频来自其他来源,那么不重新编码就很难解决。我必须查看许多解决方案,但可行的建议将建议将视频转换为相同的中间格式,然后运行concat命令。
尽管这种方法确实有效,但不能解释出什么问题了。 Gyan's comment answers it。
首先,使用ffprobe测试您的输入文件:
ffprobe video1.mp4
您将获得类似这样的输出。
video1.mp4:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 1556 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
video2.mp4:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 6454 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc (default)
即使我的FPS和其他参数相同,我也能以3.1 fps的速度拍摄58秒的视频,而不是预期的24秒的8秒的视频。此处的重要参数是时基 tbn ,即12288 tbn
与90k tbn
。
并置不会重新编码输入视频,仅使用第一个输入视频的时基来弄乱所有后续视频。
更改第一个文件的时基:
ffmpeg -i video1.mp4 -video_track_timescale 90000 video1_fixed.mp4
现在串联产生正确的结果:
( echo file 'video2.mp4' & echo file 'video1_fixed.mp4' ) | ffmpeg -y -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -c copy output.mp4
答案 5 :(得分:0)
我解决这个问题的方法是在执行 concat 之前先获取我想要连接的 mp4 并将它们转换为 .ts
。
echo > concat.txt
for filename in file1 file2 file3; do
ffmpeg -y -i "$filename.mp4" -c:a copy -c:v copy -bsf:v h264_mp4toannexb -f mpegts "$filename.ts"
echo "$filename.ts" >> concat.txt
done
ffmpeg -y -f concat -i "concat.txt" -c copy "out.mp4"