@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
129 lines (128 loc) • 5.03 kB
JavaScript
;
// Combine multiple video chunks, useful for decentralized rendering
Object.defineProperty(exports, "__esModule", { value: true });
exports.combineChunks = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const combine_audio_1 = require("./combine-audio");
const combine_video_streams_1 = require("./combine-video-streams");
const combine_video_streams_seamlessly_1 = require("./combine-video-streams-seamlessly");
const get_extension_from_codec_1 = require("./get-extension-from-codec");
const is_audio_codec_1 = require("./is-audio-codec");
const logger_1 = require("./logger");
const mux_video_and_audio_1 = require("./mux-video-and-audio");
const audio_codec_1 = require("./options/audio-codec");
const truthy_1 = require("./truthy");
const codecSupportsFastStart = {
'h264-mkv': false,
'h264-ts': false,
h264: true,
h265: true,
aac: false,
gif: false,
mp3: false,
prores: false,
vp8: false,
vp9: false,
wav: false,
};
const combineChunks = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, resolvedAudioCodec, audioBitrate, indent, logLevel, chunkDurationInSeconds, binariesDirectory, cancelSignal, seamlessAudio, seamlessVideo, muted, metadata, }) => {
const shouldCreateAudio = resolvedAudioCodec !== null && !muted;
const shouldCreateVideo = !(0, is_audio_codec_1.isAudioCodec)(codec);
const videoOutput = shouldCreateVideo
? (0, node_path_1.join)(filelistDir, `video.${(0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, resolvedAudioCodec)}`)
: null;
const audioOutput = shouldCreateAudio
? (0, node_path_1.join)(filelistDir, `audio.${(0, audio_codec_1.getExtensionFromAudioCodec)(resolvedAudioCodec)}`)
: null;
const audioFiles = files.filter((f) => f.endsWith('audio'));
const videoFiles = files.filter((f) => f.endsWith('video'));
let concatenatedAudio = 0;
let concatenatedVideo = 0;
let muxing = 0;
const updateProgress = () => {
const totalFrames = (shouldCreateAudio ? numberOfFrames : 0) +
(shouldCreateVideo ? numberOfFrames : 0) +
numberOfFrames;
const actualProgress = concatenatedAudio + concatenatedVideo + muxing;
onProgress((actualProgress / totalFrames) * numberOfFrames);
};
logger_1.Log.verbose({ indent, logLevel }, `Combining chunks, audio = ${shouldCreateAudio === false
? 'no'
: seamlessAudio
? 'seamlessly'
: 'normally'}, video = ${shouldCreateVideo === false
? 'no'
: seamlessVideo
? 'seamlessly'
: 'normally'}`);
await Promise.all([
shouldCreateAudio && audioOutput
? (0, combine_audio_1.createCombinedAudio)({
audioBitrate,
filelistDir,
files: audioFiles,
indent,
logLevel,
output: audioOutput,
resolvedAudioCodec,
seamless: seamlessAudio,
chunkDurationInSeconds,
addRemotionMetadata: !shouldCreateVideo,
binariesDirectory,
fps,
cancelSignal,
onProgress: (frames) => {
concatenatedAudio = frames;
updateProgress();
},
})
: null,
shouldCreateVideo && !seamlessVideo && videoOutput
? (0, combine_video_streams_1.combineVideoStreams)({
codec,
filelistDir,
fps,
indent,
logLevel,
numberOfGifLoops,
output: videoOutput,
files: videoFiles,
addRemotionMetadata: !shouldCreateAudio,
binariesDirectory,
cancelSignal,
onProgress: (frames) => {
concatenatedVideo = frames;
updateProgress();
},
})
: null,
].filter(truthy_1.truthy));
try {
await (0, mux_video_and_audio_1.muxVideoAndAudio)({
audioOutput,
indent,
logLevel,
onProgress: (frames) => {
muxing = frames;
updateProgress();
},
output,
videoOutput: seamlessVideo
? (0, combine_video_streams_seamlessly_1.combineVideoStreamsSeamlessly)({ files: videoFiles })
: videoOutput,
binariesDirectory,
fps,
cancelSignal,
addFaststart: codecSupportsFastStart[codec],
metadata,
});
onProgress(numberOfFrames);
(0, node_fs_1.rmSync)(filelistDir, { recursive: true });
}
catch (err) {
(0, node_fs_1.rmSync)(filelistDir, { recursive: true });
throw err;
}
};
exports.combineChunks = combineChunks;