remotion-dev/remotion · error · Error
getAudioData() is only available in the browser.
Error message
getAudioData() is only available in the browser.
What it means
Thrown by getAudioData() when the global `document` is undefined (line 23). The function needs a real browser to create an AudioContext and run fetch().decodeAudioData(), so it refuses to run in Node, SSR, or any non-DOM environment. The guard fires before any audio work happens, so the error is purely about where the call executed.
Source
Thrown at packages/media-utils/src/get-audio-data.ts:24
const metadataCache: {[key: string]: MediaUtilsAudioData} = {};
const limit = pLimit(3);
type Options = {
sampleRate?: number;
requestInit?: RequestInit;
};
const fn = async (
src: string,
options?: Options,
): Promise<MediaUtilsAudioData> => {
if (metadataCache[src]) {
return metadataCache[src];
}
if (typeof document === 'undefined') {
throw new Error('getAudioData() is only available in the browser.');
}
const audioContext = new AudioContext({
sampleRate: options?.sampleRate ?? 48000,
});
const response = await fetchWithCorsCatch(src, options?.requestInit);
if (!response.ok) {
throw new Error(
`Failed to fetch audio data from ${src}: ${response.status} ${response.statusText}`,
);
}
const arrayBuffer = await response.arrayBuffer();
const wave = await audioContext.decodeAudioData(arrayBuffer);
const channelWaveforms = new Array(wave.numberOfChannels)View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Only call getAudioData() inside Remotion components (which render in a Chromium browser) or client-only code guarded by typeof window !== 'undefined'.
- If you need audio metadata server-side, switch to Mediabunny's metadata API (see docs/mediabunny/metadata) which is not DOM-bound.
- In tests, configure jsdom/happy-dom or run the test in the Remotion testbed browser; do not run getAudioData under plain Node.
- For Next.js/Remix, mark the calling component 'use client' or move the call into a useEffect so it only runs after hydration in the browser.
Example fix
// before (runs on server, throws)
import {getAudioData} from '@remotion/media-utils';
export async function getStaticProps() {
const data = await getAudioData('/song.mp3');
return {props: {data}};
}
// after (client-only)
import {useAudioData} from '@remotion/media-utils';
export default function Player() {
const data = useAudioData(staticFile('song.mp3'));
return <Audio src={staticFile('song.mp3')} />;
} Defensive patterns
Strategy: validation
Validate before calling
// Browser-environment guard before calling the DOM-dependent helper
import {getAudioData} from '@remotion/media-utils';
async function safeGetAudioData(src: string) {
if (typeof document === 'undefined' || typeof window === 'undefined') {
// skip server-side; only run in a real browser
return null;
}
return getAudioData(src);
} Type guard
const hasBrowserAudio = (): boolean => typeof document !== 'undefined' && typeof window !== 'undefined' && typeof window.AudioContext !== 'undefined';
Try / catch
try {
const data = await getAudioData(src);
} catch (err) {
if ((err as Error).message.includes('only available in the browser')) {
// SSR path: skip or compute metadata server-side via Mediabunny
} else {
throw err;
}
} Prevention
- Never import-and-call @remotion/media-utils DOM helpers at module top level; call inside React components or effects.
- Keep audio-data fetching inside Remotion compositions (which always run in Chromium) rather than in server code.
- If metadata is needed server-side, use Mediabunny's metadata API or ffprobe instead of these DOM helpers.
- Add typeof document !== 'undefined' guards around any call invoked from isomorphic code.
When it happens
Trigger: Calling getAudioData(src) from a Node script, a server-side React render (Next.js getStaticProps, Remix loader), Jest/Node tests without jsdom, or any module-eval that runs the function at import time on the server.
Common situations: Importing @remotion/media-utils into a Next.js app and calling getAudioData() in a server component; running unit tests under Node without a DOM polyfill; server-side pre-rendering that tries to compute audio waveforms; calling it inside getStaticProps/getServerSideProps.
Related errors
- getAudioDuration() is only available in the browser.
- getImageDimensions() is only available in the browser.
- getVideoMetadata() is only available in the browser.
- Tried to call an API that only works in the browser from out
- measureText() can only be called in a browser.
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/39527050fff6c993.
Report an issue: GitHub.