remotion-dev/remotion · error
Only supporting MPEG-4 for .aac
Error message
Only supporting MPEG-4 for .aac
What it means
Thrown by parseAac when the MPEG 'ID' bit in an ADTS header is 1, meaning the stream is MPEG-2 (ISO 13818-7) rather than MPEG-4 (ISO 14496-3). The parser only supports MPEG-4 AAC, so it rejects MPEG-2 streams. This is a deliberate scope limitation of the @remotion/media-parser ADTS parser.
Source
Thrown at packages/media-parser/src/containers/aac/parse-aac.ts:24
import {convertAudioOrVideoSampleToWebCodecsTimestamps} from '../../convert-audio-or-video-sample';
import type {ParseResult} from '../../parse-result';
import {registerAudioTrack} from '../../register-track';
import type {ParserState} from '../../state/parser-state';
import {WEBCODECS_TIMESCALE} from '../../webcodecs-timescale';
export const parseAac = async (state: ParserState): Promise<ParseResult> => {
const {iterator} = state;
const startOffset = iterator.counter.getOffset();
iterator.startReadingBits();
const syncWord = iterator.getBits(12);
if (syncWord !== 0xfff) {
throw new Error('Invalid syncword: ' + syncWord);
}
const id = iterator.getBits(1);
if (id !== 0) {
throw new Error('Only supporting MPEG-4 for .aac');
}
const layer = iterator.getBits(2);
if (layer !== 0) {
throw new Error('Only supporting layer 0 for .aac');
}
const protectionAbsent = iterator.getBits(1); // protection absent
const audioObjectType = iterator.getBits(2); // 1 = 'AAC-LC'
const samplingFrequencyIndex = iterator.getBits(4);
const sampleRate = getSampleRateFromSampleFrequencyIndex(
samplingFrequencyIndex,
);
iterator.getBits(1); // private bit
const channelConfiguration = iterator.getBits(3);
const codecPrivate = createAacCodecPrivate({
audioObjectType,View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-encode to MPEG-4 AAC: `ffmpeg -i input.aac -c:a aac -f adts output.aac` (ffmpeg defaults to MPEG-4 ID).
- Switch to Mediabunny (https://www.remotion.dev/docs/mediabunny/metadata) which may support MPEG-2 AAC.
- If you cannot re-encode, use ffprobe to extract metadata instead of @remotion/media-parser.
- Report the file to the Remotion team to gauge whether MPEG-2 support is worth adding.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: verify MPEG-4 ID bit (bit 12 of ADTS header is 0)
async function isMpeg4Adts(filePath: string): Promise<boolean> {
const buf = await readFile(filePath);
if (buf.length < 2) return false;
// Byte 1, bit 3 (0-indexed from MSB) = ID bit; should be 0 for MPEG-4
return (buf[1] & 0x08) === 0x00;
} Try / catch
try {
const result = await parseMedia({src, fields: {/* ... */}});
} catch (e) {
if (e instanceof Error && e.message === 'Only supporting MPEG-4 for .aac') {
console.error('File is MPEG-2 AAC. Re-encode: ffmpeg -i input.aac -c:a aac -f adts output.aac');
} else {
throw e;
}
} Prevention
- Re-encode legacy MPEG-2 AAC files to MPEG-4 with ffmpeg before parsing.
- Check the ADTS ID bit before batch processing .aac files.
- Use ffprobe to confirm 'codec_tag' and MPEG version.
- Migrate to Mediabunny which may support MPEG-2 AAC.
When it happens
Trigger: Parsing a .aac file whose ADTS frames carry the MPEG-2 ID bit set (id=1). This occurs with legacy MPEG-2 AAC files or files produced by older encoders that default to MPEG-2 transport.
Common situations: Legacy audio files encoded with old tools (e.g. early FAAD/FAAC builds) that default to MPEG-2 AAC. Files from older broadcast or telephony systems. Some test suites still ship MPEG-2 AAC samples.
Related errors
- Only supporting MPEG-4 for .ts
- Unexpected audio object type ${audioObjectType}
- Invalid syncword: ${syncWord}
- Only supporting layer 0 for .aac
- Unsupported audio format ${strf.formatTag}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/cff468dda15d97be.
Report an issue: GitHub.