Please be forgiving to a video file format newbie, who has travelled far and wide all over the Web in search of a relatively simple question and hoped to get an answer (even a fairly complicated one would be fine!):
TL;DR: I have a broken MP4 which lacks a MOOV atom (neither at the beginning nor at the end). So, how do I create a new MOOV atom in order to fix the file?
And now for the expanded question (if you bother to read it), which shows the homework I've done so far...
What solutions I've found so far...
A quick search just here on video.stackexchange.com will get you a few dozens of similar questions and variations on the theme; do that search on Google, and you'll get a few hundreds more; even Quora has a few answers... To summarise most of them, here is what they usually say:
- "MP4 files can have a MOOV atom at the end (that's the usual way) but also at the beginning; here's a selection of N solutions to move the atom from one place to the other" (no, they aren't useful if you have no MOOV atom whatsoever)
- "You can use
ffmpeg
(or a gazillion similar utilities — most of which will useffmpeg
's library anyway — or even VLC [some versions seem to have a way to automatically fix broken videos — not my case, though]) to somehow magically extract part of your broken file, split it into bits, or even split it into individual frames, then reencode, and eventually you'll get a few sequences of frames out of the corrupted video, or even, with luck, a bit of continuous video which will play (sometimes only under VLC, sometimes only undermplayer
, sometimes requiring [insert favourite video player here])" (all these suggestions are very nice, but all assume that at least there is a MOOV atom somewhere — or else all will fail) - "Some tools (or commercial applications) can deal with corrupt data on faulty disks/pen drives/memory cards, by reading sectors directly from the underlying media and bypassing the FAT or whatever filesystem layer is used by the operating system, thus at least being able to recover part of your video, even if it's (possibly) out of order, incomplete, etc." (this may all be true, but does not help in my case, where the file is pristine and there is no problem whatsoever with the hardware where it's currently stored — the file is just missing a MOOV atom, so none of these tools will help)
- "A few tools, such as
untrunc
, may be able to repair a broken file, especially if the MOOV atom is missing at the end of the file because the video camera abruptly had its power cut (or some similar situation). There are also several commercial software solutions available which do the same (and are easier to use) or even web-based ones. Commercial applications usually have a demo/trial mode where you can at least recover some data to give you an idea if your particular file is repairable or not. Usually, such software requires a video made by the same video camera under the same circumstances, to be able to push the missing data from that video to the corrupt file." (so far, I've not managed to find the 'magic tool' which does exactly what is claimed... all I've tested will fail with a missing MOOV atom... no matter if the 'test video' has it, which could easily be copied — assuming that this will 'fix' anything, of course).
Why none of the above actually helped me out
Things may be explained a bit differently in one case or another, but after going through dozens of descriptions of 'solutions' out there, I'd say that most will fall in one of those four cases. The fourth case, of course, is the only one that may help in my case, but, so far, I've tried pretty much everything which can run on a Mac — aye, including a few commercial apps — and none will deal with the issue.
I've also found out that many of these tools — especially those that are commercial! — are little more than a GUI to ffmpeg
/libav
. Some even use hopelessly outdated versions of these; in some cases, they're compiled with them statically; in other cases, ffmpeg
and its friends are packed with the application, which just calls it with whatever special parameters the developers have figured out that might help (or even work!) in most cases.
While I'm pretty sure that some of the tools I tried out may have non-ffmpeg
/libav
code, they haven't worked, either. What I seem to be able to conclude is that anything depending on ffmpeg
/libav
code will not work without a valid MOOV atom. Therefore, the trick — if there's one! — is to somehow 'extract' a MOOV atom from either a different file and/or re-create the MOOV atom from the existing data. While the former seems to be the most popular approach (and, as said, I've tested a dozen or so apps using that approach), none worked in my case; as to the latter approach, if it exists at all, it's not explicitly named in any of the tools I've tested out, so I cannot say if that's possible at all (i.e. it may be a very obscure and undocumented feature of ffmpeg
but, so far, I have not come across an answer which mentions such feature; of course, commercial tools, for obvious reasons, may simply not document what exactly their tool is doing 'under the hood').
Whew. Wordy, I know! Let me just give you some assurance that, although I hardly understand what I'm talking about — namely, the complex structure of an MP4/MOV file — I have certainly done my best to figure out what is wrong with my file, and why all attempts I've tried out so far have utterly failed. My apologies in advance if I'm assuming wrong things about the MP4 format and/or just saying rubbish which makes no sense (such as 'reconstructing a MOOV atom out of existing frames on a movie' — perhaps such a thing is impossible to do, for reasons I don't understand).
What I know about my file...
- It certainly has data in it (i.e. not just garbage). Several of those utilities correctly figure out that it's a QuickTime stream; some can even identify a few atoms.
Here is an example from mp4dump
:
[ftyp] size=8+12
major_brand = qt
minor_version = 0
compatible_brand = qt
[wide] size=8+0
And this is the output from mp4info
:
File:
major brand: qt
minor version: 0
compatible brand: qt
fast start: yes
No movie found in the file
(weird that it knows about 'fast start', though...)
Here is the output of my own hacked utility (see below):
[ftyp]
Major brand: qt
Minor brand: 0
Compatible brands: [qt ]
[wide]
Size: 8
Start: 20
[mdat]
Size: 2305577342
Start: 28
But none can find a single MOOV atom. Photoshop can import 'noise' from some frames — they look like frames, though, just so noisy that they become 'random pixels', that is, it's pretty much impossible to figure out what exactly that frame is supposed to be...
- I have 'similar' files, generated by the same video camera (the iPhone 8's 'selfie' camera in landscape format), so I can easily extract an existing MOOV atom (or any other) and 'glue' it elsewhere on an existing file, a procedure many of the mentioned tools consider a possible solution to a 'missing' MOOV atom — but none are actually able to do that with my video...
What I can theoretically do to fix things
(or: An attempt to start to answer my own question...)
I'm just a humble amateur programmer, which means that fully developing a new tool in order just to fix my own video is very likely out of the question (and furthermore I have no time for that). The best I can promise to do if nobody has an answer is to figure out how MP4 encoders actually generate a MOOV atom from the existing data and see if I can adapt an existing tool to 'regenerate' the MOOV atom from scratch (note: I did hack it a bit to show the contents of all atoms it can find inside the file when the MOOV atom is missing, the output of which I've given before)... alas, I think that this might be impossible if one does not know some basic things about the video file itself (after all, these 'basic things' are stored on the MOOV atom!), but I'm happy to be proven wrong on that — especially because I can 'guesstimate' many of those 'basic things' by simply reading the MOOV atom from a video file generated under similar circumstances...
Here is such an example (tracks 3 and 4 are not really fundamental):
found avc1
File:
file Size: 16072874
brands: qt , [qt ]
Movie:
duration: 6859 ms / 600 (00:00:11:431)
fragments: false
timescale: 600
Found 4 Tracks
Track 1:
flags: 15 ENABLED IN-MOVIE IN-PREVIEW
id: 1
type: Video
duration: 6859 ms
language: und
width: 1920
height: 1080
media:
sample count: 184
timescale: 600
duration: 6859 (media timescale units)
duration: 11431 (ms)
display width: 1920
display height: 1080
frame rate (computed): 16.10
Track 2:
flags: 15 ENABLED IN-MOVIE IN-PREVIEW
id: 2
type: Sound
duration: 6859 ms
language: und
width: 0
height: 0
media:
sample count: 495
timescale: 44100
duration: 506880 (media timescale units)
duration: 11493 (ms)
Theoretically, with a bit more hacking, I can also extract the precise position where each track begins and ends (assuming that's how the MP4 format works!) and whatever information may be needed to 'reconstruct' the MOOV atom...
What help I actually need
I do have access to the PDFs with the ISO/IEC 14496-12 standard which defines the MP4 file format but I haven't read them yet. In essence, what I need to understand is how MOOV atoms are created/generated from existing video data. I'm fine with downloading and installing any tool which I haven't mentioned previously (so long as they work either under macOS or any non-GUI Linux — I might be able to temporarily get access to a Windows 10 machine if I'm assured that there is a solution that will work under Windows). I'm also willing to change or adapt existing open-source tools, so long as I can get some pointers on how to actually 'generate' the MOOV atom from existing video data (preferably written in Go
or PHP
, but I'm ok with C
, C++
, C#
or Python [in decreasing order of preference], or, well, Perl or JavaScript... I'm just not willing to install Java :-P and I'd really need a lot to get persuaded to use Ruby, Rust, or whatever language is currently fashionable...).
If you read until the end, my heartfelt thanks in advance :-)