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
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:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0]; \
[1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1]; \
[2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,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
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:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0]; \
[1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1]; \
[2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,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:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0]; \
[1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1]; \
[2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,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
来源:https://stackoverflow.com/questions/57366845/how-to-concatenate-videos-in-ffmpeg-with-different-attributes