Skip to content

Commit

Permalink
implement output volume #83
Browse files Browse the repository at this point in the history
  • Loading branch information
mifi committed Dec 8, 2020
1 parent feb8d44 commit 9edb1e4
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ Edit specs are JavaScript / JSON objects describing the whole edit operation wit
loopAudio: false,
keepSourceAudio: false,
clipsAudioVolume: 1,
outputVolume: 1,
audio: [
{
path,
Expand Down Expand Up @@ -197,6 +198,7 @@ Edit specs are JavaScript / JSON objects describing the whole edit operation wit
| `loopAudio` | `--loop-audio` | Loop the audio track if it is shorter than video? | `false` | |
| `keepSourceAudio` | `--keep-source-audio` | Keep source audio from `clips`? | `false` | |
| `clipsAudioVolume` | | Volume of audio from `clips` relative to `audioTracks`. See [audio tracks](#arbitrary-audio-tracks). | `1` | |
| `outputVolume` | `--output-volume` | Adjust output [volume](http://ffmpeg.org/ffmpeg-filters.html#volume) (final stage). See [example](https://github.com/mifi/editly/blob/master/examples/audio-volume.json5) | `1` | e.g. `0.5` or `10dB` |
| `audioNorm.enable` | | Enable audio normalization? See [audio normalization](#audio-normalization). | `false` | |
| `audioNorm.gaussSize` | | Audio normalization gauss size. See [audio normalization](#audio-normalization). | `5` | |
| `audioNorm.maxGain` | | Audio normalization max gain. See [audio normalization](#audio-normalization). | `30` | |
Expand Down
9 changes: 5 additions & 4 deletions audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
return outPath;
}

async function mixArbitraryAudio({ streams, audioNorm }) {
async function mixArbitraryAudio({ streams, audioNorm, outputVolume }) {
let maxGain = 30;
let gaussSize = 5;
if (audioNorm) {
Expand All @@ -173,8 +173,9 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
return `[${i}]atrim=start=${cutFrom || 0}${cutToArg},adelay=delays=${Math.floor((start || 0) * 1000)}:all=1${apadArg}[a${i}]`;
}).join(';');

const volumeArg = outputVolume != null ? `,volume=${outputVolume}` : '';
const audioNormArg = enableAudioNorm ? `,dynaudnorm=g=${gaussSize}:maxgain=${maxGain}` : '';
filterComplex += `;${streams.map((s, i) => `[a${i}]`).join('')}amix=inputs=${streams.length}:duration=first:dropout_transition=0:weights=${streams.map((s) => (s.mixVolume != null ? s.mixVolume : 1)).join(' ')}${audioNormArg}`;
filterComplex += `;${streams.map((s, i) => `[a${i}]`).join('')}amix=inputs=${streams.length}:duration=first:dropout_transition=0:weights=${streams.map((s) => (s.mixVolume != null ? s.mixVolume : 1)).join(' ')}${audioNormArg}${volumeArg}`;

const mixedAudioPath = join(tmpDir, 'audio-mixed.flac');

Expand All @@ -198,7 +199,7 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })
}


async function editAudio({ keepSourceAudio, clips, arbitraryAudio, clipsAudioVolume, audioNorm }) {
async function editAudio({ keepSourceAudio, clips, arbitraryAudio, clipsAudioVolume, audioNorm, outputVolume }) {
// We need clips to process audio, because we need to know duration
if (clips.length === 0) return undefined;

Expand Down Expand Up @@ -228,7 +229,7 @@ module.exports = ({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir })

if (streams.length < 2) return concatedClipAudioPath;

const mixedFile = await mixArbitraryAudio({ streams, audioNorm });
const mixedFile = await mixArbitraryAudio({ streams, audioNorm, outputVolume });
return mixedFile;
}

Expand Down
5 changes: 4 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const cli = meow(`
--audio-file-path Add an audio track
--loop-audio Loop the audio track if it is shorter than video?
--keep-source-audio Keep audio from source files
--output-volume Adjust audio output volume
--allow-remote-requests
--fast, -f Fast mode (low resolution and FPS, useful for getting a quick preview)
Expand All @@ -57,6 +58,7 @@ const cli = meow(`
height: { type: 'number' },
fps: { type: 'number' },
loopAudio: { type: 'boolean' },
outputVolume: { type: 'string' },
},
});

Expand Down Expand Up @@ -98,7 +100,7 @@ const cli = meow(`
params.clips = clips.map((clip) => ({ layers: [clip] }));
}

const { verbose, transitionName, transitionDuration, clipDuration, width, height, fps, audioFilePath, fontPath, fast, out: outPath, keepSourceAudio, loopAudio, allowRemoteRequests } = cli.flags;
const { verbose, transitionName, transitionDuration, clipDuration, width, height, fps, audioFilePath, fontPath, fast, out: outPath, keepSourceAudio, loopAudio, outputVolume, allowRemoteRequests } = cli.flags;

if (transitionName || transitionDuration != null) {
params.defaults.transition = {};
Expand All @@ -117,6 +119,7 @@ const cli = meow(`
if (outPath) params.outPath = outPath;
if (audioFilePath) params.audioFilePath = audioFilePath;
if (loopAudio) params.loopAudio = loopAudio;
if (outputVolume) params.outputVolume = outputVolume;
if (keepSourceAudio) params.keepSourceAudio = true;
if (allowRemoteRequests) params.allowRemoteRequests = true;
if (width) params.width = width;
Expand Down
11 changes: 11 additions & 0 deletions examples/audio-volume.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
outPath: './audio-volume.mp4',
width: 200, height: 200,
clips: [
{ duration: 2, layers: [{ type: 'title-background', text: 'Audio output volume' }] },
],
audioTracks: [
{ path: './assets/High [NCS Release] - JPB (No Copyright Music)-R8ZRCXy5vhA.m4a', cutFrom: 18 },
],
outputVolume: '-10dB',
}
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const Editly = async (config = {}) => {
keepSourceAudio,
allowRemoteRequests,
audioNorm,
outputVolume,

ffmpegPath = 'ffmpeg',
ffprobePath = 'ffprobe',
Expand Down Expand Up @@ -68,7 +69,7 @@ const Editly = async (config = {}) => {

const { editAudio } = Audio({ ffmpegPath, ffprobePath, enableFfmpegLog, verbose, tmpDir });

const audioFilePath = !isGif ? await editAudio({ keepSourceAudio, arbitraryAudio, clipsAudioVolume, clips, audioNorm }) : undefined;
const audioFilePath = !isGif ? await editAudio({ keepSourceAudio, arbitraryAudio, clipsAudioVolume, clips, audioNorm, outputVolume }) : undefined;

// Try to detect parameters from first video
let firstVideoWidth;
Expand Down

0 comments on commit 9edb1e4

Please sign in to comment.