{"record":{"id":"8a16d76f923d7f67","repo":"remotion-dev/remotion","slug":"movie-timescale-is-not-set","errorCode":null,"errorMessage":"Movie timescale is not set","messagePattern":"Movie timescale is not set","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/process-box.ts","lineNumber":399,"sourceCode":"\tif (boxType === 'trak') {\n\t\tif (!onlyIfMoovAtomExpected) {\n\t\t\tthrow new Error('State is required');\n\t\t}\n\n\t\tconst {tracks, onAudioTrack, onVideoTrack} = onlyIfMoovAtomExpected;\n\n\t\tconst trakBox = await parseTrak({\n\t\t\tsize: boxSize,\n\t\t\toffsetAtStart: fileOffset,\n\t\t\titerator,\n\t\t\tlogLevel,\n\t\t\tcontentLength,\n\t\t});\n\n\t\tconst movieTimeScale =\n\t\t\tonlyIfMoovAtomExpected.movieTimeScaleState.getTrackTimescale();\n\t\tif (movieTimeScale === null) {\n\t\t\tthrow new Error('Movie timescale is not set');\n\t\t}\n\n\t\tconst editList = findTrackStartTimeInSeconds({movieTimeScale, trakBox});\n\t\tconst transformedTrack = makeBaseMediaTrack(trakBox, editList);\n\n\t\tif (transformedTrack && transformedTrack.type === 'video') {\n\t\t\tawait registerVideoTrack({\n\t\t\t\ttrack: transformedTrack,\n\t\t\t\tcontainer: 'mp4',\n\t\t\t\tlogLevel,\n\t\t\t\tonVideoTrack,\n\t\t\t\tregisterVideoSampleCallback:\n\t\t\t\t\tonlyIfMoovAtomExpected.registerVideoSampleCallback,\n\t\t\t\ttracks,\n\t\t\t});\n\t\t}\n\n\t\tif (transformedTrack && transformedTrack.type === 'audio') {","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/process-box.ts#L381-L417","documentation":"Thrown in processBox() while handling a trak box. movieTimeScaleState.getTrackTimescale() returned null, meaning the movie timescale (set when an mvhd box is parsed) was never established before this trak was processed. The timescale is required to convert edit-list offsets to seconds, so the parser aborts the trak.","triggerScenarios":"parseMedia({src}) on a file whose moov box contains a trak box before (or without) an mvhd box. Per the ISO spec the mvhd should precede all trak boxes; if a trak is encountered first, or moov lacks an mvhd entirely, the timescale is still null and this fires.","commonSituations":"Non-compliant muxers that order trak before mvhd inside moov; moov boxes missing mvhd; reordered/edited moov atoms; corrupted moov structure.","solutions":["Re-mux with a compliant tool to fix box ordering: ffmpeg -i in.mp4 -c copy -moov_size 0 out.mp4 (or simply ffmpeg -i in.mp4 -c copy out.mp4).","Validate with MP4Box -info or ffprobe; a missing/misplaced mvhd is flagged.","Re-fetch the source if you suspect corruption.","Migrate to @remotion/mediabunny (parseMedia is deprecated)."],"exampleFix":"// before\nconst {tracks} = await parseMedia({src, reader: nodeReader});\n\n// after\ntry {\n  const {tracks} = await parseMedia({src, reader: nodeReader});\n} catch (err) {\n  if (err instanceof Error && /Movie timescale is not set/.test(err.message)) {\n    // moov has no/late mvhd; re-mux to fix box ordering\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Validate moov/mvhd ordering with MP4Box before parsing:\n//   MP4Box -info in.mp4\nimport {execFileSync} from 'node:child_process';\nfunction fileLooksIntact(file: string): boolean {\n  try {\n    execFileSync('ffprobe', ['-v','warning','-hide_banner', file], {encoding:'utf8', stdio:'pipe'});\n    return true;\n  } catch { return false; }\n}","typeGuard":"// moov box ordering is a deep structural property; not caller-type-guardable.\n// => typeGuard: null","tryCatchPattern":"try {\n  const {tracks} = await parseMedia({src, reader: nodeReader});\n} catch (err) {\n  if (err instanceof Error && /Movie timescale is not set/.test(err.message)) {\n    // moov has no/late mvhd; re-mux to fix box ordering\n  } else {\n    throw err;\n  }\n}","preventionTips":["Re-mux files with ffmpeg to ensure mvhd precedes trak inside moov.","Validate moov structure with MP4Box -info / ffprobe before parsing.","Re-fetch sources suspected of corruption or hand-editing.","Migrate to @remotion/mediabunny (parseMedia is deprecated)."],"tags":["mp4","iso-base-media","media-parser","moov","mvhd","corrupt-file","box-ordering"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}