on the MP4 file before piping, so that the structural metadata (the “moov” box) is near the beginning of the file. Or you can devise another solution to rearrange the mp4 stream in the pipeline — although that may require buffering the entire video.
I see the same error from FFmpeg when I pipe an mp4 file whose
moov box is after the
mdat box. Many mp4 generators produce such files because it is the most convenient when recording, but for consuming (especially when streaming and piping) it is frequently better to arrange the file so that the
moov box comes before the
In your scenario, FFmpeg is scanning through the stream looking for the
moov metadata before beginning to process the video frames. After it parses the
moov metadata at the end of the file, it then attempts to seek back to the
mdat data near the beginning. Naturally, you cannot seek in pipe input. FFmpeg’s I/O abstraction layer (“avio”) does provide a limited capability to maintain a buffer in memory and allows seeks to occur within this buffer, but the buffer isn’t nearly large enough to contain an entire
mdat box (i.e. all the video frames!) so that libavformat can “seek” back to the beginning.
A few options you might consider:
- Run MP4Box (with the -hint argument) on your mp4 file before piping, to rearrange the mp4 file so that the
moovbox is at the beginning of the file.
- Perhaps FFmpeg’s avio buffer could be increased to a size that can accomodate the largest video file you anticipate processing. Then, the “seek back to the
mdatbox” will succeed because the buffer contains the entire file. Obviously, this would be very wasteful in terms of memory.
- If you absolutely require a pipeline solution, you could devise a program to accept mdat-before-moov mp4 on standard input, and write the translated moov-before-mdat stream to the standard output. This also requires buffering the entire file, which could be done in memory or in temporary files.
Curious that David didn’t suggest
qt-faststart being as he’s clearly an FFmpeg fan and it’s included with the source.
From the FFmpeg source dir:
./configure --disable-everything #(only needed if you haven't built ffmpeg already) make tools/qt-faststart chmod +x tools/qt-faststart sudo cp tools/qt-faststart /usr/local/bin #(optional step to move the binary to a PATH included directory)
You can then use it to move the moov atom to the beginning of the file, in this case:
qt-faststart video-2012-04-26-19-48-40.mp4 video-out-file.mp4