remotion
Version:
Make videos programmatically
86 lines (85 loc) • 3.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSingletonAudioContext = void 0;
const react_1 = require("react");
const log_1 = require("../log");
const use_remotion_environment_1 = require("../use-remotion-environment");
let warned = false;
const warnOnce = (logLevel) => {
if (warned) {
return;
}
warned = true;
// Don't pullute logs if in SSR
if (typeof window !== 'undefined') {
log_1.Log.warn({ logLevel, tag: null }, 'AudioContext is not supported in this browser');
}
};
const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, }) => {
const env = (0, use_remotion_environment_1.useRemotionEnvironment)();
const context = (0, react_1.useMemo)(() => {
if (env.isRendering) {
return null;
}
if (!audioEnabled) {
return null;
}
if (typeof AudioContext === 'undefined') {
warnOnce(logLevel);
return null;
}
const audioContext = new AudioContext({
latencyHint,
// By default, this can end up being 44100Hz.
// Playing a 48000Hz file in a 44100Hz context, such as https://remotion.media/video.mp4 in a @remotion/media tag
// we observe some issues that seem to go away when we set the sample rate to 48000 with Sony LinkBuds Bluetooth headphones.
sampleRate: 48000,
});
const gainNode = audioContext.createGain();
gainNode.connect(audioContext.destination);
log_1.Log.trace({ logLevel, tag: 'audio' }, 'Creating new audio context');
audioContext.suspend();
// Tracks the state we are transitioning towards while resume()/suspend()
// have been called but the native state has not updated yet.
let transitionTarget = null;
const getState = () => {
const nativeState = audioContext.state;
if (transitionTarget === 'running' && nativeState !== 'running') {
return 'suspended-to-running';
}
if (transitionTarget === 'suspended' && nativeState !== 'suspended') {
return 'running-to-suspended';
}
return nativeState;
};
const resume = () => {
transitionTarget = 'running';
const promise = audioContext.resume();
promise.finally(() => {
if (transitionTarget === 'running') {
transitionTarget = null;
}
});
return promise;
};
const suspend = () => {
transitionTarget = 'suspended';
const promise = audioContext.suspend();
promise.finally(() => {
if (transitionTarget === 'suspended') {
transitionTarget = null;
}
});
return promise;
};
return {
audioContext,
gainNode,
getState,
resume,
suspend,
};
}, [logLevel, latencyHint, env.isRendering, audioEnabled]);
return context;
};
exports.useSingletonAudioContext = useSingletonAudioContext;