5

I am trying to use FFMPEG (v.3.3.3) concat demuxer and as the file is stitched the audio drops at concat points. As I have files of same codecs, bitrates and so on - it doesn't make much sense to transcode again, so I really want to make concat demuxer to work.

I've had this problem with h.264 and aac. Here is how to recreate so you can see what I am talking about.

  1. Create test file with bars and tone (10s)

    ffmpeg -f lavfi -i "sine=frequency=1000:sample_rate=48000:duration=10" -f lavfi -i smptehdbars=size=1920x1080 -t 10 test.mp4

  2. Split the file into two using seeking

    ffmpeg -i test.mp4 -ss 0 -t 5 test-1.mp4

    ffmpeg -i test.mp4 -ss 5 -t 5 test-2.mp4

  3. Join the files together using concat demuxer

    ffmpeg -f concat -safe 0 -i <(for f in ./test-*.mp4; do echo "file '$PWD/$f'"; done) -c copy testconcat.mp4

This creates a file with clearly audible audio drop at 5s mark. To picture this here I've created two spectrograms by extracting audio.

  1. Extract audio

    ffmpeg -i test.mp4 test.wav

    ffmpeg -i testconcat.mp4 testconcat.wav

  2. Create spectrograms

    sox test.wav -n spectrogram -Y 130 -c "Input file" -o test.png

    sox testconcat.wav -n spectrogram -Y 130 -c "Concat file" -o testconcat.png

And here is the result:

Input File

Concat File

So my questions are:

  1. Can concat demuxer be used in such a way to avoid the described problem?
  2. Or what would you see as a solution (beyond full re-transcode)?
3
  • Transcode the audio of your inputs to PCM and save as MOV. Concat those.
    – Gyan
    Aug 28, 2017 at 10:30
  • @Mulvya - I know it's brief, but you could make a good answer from that comment.
    – Dr Mayhem
    Aug 28, 2017 at 15:53
  • MOV and MP4 almost same container
    – bukkojot
    Aug 30, 2017 at 17:35

2 Answers 2

0
ffmpeg -i test.mp4 -ss 0 -t 5 test-1.mp4
ffmpeg -i test.mp4 -ss 5 -t 5 test-2.mp4

This is the root of evil. You almost never can split your audio/video with very high precise. Reasons for it:

  1. Non-integer FPS in video. You can't split non-integer number of frames, so if you use 29.997 fps, you can't get 149.985 frames in file.
  2. Audio codecs compress audio samples in blocks of samples, for example, in 1024 samples per second. So, if you split your sound in 5 second and sound has samplerate 44100Hz, you can only get 44100*5/1024=215.332 frames, this is too not integer. Actually, here you get small drop. Some codecs always add some silent frames at end, mp3 do in that way. Only one exception I know: pcm (any kind), this "codec" can save any count of frame, with no rough.

So, in conclusion, if you want split and concatenate files without loss:

  1. use integer count for fps
  2. use codecs what can encode any count of samples without rough or padding.
1
  • could you explain how to use integer count for fps for #1. Also Michal - how did you solve your problem
    – Garuuk
    Feb 14, 2023 at 5:27
0

The problem you're describing with blanks between each segment is due to priming samples. This can be removed with the inpoint directive. However, for it to be completely seamless, there's a bit more to do.

To concat seamlessly with no gaps, you can do the following:

  1. Calculate the AAC frame length based on the sample rate, e.g. 1024/44100 = 0.02321995 for 44.1KHz.
  2. Encode an extra 2 AAC frames at the beginning and end of each segment.
  3. Account for the 2 silent padding frames that ffmpeg always adds internally.
  4. Assign inpoint and outpoint directives in the concat txt file so that only the "good" content is used when creating the output file.

The 2 extra beginning frames are required because each AAC frame is dependent on up to 2 frames before it. So to encode the first frame correctly, it needs that context. The 2 extra frames at the end are required because ffmpeg tapers the audio at the end to avoid a sudden pop. By adding 2 extra frames, we shift the taper so it doesn't affect our actual content. These extra frames are then removed with inpoint and outpoint to avoid repeated content.

Using this method, it's important that all segments have a length that's an exact multiple of an AAC frame duration. If they don't, you will see unpredictable artifacts at segment boundaries.

I recently released a repo that demonstrates this further with actual code: https://github.com/wistia/seamless-aac-split-and-stitch-demo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.