Browse Source

refactor

new-features-2020
Mikael Finstad 6 years ago
parent
commit
a875f4cf00
  1. 20
      audio.js
  2. 12
      parseConfig.js

20
audio.js

@ -95,7 +95,7 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
if (processedAudioLayers.length === 1) return { clipAudioPath: processedAudioLayers[0].layerAudioPath }; if (processedAudioLayers.length === 1) return { clipAudioPath: processedAudioLayers[0].layerAudioPath };
// Merge/mix all layer's audio
// Merge/mix all layers' audio
const weights = processedAudioLayers.map(({ audioLayer }) => (audioLayer.mixVolume != null ? audioLayer.mixVolume : 1)); const weights = processedAudioLayers.map(({ audioLayer }) => (audioLayer.mixVolume != null ? audioLayer.mixVolume : 1));
const args = [ const args = [
...getFfmpegCommonArgs({ enableFfmpegLog }), ...getFfmpegCommonArgs({ enableFfmpegLog }),
@ -120,12 +120,12 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
}, { concurrency: 4 }); }, { concurrency: 4 });
} }
async function mergeFadeClipAudio(clipAudio) {
async function crossFadeConcatClipAudio(clipAudio) {
if (clipAudio.length < 2) { if (clipAudio.length < 2) {
return clipAudio[0].path; return clipAudio[0].path;
} }
const mergedClipAudioPath = join(tmpDir, 'audio-merged.flac');
const outPath = join(tmpDir, 'audio-concat.flac');
if (verbose) console.log('Combining audio', clipAudio.map(({ path }) => basename(path))); if (verbose) console.log('Combining audio', clipAudio.map(({ path }) => basename(path)));
@ -149,11 +149,11 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
filterGraph, filterGraph,
'-c', 'flac', '-c', 'flac',
'-y', '-y',
mergedClipAudioPath,
outPath,
]; ];
await execa(ffmpegPath, args); await execa(ffmpegPath, args);
return mergedClipAudioPath;
return outPath;
} }
async function mixArbitraryAudio({ streams, audioNorm }) { async function mixArbitraryAudio({ streams, audioNorm }) {
@ -214,19 +214,19 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
if (clipAudio.every((ca) => ca.silent) && arbitraryAudio.length === 0) return undefined; if (clipAudio.every((ca) => ca.silent) && arbitraryAudio.length === 0) return undefined;
// Merge & fade the clip audio files // Merge & fade the clip audio files
const mergedClipAudioPath = await mergeFadeClipAudio(clipAudio);
const concatedClipAudioPath = await crossFadeConcatClipAudio(clipAudio);
const streams = [ const streams = [
// The first stream is required, and it determines the length of the output audio.
// All other streams will be truncated to this length
{ path: mergedClipAudioPath, mixVolume: clipsAudioVolume },
// The first stream is required, as it determines the length of the output audio.
// All other streams will be truncated to its length
{ path: concatedClipAudioPath, mixVolume: clipsAudioVolume },
...arbitraryAudio, ...arbitraryAudio,
]; ];
console.log('Mixing clip audio with arbitrary audio'); console.log('Mixing clip audio with arbitrary audio');
if (streams.length < 2) return mergedClipAudioPath;
if (streams.length < 2) return concatedClipAudioPath;
const mixedFile = await mixArbitraryAudio({ streams, audioNorm }); const mixedFile = await mixArbitraryAudio({ streams, audioNorm });
return mixedFile; return mixedFile;

12
parseConfig.js

@ -216,17 +216,18 @@ async function parseConfig({ defaults: defaultsIn = {}, clips, arbitraryAudio: a
} }
// These audio tracks are detached from the clips (can run over multiple clips) // These audio tracks are detached from the clips (can run over multiple clips)
// This is useful so we can have audio start relative to clip start time
// This is useful so we can have audio start relative to their parent clip's start time
if (type === 'detached-audio') { if (type === 'detached-audio') {
const { cutFrom, cutTo, mixVolume } = layer; const { cutFrom, cutTo, mixVolume } = layer;
if (!detachedAudioByClip[clipIndex]) detachedAudioByClip[clipIndex] = []; if (!detachedAudioByClip[clipIndex]) detachedAudioByClip[clipIndex] = [];
detachedAudioByClip[clipIndex].push({ path, cutFrom, cutTo, mixVolume, start }); detachedAudioByClip[clipIndex].push({ path, cutFrom, cutTo, mixVolume, start });
return undefined;
return undefined; // Will be filtered out
} }
return layer; return layer;
}); });
// Filter out deleted layers
layersOut = layersOut.filter((l) => l); layersOut = layersOut.filter((l) => l);
return { return {
@ -240,11 +241,12 @@ async function parseConfig({ defaults: defaultsIn = {}, clips, arbitraryAudio: a
let totalClipDuration = 0; let totalClipDuration = 0;
const clipDetachedAudio = []; const clipDetachedAudio = [];
// Need to map again because now we know all clip durations
// Need to map again because now we know all clip durations, and we can adjust transitions so they are safe
clipsOut = await pMap(clipsOut, async (clip, i) => { clipsOut = await pMap(clipsOut, async (clip, i) => {
const nextClip = clipsOut[i + 1]; const nextClip = clipsOut[i + 1];
// We clamp all transitions to half the length of every clip
// We clamp all transitions to half the length of every clip. If not, we risk that clips that are too short,
// will be eaten by transitions and could cause de-sync issues with audio/video
// NOTE: similar logic is duplicated in index.js // NOTE: similar logic is duplicated in index.js
let safeTransitionDuration = 0; let safeTransitionDuration = 0;
if (nextClip) { if (nextClip) {
@ -269,7 +271,7 @@ async function parseConfig({ defaults: defaultsIn = {}, clips, arbitraryAudio: a
}; };
}); });
// Audio can either come from `audioFilePath`, `audio` or from "detached" audio layers in clips
// Audio can either come from `audioFilePath`, `audio` or from "detached" audio layers from clips
const arbitraryAudio = [ const arbitraryAudio = [
// Background audio is treated just like arbitrary audio // Background audio is treated just like arbitrary audio
...(backgroundAudioPath ? [{ path: backgroundAudioPath, mixVolume: 1, loop: loopAudio ? -1 : 0 }] : []), ...(backgroundAudioPath ? [{ path: backgroundAudioPath, mixVolume: 1, loop: loopAudio ? -1 : 0 }] : []),

Loading…
Cancel
Save