mltframework / mlt

MLT Multimedia Framework
https://www.mltframework.org
GNU Lesser General Public License v2.1
1.48k stars 314 forks source link

melt hickups #479

Closed paperbenni closed 4 years ago

paperbenni commented 4 years ago

When I try to merge multiple clips into one file, (melt clip1.mp4 clip2.mp4 -consumer avformat:output.mp4), it always stays on the last frame of every clip for a bit before showing the next one. I tried multiple kinds of clips, for some it's a few frames, for some it's over 3 seconds. Transitions can hide that, but make the transition too short and it becomes visible. My os is arch with melt from the main repo. Ryzen 1700 GTX 1060 proprietary drivers

ddennedy commented 4 years ago

MLT simply uses the FFmpeg library to get the duration. When there are not enough frames in the video stream, it repeats the last one. This often happens because the audio stream is longer than the video. See the output of ffprobe -show_streams to compare each stream's duration. This can also happen when you use variable frame rate source files, which MLT does not support. You can use mediainfo to see if reports variable. Sometimes, you need to set an appropriate out property on the producer instead of trusting whatever was determined from duration. Duration calculation is not something I am going to change as I have been here before a few times with people. When I tried to make length based on the shortest stream of a file, I got bug reports about data being discarded. So, I am no longer going to deviate from FFmpeg's duration.

paperbenni commented 4 years ago

@ddennedy The framerate is not variable and the issue occurs even if the video stream is longer than the audio stream. It also doesn't just repeat the last frame, it actually freezes for the last few frames while audio keeps playing. I tried with and without -shortest. The issue doesn't occur with pure ffmpeg or moviepy.

ddennedy commented 4 years ago

Maybe you are seeing something different than what I explained. To test this, I created 4 10-second clips at 25 fps with a burned in timecode and then concatenated them in a playlist:

melt color:red length=:10.0 -attach dynamictext -consumer avformat:red.mp4
melt color:green length=:10.0 -attach dynamictext -consumer avformat:green.mp4
melt color:blue length=:10.0 -attach dynamictext -consumer avformat:blue.mp4
melt color:white length=:10.0 -attach dynamictext -consumer avformat:white.mp4
melt red.mp4 green.mp4 blue.mp4 white.mp4 -consumer avformat:result.mp4

Stepping through this frame-by-frame in Shotcut, I see the last frame of red, green, and blue repeated twice. The last frame of white.mp4 is repeated 3 times. Looking at red.mp4 with ffprobe to see the stream durations, I can see the audio is 10.005 seconds:

ffprobe -show_entries format=duration:stream=duration red.mp4
[STREAM]
duration=10.000000
[/STREAM]
[STREAM]
duration=10.005000
[/STREAM]
[FORMAT]
duration=10.027000
[/FORMAT]

This partly explains why an extra frame is shown. The other part is that the H.264 and AAC codecs have a delay and their output buffers must be flushed, which results in this. If you use codecs without temporal compression and delay, you avoid this. This applies all of the inputs to result.mp4 as well as the output of result.mp4, which causes the extra frames.

Repeating the same but replacing "mp4" with "dv" everywhere produces a perfectly frame accurate result.

Doing something similar with ffmpeg command line: ffmpeg -f concat -safe 0 -i mylist.txt ffmpeg.mp4 For me, the result is it repeats the first frame twice of red, blue, and white.

paperbenni commented 4 years ago

I was actually using aac and h264. What codecs are recommended for melt?

ddennedy commented 4 years ago

for SD: dv for everything else video: ut video, dnxhd (including dnxhr profiles), ffv1, prores, huffyuv audio: pcm, alac, ac3

paperbenni commented 4 years ago

What is SD?

faridosc commented 4 years ago

What is SD?

Standard Definition (480p)