remotion-dev/remotion · error · Error
Cannot get duration of VBR MP3 file - no frames
Error message
Cannot get duration of VBR MP3 file - no frames
What it means
Thrown by `getDurationFromMp3Xing` when computing the duration of a variable-bitrate (VBR) MP3 file from its Xing header, but `xingData.numberOfFrames` is zero or falsy. The Xing/VBR header's frame count field is required to compute duration; without it the calculation is impossible.
Source
Thrown at packages/media-parser/src/containers/mp3/get-duration.ts:15
import type {ParserState} from '../../state/parser-state';
import {getMpegFrameLength} from './get-frame-length';
import type {XingData} from './parse-xing';
import {getSamplesPerMpegFrame} from './samples-per-mpeg-file';
export const getDurationFromMp3Xing = ({
xingData,
samplesPerFrame,
}: {
xingData: XingData;
samplesPerFrame: number;
}) => {
const xingFrames = xingData.numberOfFrames;
if (!xingFrames) {
throw new Error('Cannot get duration of VBR MP3 file - no frames');
}
const {sampleRate} = xingData;
if (!sampleRate) {
throw new Error('Cannot get duration of VBR MP3 file - no sample rate');
}
const xingSamples = xingFrames * samplesPerFrame;
return xingSamples / sampleRate;
};
export const getDurationFromMp3 = (state: ParserState): number | null => {
const mp3Info = state.mp3.getMp3Info();
const mp3BitrateInfo = state.mp3.getMp3BitrateInfo();
if (!mp3Info || !mp3BitrateInfo) {
return null;
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-encode the MP3 file with a standard encoder (e.g., LAME) that writes a complete Xing header.
- Try converting the file to CBR MP3 to avoid the VBR/Xing path entirely.
- If the file is user-supplied, validate it with an audio tool (e.g., `ffprobe`) before parsing.
- Wrap `parseMedia` in a try-catch and fall back to a different file or format.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate an MP3 file's Xing header before parsing
async function hasValidXingFrames(file: File): Promise<boolean> {
const buf = await file.slice(0, 4096).arrayBuffer();
const bytes = new Uint8Array(buf);
const text = new TextDecoder().decode(bytes);
const xingIdx = text.indexOf('Xing');
if (xingIdx === -1) return true; // not VBR, no issue
// Xing flags + frame count are at xingIdx+4 (flags) and xingIdx+8 (frames)
if (xingIdx + 12 > bytes.length) return false;
const view = new DataView(buf, xingIdx + 8, 4);
return view.getUint32(0) > 0;
} Try / catch
try {
await parseMedia({src, fields: {durationInSeconds: true}});
} catch (e) {
if (e instanceof Error && e.message.includes('no frames')) {
console.error('The VBR MP3 has a corrupt Xing header with no frame count.');
// Re-encode or use a different file
}
throw e;
} Prevention
- Re-encode VBR MP3 files with LAME to ensure a complete Xing header.
- Validate MP3 files with ffprobe before parsing.
- Prefer CBR MP3 or AAC/M4A formats for reliable parsing.
- Wrap parseMedia in try-catch when handling user-uploaded audio.
When it happens
Trigger: An MP3 file with a Xing header where the `numberOfFrames` field is 0 or missing. The `parseXing` function parsed the header successfully but the frame-count bytes were zero, indicating a corrupt or incomplete Xing table of contents.
Common situations: Corrupt or truncated MP3 files with a damaged Xing header. Files produced by encoders that write a Xing marker but don't populate the frame count. Files that have been concatenated or re-tagged in ways that corrupt the VBR header region.
Related errors
- Cannot get duration of VBR MP3 file - no sample rate
- Unknown MP3 header
- Bitrate mismatch at offset ${initialOffset}: ${bitrateInKbit
- MP3 files with VBRI are currently unsupported because we hav
- No bitrate info
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/0fd1bf2bb694a574.
Report an issue: GitHub.