{"record":{"id":"13f77aa0593431c3","repo":"remotion-dev/remotion","slug":"could-not-find-sample-rate","errorCode":null,"errorMessage":"Could not find sample rate","messagePattern":"Could not find sample rate","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/make-track.ts","lineNumber":69,"sourceCode":"\tconst timescaleAndDuration = getTimescaleAndDuration(trakBox);\n\n\tif (!tkhdBox) {\n\t\tthrow new Error('Expected tkhd box in trak box');\n\t}\n\n\tif (!timescaleAndDuration) {\n\t\tthrow new Error('Expected timescale and duration in trak box');\n\t}\n\n\tif (trakBoxContainsAudio(trakBox)) {\n\t\tconst numberOfChannels = getNumberOfChannelsFromTrak(trakBox);\n\t\tif (numberOfChannels === null) {\n\t\t\tthrow new Error('Could not find number of channels');\n\t\t}\n\n\t\tconst sampleRate = getSampleRate(trakBox);\n\t\tif (sampleRate === null) {\n\t\t\tthrow new Error('Could not find sample rate');\n\t\t}\n\n\t\tconst {codecString, description} = getAudioCodecStringFromTrak(trakBox);\n\t\tconst codecPrivate =\n\t\t\tgetCodecPrivateFromTrak(trakBox) ?? description ?? null;\n\t\tconst codecEnum = getAudioCodecFromTrack(trakBox);\n\n\t\tconst actual = getActualDecoderParameters({\n\t\t\taudioCodec: codecEnum,\n\t\t\tcodecPrivate: codecPrivate ?? null,\n\t\t\tnumberOfChannels,\n\t\t\tsampleRate,\n\t\t});\n\n\t\treturn {\n\t\t\ttype: 'audio',\n\t\t\ttrackId: tkhdBox.trackId,\n\t\t\toriginalTimescale: timescaleAndDuration.timescale,","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/make-track.ts#L51-L87","documentation":"Thrown by makeBaseMediaTrack() immediately after the channel-count check. The track is detected as audio, but getSampleRate() returned null, so the sample rate could not be extracted from the audio sample entry (typically the mp4a esds/decoder-specific info). Sample rate is required to configure a WebCodecs AudioDecoder, so the parser aborts rather than guess.","triggerScenarios":"parseMedia({src}) on an MP4/MOV/M4A whose audio sample entry lacks or has a corrupt esds/wave sub-box carrying the sample-rate field. Common when the mp4a box is present (so the track is flagged audio) but its decoder-config payload is missing or truncated.","commonSituations":"Files with stripped/rewritten atoms, incomplete captures, screen recordings with malformed audio, or audio codecs whose decoder-private data this parser does not understand.","solutions":["Pre-validate with ffprobe <file> to confirm it reports a sample rate; if not, the file is malformed.","Re-mux cleanly: ffmpeg -i in.mp4 -c copy out.mp4, or re-encode audio: ffmpeg -i in.mp4 -c:v copy -c:a aac out.mp4.","Switch to @remotion/mediabunny (parseMedia is deprecated).","Drop the audio track if unused: ffmpeg -i in.mp4 -an -c:v copy out.mp4."],"exampleFix":"// before\nawait parseMedia({src, reader: nodeReader, onAudioTrack: () => {}});\n\n// after\ntry {\n  await parseMedia({src, reader: nodeReader, onAudioTrack: () => {}});\n} catch (err) {\n  if (err instanceof Error && /Could not find sample rate/.test(err.message)) {\n    // audio sample entry unreadable; re-encode the audio stream\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the audio stream reports a sample rate via ffprobe before parsing:\n//   ffprobe -v error -select_streams a:0 -show_entries stream=sample_rate -of default=nw=1:nk=1 in.mp4\nimport {execFileSync} from 'node:child_process';\nfunction audioSampleRateReadable(file: string): boolean {\n  try {\n    const out = execFileSync('ffprobe',\n      ['-v','error','-select_streams','a:0','-show_entries','stream=sample_rate','-of','default=nw=1:nk=1', file],\n      {encoding: 'utf8'});\n    return /^\\d+$/.test(out.trim()) && Number(out.trim()) > 0;\n  } catch { return false; }\n}","typeGuard":"// src is a URL/File/Uint8Array; the audio sample entry is binary and not\n// type-guardable from the caller. No narrowing function is possible.\n// => typeGuard: null","tryCatchPattern":"try {\n  await parseMedia({src, reader: nodeReader, onAudioTrack: () => {}});\n} catch (err) {\n  if (err instanceof Error && /Could not find sample rate/.test(err.message)) {\n    // audio decoder-private data unreadable: re-encode audio or skip it\n  } else {\n    throw err;\n  }\n}","preventionTips":["Pre-validate sources with ffprobe (sample_rate must be a positive integer).","Re-mux suspect files with ffmpeg before parsing.","Migrate to @remotion/mediabunny (parseMedia is deprecated).","Wrap parseMedia() in try/catch for any untrusted input."],"tags":["mp4","iso-base-media","media-parser","audio","corrupt-file","codec","sample-entry"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}