{"record":{"id":"4381dbccec759e54","repo":"remotion-dev/remotion","slug":"the-primary-video-track-contains-no-presentable-vi","errorCode":null,"errorMessage":"The primary video track contains no presentable video duration.","messagePattern":"The primary video track contains no presentable video duration\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/separate-video-layers.ts","lineNumber":331,"sourceCode":"\t\toptions.audioBitrate ?? 'medium',\n\t);\n\tconst keyframeIntervalInSeconds = options.keyframeIntervalInSeconds ?? 1;\n\tconst input = makeInput(options.src);\n\tconst onInputAbort = () => input.dispose();\n\toptions.signal?.addEventListener('abort', onInputAbort, {once: true});\n\n\ttry {\n\t\tconst {videoTrack, width, height} = await probeVideoInput({\n\t\t\tinput,\n\t\t\tvideoQuality,\n\t\t});\n\t\tconst [inputFirstVideoTimestamp, videoEndTimestamp] = await Promise.all([\n\t\t\tvideoTrack.getFirstTimestamp(),\n\t\t\tvideoTrack.computeDuration(),\n\t\t]);\n\t\tconst videoStartTimestamp = Math.max(inputFirstVideoTimestamp, 0);\n\t\tif (videoEndTimestamp <= videoStartTimestamp) {\n\t\t\tthrow new Error(\n\t\t\t\t'The primary video track contains no presentable video duration.',\n\t\t\t);\n\t\t}\n\n\t\tconst durationInSeconds = videoEndTimestamp - videoStartTimestamp;\n\t\tthrowIfAborted(options.signal);\n\n\t\tconst result = await withLoadedVideoMattingPipeline({\n\t\t\tmodel,\n\t\t\tonProgress: options.onModelLoadProgress,\n\t\t\tsignal: options.signal ?? null,\n\t\t\trun: async (pipeline) => {\n\t\t\t\tthrowIfAborted(options.signal);\n\t\t\t\tlet iterator: AsyncGenerator<\n\t\t\t\t\t{\n\t\t\t\t\t\tcanvas: HTMLCanvasElement | OffscreenCanvas;\n\t\t\t\t\t\ttimestamp: number;\n\t\t\t\t\t\tduration: number;","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/separate-video-layers.ts#L313-L349","documentation":"The library computes the video duration via videoTrack.computeDuration() and a start timestamp via getFirstTimestamp(); if videoEndTimestamp <= videoStartTimestamp (after clamping start to 0), there is no usable playback duration to separate, so it throws. This means the track reports zero, negative, or undefined-length video content.","triggerScenarios":"Input container whose video track has zero-length or corrupt duration metadata (e.g. moov missing duration), a first timestamp larger than the computed end timestamp, or a recording stopped immediately after starting (0 frames of duration).","commonSituations":"Files recorded and aborted instantly; broken muxers writing duration 0; live-recorded fragments where timestamps start above the computed duration; corrupted mp4 whose duration field was never finalized.","solutions":["Verify the file plays and shows a real duration in a player / ffprobe before processing.","Re-encode the source with ffmpeg (this rebuilds duration metadata): ffmpeg -i in.mp4 -c:v libx264 out.mp4.","If the file is a fragmented/live recording, finalize it (e.g. remux with ffmpeg) so the duration is written.","Guard in code: check the media duration > 0 before calling separateVideoLayers."],"exampleFix":"// before\nawait separateVideoLayers({src: zeroDurationClip.webm});\n// after\nconst duration = await getTrackDuration(zeroDurationClip); // your probe\nif (duration <= 0) throw new Error('Source clip has no duration');\nawait separateVideoLayers({src: zeroDurationClip});","handlingStrategy":"validation","validationCode":"const input = new Input({source: new BlobSource(file), formats: ALL_FORMATS});\nconst track = await input.getPrimaryVideoTrack();\nconst duration = await track.computeDuration();\nif (duration <= 0) throw new Error('Source video has no usable duration');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure recordings are finalized (not mid-write live fragments) before processing.","Re-encode sources whose metadata may be missing duration.","Check playback duration in a player/ffprobe for user-supplied files."],"tags":["mediabunny","duration","timestamps","corrupt-file"],"backgroundTag":"value-out-of-range","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}