videomend - Media Rescue Lab ============================ WHAT IT IS videomend is a command-line container inspector for video files. It opens an MP4, MOV, M4V or 3GP file and walks its ISO base media file format (ISO-BMFF) box tree - ftyp, moov, mdat, free, moof and the rest - box by box, decoding each box's offset, size and type straight from the raw bytes. For AVI it walks the RIFF chunk structure and decodes the avih main header. From that structure alone it can usually tell you why a file will not play. That is a structural question, and structural questions can be answered without a single line of codec code. "Where does the movie index live?" "Does this box claim more bytes than the file actually contains?" "Is there an mdat full of video with no moov to describe it?" Those are the questions videomend answers. WHAT IT DOES NOT DO - PLEASE READ THIS videomend DIAGNOSES container structure. It does NOT repair files. It does NOT re-encode, remux, transcode or convert anything. It does NOT play video. It never writes to, moves or modifies the file you point it at: every file is opened strictly read-only, and the only thing videomend ever writes is text to your terminal. Most importantly: videomend CANNOT tell you whether the actual audio and video streams inside the file are intact. Judging that needs codecs - an H.264, HEVC, AAC or MJPEG decoder that can walk the compressed bitstream and check that the frames decode. videomend has no decoders and deliberately does not try. A file can pass every check here - perfect box tree, perfect sizes, moov in the right place - and still show green smears or silence, because the bytes inside mdat were corrupted in place. Equally, a file that fails these checks is definitely broken as a container, whatever shape its streams are in. So: PASS here means "the container is well formed", not "the video is good". COMMANDS videomend inspect [--json] Walk the container and report it. For MP4/MOV: every top-level box with its offset, size, type and size form, plus the ftyp major brand, minor version and compatible brands, and from moov/mvhd the timescale, the duration in timescale units and in seconds, and the creation and modification times. For AVI: the RIFF/LIST/chunk structure and the avih main header - frame size, microseconds per frame, frame rate, frame count, duration, stream count and flags. videomend diagnose [--json] A plain-language verdict on playability. Each check is PASS, WARN or FAIL: * ftyp present, and is it the first box? * moov present? A file with mdat but no moov is the classic interrupted recording, and videomend says so in as many words. * is moov after mdat? Then the file must be downloaded in full before it can start playing, and it wants a faststart pass. Reported as a warning, not damage. * does any box claim a size that runs past the end of the file? That is truncation, and the offending box is named. * is there trailing data after the last box? * do the box sizes tile the file exactly, with no gaps and no overlaps? AVI files get the equivalent checks: RIFF header, hdrl header list, avih, movi frame list, idx1 index, chunks past EOF, trailing data, tiling. videomend tree The nested box or chunk tree, indented, with offset, size and end offset on every line, so a technician can see the whole structure at a glance. videomend help videomend -h videomend --help Show usage. OPTIONS --json Emit machine-readable JSON (inspect and diagnose). -h, --help Show usage. Flags may be written before or after the file name; both work. EXIT STATUS 0 success. For diagnose: no check failed (warnings are still exit 0). 1 usage error, or the file could not be opened, or it is not an MP4/MOV or AVI file at all. 2 diagnose found at least one FAIL check. BOX SIZE FORMS ISO-BMFF has three ways to write a box size, and videomend handles all three, because getting them wrong is the classic box-parser bug: * the ordinary 32-bit size in the first four bytes of the header; * size == 1, meaning a 64-bit largesize follows the type field, so the header is 16 bytes instead of 8 - this is how files larger than 4 GiB store mdat; * size == 0, meaning "this box runs to the end of the file", which recorders use for the mdat they are still writing. A size smaller than the header it belongs to, or a 64-bit size larger than any real file, is reported as corruption rather than being trusted. EXAMPLES videomend inspect clip.mp4 videomend inspect clip.mp4 --json | jq .boxes videomend diagnose interrupted.mp4 videomend diagnose --json capture.avi videomend tree clip.mov # Triage a folder of dashcam files and list the broken ones: for f in *.mp4; do videomend diagnose "$f" >/dev/null || echo "BROKEN: $f"; done TYPICAL FINDINGS AND WHAT THEY MEAN "NO moov BOX, but there is an mdat box" The single most common real-world failure. The recorder writes media data into mdat as it goes and writes the moov index only when you press stop. Battery died, card was pulled, app crashed, phone rebooted - so the index was never written. The video data is very probably still sitting in mdat, but no player can use it, because nothing tells it where frames begin, what codec they use or how fast to play them. Recovery means rebuilding a moov, which needs a reference clip from the same camera in the same mode. videomend does not do that today; see the roadmap. "TRUNCATED: mdat at offset N claims X bytes" The file is shorter than its own headers say. A copy that did not finish, a full disk, a failing card, an interrupted download. "moov is at offset N, AFTER mdat" Fine on local disk. Bad for streaming, because the player needs the index before it can start and the index is at the end of the file. ROADMAP * Rebuilding a moov from the samples found in mdat, using a reference file recorded by the same device, so interrupted recordings become playable. * Matroska and WebM (MKV/WebM EBML element tree) alongside ISO-BMFF and RIFF. * Codec-level frame validation: walking H.264/HEVC NAL units and AAC frames to check that the compressed data really is intact, which is the one question the structural parser cannot answer. BUILD go build -o videomend . Go standard library only. No third-party dependencies, no network access, no build tags. GOPROXY=off go build works. PART OF THE TECHLOSOFT MEDIA RESCUE LAB mediarescue photo triage photorevive photo repair cardrecovery carving deleted files off a card videomend video container structure (this program)