{"record":{"id":"bc631da9f4bb4474","repo":"remotion-dev/remotion","slug":"no-video-and-no-audio-tracks","errorCode":null,"errorMessage":"no video and no audio tracks","messagePattern":"no video and no audio tracks","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.ts","lineNumber":52,"sourceCode":"\tmp4HeaderSegment,\n}: {\n\tinfo: IsoBaseMediaSeekingHints;\n\ttime: number;\n\tlogLevel: MediaParserLogLevel;\n\tcurrentPosition: number;\n\tisoState: IsoBaseMediaState;\n\tstructure: StructureState;\n\ttracks: MediaParserTrack[];\n\tisLastChunkInPlaylist: boolean;\n\tmp4HeaderSegment: IsoBaseMediaStructure | null;\n}): Promise<SeekResolution> => {\n\tconst firstVideoTrack = tracks.find((t) => t.type === 'video');\n\n\t// If there is both video and audio, seek based on video, but if not then audio is also okay\n\tconst firstTrack = firstVideoTrack ?? tracks.find((t) => t.type === 'audio');\n\n\tif (!firstTrack) {\n\t\tthrow new Error('no video and no audio tracks');\n\t}\n\n\tconst moov = getMoovBoxFromState({\n\t\tstructureState: structure,\n\t\tisoState,\n\t\tmp4HeaderSegment,\n\t\tmayUsePrecomputed: true,\n\t});\n\tif (!moov) {\n\t\tthrow new Error('No moov atom found');\n\t}\n\n\tconst trakBox = getTrakBoxByTrackId(moov, firstTrack.trackId);\n\n\tif (!trakBox) {\n\t\tthrow new Error('No trak box found');\n\t}\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.ts#L34-L70","documentation":"Thrown by getSeekingByteFromFragmentedMp4 when the `tracks` array contains neither a track with type 'video' nor one with type 'audio'. The function picks firstVideoTrack then falls back to first audio track; if both lookups miss, there is nothing to seek on. This is fundamentally a state bug: the parser reached seek resolution without having registered any playable track.","triggerScenarios":"Reached during fragmented MP4 seek when state.tracks has no video and no audio entries — e.g. only 'other' tracks (timed metadata, hint tracks), or the tracks array was emptied/reset before seek. Also reachable if track.type uses an unexpected value due to a parser change.","commonSituations":"MP4 with only hint or metadata tracks (rare for consumer media). A bug in track registration that never produces video/audio tracks. Calling seek before any onVideoTrack/onAudioTrack callback has fired. Streams where the moov declares only subtitle/metadata traks.","solutions":["Defer seeking until at least one video or audio track has been registered (wait for onVideoTrack/onAudioTrack).","Inspect the file's tracks with `ffprobe -show_streams` and confirm it has a video or audio stream.","If the file legitimately has only metadata tracks, do not attempt media seeking.","Re-mux to ensure the moov declares standard video/audio traks."],"exampleFix":"// before\nawait parser.seek(timeInSeconds);\n\n// after\nif (!tracks.some((t) => t.type === 'video' || t.type === 'audio')) {\n  throw new Error('No playable track — waiting for track registration or file has only metadata tracks');\n}\nawait parser.seek(timeInSeconds);","handlingStrategy":"validation","validationCode":"import type {MediaParserTrack} from '../../get-tracks';\nfunction hasPlayableTrack(tracks: MediaParserTrack[]): boolean {\n  return tracks.some((t) => t.type === 'video' || t.type === 'audio');\n}","typeGuard":"import type {MediaParserTrack} from '../../get-tracks';\nfunction hasMediaTrack(tracks: MediaParserTrack[]): boolean {\n  return tracks.some((t) => t.type === 'video' || t.type === 'audio');\n}","tryCatchPattern":"try {\n  await parser.seek(time);\n} catch (err) {\n  if (/no video and no audio tracks/i.test(String(err?.message))) {\n    // Defer seek until at least one media track is registered\n    return;\n  }\n  throw err;\n}","preventionTips":["Wait for onVideoTrack or onAudioTrack to fire before issuing a seek.","Probe the file with ffprobe and confirm it has a video or audio stream.","Do not attempt seeking on metadata-only files.","Reset and rebuild the tracks array whenever the moov is reloaded."],"tags":["mp4","isobmff","media-parser","seeking","tracks","fmp4"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}