editly icon indicating copy to clipboard operation
editly copied to clipboard

Normalizing Audio

Open bkroggel opened this issue 5 years ago • 4 comments

From my point of view it would be quite helpful if editly includes the functionality to automatically normalize all video/audio files before stitching them together. That way we would eliminate differences in sound levels between the single files and create a more seamless video clip.

For reference: https://github.com/slhck/ffmpeg-normalize

bkroggel avatar Apr 29 '20 18:04 bkroggel

I think audio should not be normalized as it would make silent clips very loud. Instead I'd provide an option to change each clip's volume relatively.

jukkatupamaki avatar Apr 30 '20 11:04 jukkatupamaki

As of now, individual clip's audio is discarded and only the audio-file-path will be used for the whole video. But in the future we could look into this

mifi avatar Apr 30 '20 15:04 mifi

I think a sensible interface would look like this:

clips: [{ 
    layers: [
        { type: 'video', path: './assets/IMG_4605.MOV', volume: 1 }, // include video clip audio
        { type: 'audio', path: './music.mp3' , audioEffects: ['normalize'], volume: 0.75 } // normalize but then reduce to 75 % 
    ] 
}]

for changing all clips, set the default:

projectAudio: './bgmusic.mp3', // this is a global/project audio file (previously called audioFilePath)
projectAudioEffects: ['normalize'],
projectAudioVolume: 0.9, // this would reduce the volume of the projectAudio file after it was normalized to 90%
defaults: {
    layers: [ 
        { type: 'video', audioEffects: ['normalize'], volume: 1 }, // this would normalize all audio from video clips. `volume: 1` would be required if we don't make it implicit
        { type: 'audio', audioEffects: ['normalize'] } // this would normalize all other audio clips, volume is already implicitly set to 1 for audio layers
},
clips: [{ 
    layers: [
        { type: 'video', path: './assets/IMG_4605.MOV' },
        { type: 'video', path: './assets/IMG_4605.MOV', audioEffects: null } // but you could still override it like this ?
    ] 
}]

http://www.sengpielaudio.com/calculator-levelchange.htm

edit: instead of having an ugly includeAudio: true flag we could just make the default be volume: 0 and when volume === 0 then it will not even include it in the ffmpeg concat filter

edit2: it's probably better to just move normalize into a separate string array for audioEffects. Volume would be the last filter. So you could normalize but have lower than 0db (absolute maximum volume)

if audioEffects is set then should volume should be implicitly set to 1 (normal volume) for video layers ?

ps. if we do this correctly then we can do this and listen to the soothing 3D printer-like sounds of GL:

clips: [{ 
    layers: [
        { type: 'rainbow-colors', volume: 11 } // oooooohhhhhh 😌
    ] 
}]

chapmanjacobd avatar Apr 30 '20 17:04 chapmanjacobd

I had an issue where I needed this. I think "dynaudnorm" is quite good so maybe audio filters per clip is not very necessary. I think a lot can be done with few simple options on the global audio output like acompressor and dynaudnorm but there is also still a need for controlling the audio level of bg music or other SFX/audio sources

here are some great resources:

https://medium.com/@jud.dagnall/dynamic-range-compression-for-audio-with-ffmpeg-and-compand-621fe2b1a892 https://superuser.com/questions/1104534/how-to-use-compressor-with-ffmpeg https://superuser.com/questions/1303036/adjusting-audio-with-varying-loudness-recorded-talks-with-ffmpeg https://github.com/stoyanovgeorge/ffmpeg/wiki/How-to-Find-and-Fix-Corruptions-in-FFMPEG

of course, dynamic range compression is completely different from normalizing but it might be what some people want when they say 'normalize'

chapmanjacobd avatar May 07 '20 05:05 chapmanjacobd