@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
189 lines (188 loc) • 6.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.audioCodecOption = exports.getDefaultAudioCodec = exports.resolveAudioCodec = exports.getExtensionFromAudioCodec = exports.defaultAudioCodecs = exports.mapAudioCodecToFfmpegAudioCodecName = exports.supportedAudioCodecs = exports.validAudioCodecs = void 0;
const separate_audio_1 = require("./separate-audio");
exports.validAudioCodecs = ['pcm-16', 'aac', 'mp3', 'opus'];
exports.supportedAudioCodecs = {
h264: ['aac', 'pcm-16', 'mp3'],
'h264-mkv': ['pcm-16', 'mp3'],
'h264-ts': ['pcm-16', 'aac'],
aac: ['aac', 'pcm-16'],
avi: [],
gif: [],
h265: ['aac', 'pcm-16'],
mp3: ['mp3', 'pcm-16'],
prores: ['aac', 'pcm-16'],
vp8: ['opus', 'pcm-16'],
vp9: ['opus', 'pcm-16'],
wav: ['pcm-16'],
};
const _satisfies = exports.supportedAudioCodecs;
if (_satisfies) {
// Just for type checking
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const audioCodecNames = [
'pcm_s16le',
'libfdk_aac',
'libmp3lame',
'libopus',
];
const mapAudioCodecToFfmpegAudioCodecName = (audioCodec) => {
if (audioCodec === 'aac') {
return 'libfdk_aac';
}
if (audioCodec === 'mp3') {
return 'libmp3lame';
}
if (audioCodec === 'opus') {
return 'libopus';
}
if (audioCodec === 'pcm-16') {
return 'pcm_s16le';
}
throw new Error('unknown audio codec: ' + audioCodec);
};
exports.mapAudioCodecToFfmpegAudioCodecName = mapAudioCodecToFfmpegAudioCodecName;
const cliFlag = 'audio-codec';
const ssrName = 'audioCodec';
exports.defaultAudioCodecs = {
'h264-mkv': {
lossless: 'pcm-16',
compressed: 'pcm-16',
},
'h264-ts': {
lossless: 'pcm-16',
compressed: 'aac',
},
aac: {
lossless: 'pcm-16',
compressed: 'aac',
},
gif: {
lossless: null,
compressed: null,
},
h264: {
lossless: 'pcm-16',
compressed: 'aac',
},
h265: {
lossless: 'pcm-16',
compressed: 'aac',
},
mp3: {
lossless: 'pcm-16',
compressed: 'mp3',
},
prores: {
lossless: 'pcm-16',
compressed: 'pcm-16',
},
vp8: {
lossless: 'pcm-16',
compressed: 'opus',
},
vp9: {
lossless: 'pcm-16',
compressed: 'opus',
},
wav: {
lossless: 'pcm-16',
compressed: 'pcm-16',
},
};
const extensionMap = {
aac: 'aac',
mp3: 'mp3',
opus: 'opus',
'pcm-16': 'wav',
};
const getExtensionFromAudioCodec = (audioCodec) => {
if (extensionMap[audioCodec]) {
return extensionMap[audioCodec];
}
throw new Error(`Unsupported audio codec: ${audioCodec}`);
};
exports.getExtensionFromAudioCodec = getExtensionFromAudioCodec;
const resolveAudioCodec = ({ codec, setting, preferLossless, separateAudioTo, }) => {
let derivedFromSeparateAudioToExtension = null;
if (separateAudioTo) {
const extension = separateAudioTo.split('.').pop();
for (const [key, value] of Object.entries(extensionMap)) {
if (value === extension) {
derivedFromSeparateAudioToExtension = key;
if (!exports.supportedAudioCodecs[codec].includes(derivedFromSeparateAudioToExtension) &&
derivedFromSeparateAudioToExtension) {
throw new Error(`The codec is ${codec} but the audio codec derived from --${separate_audio_1.separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}. The only supported codecs are: ${exports.supportedAudioCodecs[codec].join(', ')}`);
}
}
}
}
// Explanation: https://github.com/remotion-dev/remotion/issues/1647
if (preferLossless) {
const selected = (0, exports.getDefaultAudioCodec)({ codec, preferLossless });
if (derivedFromSeparateAudioToExtension &&
selected !== derivedFromSeparateAudioToExtension) {
throw new Error(`The audio codec derived from --${separate_audio_1.separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from the "Prefer lossless" option (${selected}). Remove any conflicting options.`);
}
return selected;
}
if (setting === null) {
if (derivedFromSeparateAudioToExtension) {
return derivedFromSeparateAudioToExtension;
}
return (0, exports.getDefaultAudioCodec)({ codec, preferLossless });
}
if (derivedFromSeparateAudioToExtension !== setting &&
derivedFromSeparateAudioToExtension) {
throw new Error(`The audio codec derived from --${separate_audio_1.separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from your ${exports.audioCodecOption.name} setting (${setting}). Remove any conflicting options.`);
}
return setting;
};
exports.resolveAudioCodec = resolveAudioCodec;
const getDefaultAudioCodec = ({ codec, preferLossless, }) => {
return exports.defaultAudioCodecs[codec][preferLossless ? 'lossless' : 'compressed'];
};
exports.getDefaultAudioCodec = getDefaultAudioCodec;
let _audioCodec = null;
exports.audioCodecOption = {
cliFlag,
setConfig: (audioCodec) => {
if (audioCodec === null) {
_audioCodec = null;
return;
}
if (!exports.validAudioCodecs.includes(audioCodec)) {
throw new Error(`Audio codec must be one of the following: ${exports.validAudioCodecs.join(', ')}, but got ${audioCodec}`);
}
_audioCodec = audioCodec;
},
getValue: ({ commandLine }) => {
if (commandLine[cliFlag]) {
const codec = commandLine[cliFlag];
if (!exports.validAudioCodecs.includes(commandLine[cliFlag])) {
throw new Error(`Audio codec must be one of the following: ${exports.validAudioCodecs.join(', ')}, but got ${codec}`);
}
return {
source: 'cli',
value: commandLine[cliFlag],
};
}
if (_audioCodec !== null) {
return {
source: 'config',
value: _audioCodec,
};
}
return {
source: 'default',
value: null,
};
},
description: () => `Set the format of the audio that is embedded in the video. Not all codec and audio codec combinations are supported and certain combinations require a certain file extension and container format. See the table in the docs to see possible combinations.`,
docLink: 'https://www.remotion.dev/docs/encoding/#audio-codec',
name: 'Audio Codec',
ssrName,
type: 'aac',
};