如何连接具有不同属性的ffmpeg中的视频? [英] How to concatenate videos in ffmpeg with different attributes?

查看:89
本文介绍了如何连接具有不同属性的ffmpeg中的视频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试合并一些视频,但出现时间戳错误。



我试图通过相同的尺寸,帧速率,采样率以及在没有音频轨道时添加音轨来使它们全部相等。

  lista = ['1.mp4','2.mp4','3.mp4'] 
路径='/ Downloads / abc /'
a = open('/ Downloads / abc / list.txt','w +')

i = 0
对于lista中的f:
i + = 1
位=路径+ str(i)+'test.mp4'
res =路径+ str(i)+'fixtest.mp4'
bb = check_output( shlex.split('ffprobe -i'+ f +'-show_streams -select_streams -loglevel错误'))
如果len(bb)== 0:
subprocess.call('ffmpeg -i' + f +'-y -i audio.mp3 -c:v复制-c:a aac-最短-严格实验'+ res)
subprocess.call('ffmpeg -i'+ res +'-y- ar 48000 -vf scale = 1280:720'+位)
else:
subprocess.call('ffmpeg -i'+ f +'-framerate 30 -y -ar 48000 -vf scale = 1280: 720个+位)
a.write( fil e' +路径+ str(i)+ test.mp4'\n)

a.close
subprocess.call('ffmpeg -y -safe 0 -f concat -i list.txt -c复制output.mp4')

错误消息如下:Non输出流0:0中的单调DTS;前一个:8052684,当前:4127401;更改为8052685。这可能会导致输出文件中的时间戳不正确。

解决方案

因为这纯粹是一个ffmpeg用法问题,将省略Python。由于我假设您的输入将是任意的,因此我建议使用concat过滤器而不是concat多路分配器,因为您将需要执行过滤以使所有内容均符合一组通用参数,并且您可以一次完成所有操作



制作所有视频1280x720、1:1 SAR,30 fps,yuv420p


使用比例(宽度x高度/分辨率), setsar (长宽比), fps (帧速率),格式(色度二次采样),和 concat (并置/加入)过滤器。


< pre class = lang-none prettyprint-ove rride> ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex \
[[0:v] scale = 1280:720:force_original_aspect_ratio =减少, pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v0];
[1:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v1];
[2:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v2];
[v0] [0:a] [v1] [1:a] [v2] [2:a] concat = n = 3:v = 1:a = 1 [v] [a] \
-map [v]; -映射 [a] -c:v libx264 -c:a aac -movflags + faststart output.mp4


与上述相同,但也处理音频立体声,采样率为48000


添加了 aformat (采样率和频道布局)过滤器。

  ffmpeg -i 1.mp4 -i 2.mp4-我3.mp4 -filter_complex \ 
" [0:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1:(oh-ih)/ 2,setsar = 1,fps = 30,format = yuv420p [v0];
[1:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v1];
[2:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v2];
[0:a] aformat = sample_rates = 48000:channel_layouts = stereo [a0];
[1:a] aformat = sample_rates = 48000:channel_layouts = stereo [a1];
[2:a] aformat = sample_rates = 48000:channel_layouts = stereo [a2];
[v0] [a0] [v1] [a1] [v2] [a2] concat = n = 3:v = 1:a = 1 [v] [a] \
-map [v] -映射 [a] -c:v libx264 -c:a aac -movflags + faststart output.mp4


为输入内容添加静音虚拟音频没有音频


anullsrc 过滤器如果您的输入之一不包含音频,则用于提供静音虚拟音频。这可能是必需的,因为要串联的所有段都必须具有相同数量和类型的流。

  ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -t 0.1 -f lavfi -i anullsrc = channel_layout = stereo:sample_rate = 48000 -filter_complex \ 
quot [[0:v] scale = 1280:720 :force_original_aspect_ratio =减少,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v0];
[1:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720:-1:-1,setsar = 1,fps = 30,format = yuv420p [v1];
[2:v] scale = 1280:720:force_original_aspect_ratio = decrease,pad = 1280:720 ::-1:-1,setsar = 1,fps = 30,format = yuv420p [v2];
[0:a] aformat = sample_rates = 48000:channel_layouts = stereo [a0];
[2:a] aformat = sample_rates = 48000:channel_layouts = stereo [a2];
[v0] [a0] [v1] [3:a] [v2] [a2] concat = n = 3:v = 1:a = 1 [v] [a] \
-map [v]; -映射 [a] -c:v libx264 -c:a aac -movflags + faststart output.mp4

注意:保持 -t 0.1 不变:anullsrc的持续时间只需要短于相关视频输入的持续时间。 concat过滤器将自动扩展无声音频以匹配相关视频输入的长度。


I'm trying to merge some videos but I'm getting timestamp errors.

I tried to make them all equal with the same dimensions, frame rate, sample rate and also by adding an audio track when there's none.

lista = ['1.mp4', '2.mp4', '3.mp4']
path = '/Downloads/abc/'
a = open('/Downloads/abc/list.txt', 'w+')

i = 0
for f in lista:
    i += 1
    places = path + str(i) + 'test.mp4'
    res = path + str(i) + 'fixtest.mp4'
    bb = check_output(shlex.split('ffprobe -i ' + f + ' -show_streams -select_streams a -loglevel error'))
        if len(bb) == 0:
            subprocess.call('ffmpeg -i ' + f + ' -y -i audio.mp3 -c:v copy -c:a aac -shortest -strict experimental ' + res)
            subprocess.call('ffmpeg -i ' + res + ' -y -ar 48000 -vf scale=1280:720 ' + places)
        else:
            subprocess.call('ffmpeg -i ' + f + ' -framerate 30 -y -ar 48000 -vf scale=1280:720 ' + places)
        a.write("file '" + path + str(i) + "test.mp4'\n")

a.close
subprocess.call('ffmpeg -y -safe 0 -f concat -i list.txt -c copy output.mp4')

The error messages look like this: Non-monotonous DTS in output stream 0:0; previous: 8052684, current: 4127401; changing to 8052685. This may result in incorrect timestamps in the output file.

解决方案

Because this is purely a ffmpeg usage question I'll leave out the Python. Since I'm assuming your inputs are going to be arbitrary I recommend using the concat filter instead of the concat demuxer because you're going to need to perform filtering anyway to conform everything into a common set of parameters and you can do everything in one command.

Make all videos 1280x720, 1:1 SAR, 30 fps, yuv420p

Using scale (width x height / resolution), setsar (aspect ratio), fps (frame rate), format (chroma subsampling), and concat (concatenation/joining) filters.

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

Same as above but also processes audio to be stereo with 48000 sample rate

Added the aformat (sample rate and channel layout) filter.

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];
 [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1];
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];
 [v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

Adding silent dummy audio for an input that does not have audio

This anullsrc filter is used to provide silent dummy audio if one of your inputs does not contain audio. This may be required because all segments to be concatenated must have the same number and type of streams.

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -t 0.1 -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720::-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];
 [v0][a0][v1][3:a][v2][a2]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

Note: Leave -t 0.1 as is: the duration of anullsrc only needs to be shorter than the duration of the associated video input(s). The concat filter will automatically extend the silent audio to match the length of the associated video input.

这篇关于如何连接具有不同属性的ffmpeg中的视频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆