{"record":{"id":"6dfe714017a3b6d7","repo":"remotion-dev/remotion","slug":"the-primary-audio-track-uses-sourcecodec-an","errorCode":null,"errorMessage":"The primary audio track uses ${sourceCodec ?? 'an unknown codec'}, which cannot be decoded in this browser. The audio cannot be converted to Opus.","messagePattern":"The primary audio track uses (.+?), which cannot be decoded in this browser\\. The audio cannot be converted to Opus\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/prepare-audio.ts","lineNumber":289,"sourceCode":"\t\t\t\t} finally {\n\t\t\t\t\tawait stopPacketIterator();\n\t\t\t\t\tclosePacketSources();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancel: async () => {\n\t\t\t\tif (finished || canceled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcanceled = true;\n\t\t\t\tpendingPacket = undefined;\n\t\t\t\tawait stopPacketIterator();\n\t\t\t},\n\t\t};\n\t}\n\n\tif (!(await audioTrack.canDecode())) {\n\t\tthrow new Error(\n\t\t\t`The primary audio track uses ${sourceCodec ?? 'an unknown codec'}, which ` +\n\t\t\t\t'cannot be decoded in this browser. The audio cannot be converted to Opus.',\n\t\t);\n\t}\n\n\tconst originalNumberOfChannels = await audioTrack.getNumberOfChannels();\n\tconst originalSampleRate = await audioTrack.getSampleRate();\n\tconst quality = audioQuality ?? new Quality('medium');\n\tlet outputNumberOfChannels = originalNumberOfChannels;\n\tlet outputSampleRate = originalSampleRate;\n\n\tif (\n\t\t!(await canEncodeAudio('opus', {\n\t\t\tnumberOfChannels: outputNumberOfChannels,\n\t\t\tsampleRate: outputSampleRate,\n\t\t\tquality,\n\t\t}))\n\t) {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/prepare-audio.ts#L271-L307","documentation":"prepareAudio() checks the primary audio track's codec via audioTrack.canDecode(). If the browser cannot decode the source codec (e.g. no AAC or E-AC-3 decoder in WebKit/Firefox), the track cannot be converted to Opus, and prepareAudio throws with the codec name (or 'an unknown codec' if the box reports none).","triggerScenarios":"Calling prepareAudio() on an MP4/MOV whose audio is AAC in a browser lacking AudioDecoder support for 'mp4a.40.2' (e.g. some WebKit builds); a codec string that WebCodecs cannot recognize at all.","commonSituations":"Safari/WebKit missing AAC decode support in the WebCodecs path; MOV files with proprietary audio codecs; running in an environment where AudioDecoder.isConfigSupported always rejects; server-side rendering without codec support.","solutions":["Remux/transcode the input's audio to Opus or AAC-decodable format before calling prepareAudio (e.g. with ffmpeg).","Test support first with the track's canDecode() or AudioDecoder.isConfigSupported() and show a user-facing message.","Prefer MP4 inputs with universally decodable audio (AAC/AAC-LC) or Opus-in-WebM inputs.","If rendering server-side, use a headless Chrome build with the needed proprietary codecs."],"exampleFix":"// before\nconst audio = await prepareAudio({input: movFile}); // AAC undecodable here\n// after\nif (!(await getPrimaryAudioTrack(input)).canDecode()) {\n  input = await remuxToOpusWebM(input); // pre-transcode\n}\nconst audio = await prepareAudio({input});","handlingStrategy":"fallback","validationCode":"const track = await getPrimaryAudioTrack(input);\nconst decodable = await track.canDecode();\nif (!decodable) input = await transcodeAudioToOpus(input);","typeGuard":"null","tryCatchPattern":"try { audio = await prepareAudio({input}); } catch (e) { if (e.message.includes('cannot be decoded')) { input = await transcodeWithFfmpeg(input); audio = await prepareAudio({input}); } else throw e; }","preventionTips":["Feature-detect codec support (track.canDecode()) before choosing inputs","Prefer AAC or Opus audio in source files","Keep a server-side transcode fallback for unsupported codecs","Test in Safari/WebKit where codec support differs"],"tags":["codec","webcodecs","browser-compatibility","audio"],"backgroundTag":"unsupported-operation","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"}