Increasing a file's volume using VLC CLI - audio

My goal is to have a script that takes an audio file and increases its volume by 50%.
I currently use the following AutoHotKey snippet to encode a file to MP3:
run_string := "bash -c ""\""c:\Program Files\VideoLAN\VLC\vlc.exe\"" -I dummy \""" . file_path . "\"" --sout='#transcode{acodec=mp3,vcodec=dummy}:standard{access=file,mux=raw,dst=\""" . file_path . ".mp3\""}' vlc://quit"""
How can I modify this line to not only encode to mp3, but also increase the volume of the file by 50%? I tried setting --volume 150 but it just made the file play, while I don't want to play, I want to have it saved with that volume.
If you have suggestions for other Windows-compatible tools to modify audio that can do this, (along with instructions on how to do this) I'll be happy to hear about them.

I suggest you to use ffmpeg. it is very powerful, cross platform 32 or 64 bit, audio and video converter. Can be downloaded from Zeranoe FFmpeg - Builds
Below sample commands work for audio extracting from video, or audio converter with volume increasing or decreasing support.
Extract audio from video to MP3, or convert audio to MP3 (sample InputFilePath_VideoOrAudio = "e:\video.mp4" or "e:\audio.m4a")
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec libmp3lame -ab 192k -ar 48000 -sn -dn -vn "E:\out.mp3"
Extract audio from video to MP3 and increase volume 150% while extracting add -af "volume=1.5" parameter.
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec libmp3lame -ab 192k -ar 48000 -sn -dn -vn -af "volume=1.5" "E:\out.mp3"
List of audio converter parameters (mp3,ogg,ac3,wma,flac,wav,aiff,m4a....). to change volume level while converting to audio add -af "volume=VolumeValue" parameter.
VolumeValue=0.5 decrease volume %50
VolumeValue=1.5 increase volume %150
VolumeValue=2.0 increase volume %200 and so on.
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec libmp3lame -ab 192k -ar 48000 -sn -dn -vn -af "E:\out.mp3"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec ac3 -ab 192k -ar 48000 -sn -dn -vn "E:\out.ac3"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -f ogg -acodec libvorbis -ab 192k -ar 48000 -sn -dn -vn "E:\out.ogg"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec wmav2 -ab 192k -ar 48000 -sn -dn -vn "E:\out.wma"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec flac -sn -dn -vn "E:\out.flac"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -sn -dn -vn "E:\out.wav"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -f aiff -sn -dn -vn "E:\out.aiff"
e:\ffmpeg\ffmpeg.exe -y -i "InputFilePath_VideoOrAudio" -acodec aac -ab 192k -ar 48000 -sn -dn -vn "E:\out.m4a"
Note 1: some codecs can be experimental in such case you should use -strict experimental or -strict -2 parameters.
Note 2: -ab parameter means audio bit rate. Some devices can not play audio file that bit rate greater than -ab 192k. Use -ab 128k or -ab 192k with -ar 44100 parameters to produce audio file that can be playable most of the mobile devices. -ac 2 parameter means stereo -ac 1 means mono.
to convert specific part of the input file use -ss 00:00:00 and -t parameters. -ss means Start From -t means duration. Important: parameter -ss should placed before the -i parameter, otherwise ffmpeg seeks to -ss position slowly.
Samples: assume that input file duration is 00:20:00 (20 minutes)
using only -ss 00:05:00 means convert input file starting from 5th minute to end of the input file. Duration of the output file will be 15 minutes.
using -ss 00:05:00 with -t 120 or -t 00:02:00 means convert 120 seconds, starting from 5th minute. Duration of the output file will be 120 seconds.
e:\ffmpeg\ffmpeg.exe -y -ss 00:05:00 -i "InputFilePath_VideoOrAudio" -t 120 -acodec libmp3lame -ab 192k -ar 48000 -sn -dn -vn -af "E:\out.mp3"
Note: -y means in advance YES to ffmpeg's yes/no questions such as output file already exist, over write? with -y parameters ffmpeg over writes the output file if it is already exist without asking the user.
-sn disables subtitle, -vn disable video, -dn disable data streams for output file.

If you just want a CLI tool then you could use ffmpeg:
ffmpeg.exe -i test.mp3 -af volume=1.5 loud.mp3
^ ^ ^
input new volume level output name
If you'd like to be able to do it programmatically, looking at your profile I deduced that python should not be a problem :)
So you can use the nice pydub module together with ffmpeg (or avconv which it also supports) for your task.
E.g:
from pydub import AudioSegment
AudioSegment.converter = r"C:\PATH_TO_FFMPEG_DIR\bin\ffmpeg.exe"
sound = AudioSegment.from_mp3("test.mp3") # <- the input file
new = sound.export("loud.mp3", format="mp3", parameters=["-vol", "384"]) # 384 <-> 150% volume
new.flush()
new.close()
The reason for 384 is that the ffmpeg doc states that
-vol volume change audio volume (256=normal)
So 256*1.5 = 384
Tested this on my windows 7 machine just now...
Hope this helps.

The "--volume" option in VLC doesn't actually change the volume of the output video as you would think it would. What you want to do is add the compressor filter and then set the "compressor-makup-gain". Set it to a value from 1-24 depending on how loud you want the video to be. So your command would be something like this:
run_string := "bash -c ""\""c:\Program Files\VideoLAN\VLC\vlc.exe\"" -I dummy \""" . file_path . "\"" --sout='#transcode{acodec=mp3,vcodec=dummy,afilter=compressor}:standard{access=file,mux=raw,dst=\""" . file_path . ".mp3 --compressor-makeup-gain=20\""}' vlc://quit"""
By the way, for anyone who is trying to figure out how to use VLC to increase the volume of the audio in a video file, here's how you can do that:
"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" yoursourcefile.mp4 :sout=#transcode{acodec=mp3,ab=128,channels=2,samplerate=44100,afilter=compressor}:file{dst=outputfilename.mp4} :sout-all :sout-keep --compressor-makeup-gain=20
Replace "yoursourcefile.mp4" and "outputfilename.mp4" with your own file names. In my experience, VLC crashed about half the time I ran this command, so you may need to try it more than once if it crashes on you.

Run this on a dir to increasing all files volume on that dir, one by one (or else it would eat up all CPU)
FOR %f IN (*) DO (start /wait "" "C:\Program Files
(x86)\VideoLAN\VLC\vlc.exe" %f
:sout=#transcode{acodec=mp3,afilter=compressor}:file{dst=Boost%f}
:sout-all :sout-keep --play-and-exit --compressor-makeup-gain=10)

I believe mp3gain has a command line option for this. You could run this as a separate pass over the generated file:
http://mp3gain.sourceforge.net/

Related

How do I convert wav into an mxf file with timecode?

I'm looking for a way to convert wav(16bit, 48kHz, LPCM) into an mxf file with timecode.
Since ffmpeg supports mxf, I'm trying, but I don't know the command.
ffmpeg -i ./input.wav [hh:mm:ss.ff, name1] [hh:mm:ss.ff, name2]... ./output.mxf
I'm expecting the above command, but does anyone know?
MXF is a pain
The default MXF muxer requires video.
The -timecode option with MXF requires video.
The mxf_opatom muxer allows just audio, but only mono with 48000 MHz sample rate, so each channel will need to be in its own MXF file.
Workaround 1: Pipe
ffmpeg -i input.wav -ar 48000 -c:a pcm_s16le -timecode 01:02:03:04 -f nut - | ffmpeg -i - -c:a pcm_s16le -f mxf_opatom output.mxf
I'm assuming your audio is mono (you didn't say what it is). If your input is multichannel then output each channel into its own file.
Use 01:02:03:04 for non-drop timecode, and 01:02:03.04 or 01:02:03;04 for drop.
Workaround 2: Dummy/blank video
Just ignore the video.
Non-drop timecode:
ffmpeg -f lavfi -i color=r=25 -i input.wav -timecode 01:02:03:04 -c:a copy -shortest output.mxf
Drop timecode:
ffmpeg -f lavfi -i color=r=30000/1001 -i input.wav -timecode 01:02:03.04 -c:a copy -shortest output.mxf

How to convert High bitrate MP3 to lower rate using FFmpeg

We want to convert 320kbps mp3 file to 128kbps mp3 so currently we are using below ffmpeg command but its not working.
ffmpeg -i input.mp3 -codec:a libmp3lame -qscale:a 5 output.mp3
Result:-the output bitrate same as input mp3.
And we are following the FFmpeg Encoding guideline for that here is the link :- https://trac.ffmpeg.org/wiki/Encode/MP3
so please suggest any solution.
I tried your shown command (tested on Windows / commandline) :
ffmpeg -i input.mp3 -codec:a libmp3lame -qscale:a 5 output.mp3
Result : It works for me. However the -qscale:a 5 makes FFmpeg decide on an average bitrate for you. With one (320k) MP3 file I got it giving a close convert of 134kbps. This is expected since :
lame option Average kbit/s Bitrate range kbit/s ffmpeg option
-V 5 130 120-150 -q:a 5
Solution :
Instead of making the internal mp3 frames hold different bitrates (that vary to acommodate the "current" perceived audio, eg: think "silent" parts using smaller rate of bits/bytes compared to "busy" audio parts), so just set a constant bitrate of 128kbps as you need.
I would just set it to constant 128kbps manually and explicitly with :
ffmpeg -i input.mp3 -codec:a libmp3lame -b:a 128k output.mp3
I use this shellscript in order to not visit this stackoverflow-page over and over again :)
#!/bin/bash
[[ ! -n $1 ]] && {
echo "Usage: mp3convert <input.mp3> <output.mp3> <bitrate:56/96/128/256> <channels> <samplerate>"
exit 0
}
set -x # print next command
ffmpeg -i "$1" -codec:a libmp3lame -b:a "$3"k -ac "$4" -ar $5 "$2"
Make sure your version of FFmpeg has libmp3lame enabled. The selected answer didn't work for me, but this did:
ffmpeg -v debug -i "input.mp3" -c:a libmp3lame \
-b:a 128k -ac 2 -ar 44100 -vn "output.mp3"
-ac 2 - output has 2 (stereo) audio channels
-ar 44100 - sample rate of 44100Hz, which is ideal for high quality music.
Although, in 2022 I wouldn't recommend converting to 128kbps since storage space is much more cheap and abundant nowadays.
I think -b:a 192k strikes the best balance between compression and quality for most people (unless you're an audiophile with $1000 headphones, and even then you'd be better off using FLAC anyways).

libav / ffmpeg output optimisation for small file sizes

I am using the following command to take an audio mp3 file and make a video out of it (by using a static jpg picture). My aim is to get a mp3 audio that is as small as possible with still acceptable quality.
frequency="11000"
bitrate="45000"
avconv -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -metadata STEREO_MODE=mono -c:v libx264 -ar "$frequency" -b:a "$bitrate" -ac 0 result.mkv
My questions are:
1. how can I achieve that the resulting file is MONO?
2. is it possible to reduce the bitrate furthermore? I would like to use values below 45000, too.
3. My aim is to get control of the parameters that influence the file size most significantly. Presently I know that the frequency is quite important. Are there any other parameters that would help me to get a very small output file with still acceptable quality?
Thanks in advance.
Since you are coding to a compressed audio codec, the frequency doesn't directly affect the file size. However, a frequency of 11 kHz will reduce quality of music.
Instead, I'd suggest
frequency="22050"
bitrate="48000"
ffmpeg -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -c:v libx264 -crf 28 \
-ar "$frequency" -b:a "$bitrate" -ac 1 result.mkv
The CRF parameter controls video quality - lower values produce better quality but larger files. You'll get more savings from controlling that than audio bitrate, which is at the lower end anyway.
If your build has libfdk_aac included, you can instead use
frequency="22050"
bitrate="32000"
ffmpeg -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -c:v libx264 -crf 28 \
-ar "$frequency" -c:a libfdk_aac -profile:a aac_he_v2 -b:a "$bitrate" -ac 1 result.mkv

How to overlay/downmix two audio files using ffmpeg

Can I overlay/downmix two audio mp3 files into one mp3 output file using ffmpeg?
stereo + stereo → stereo
Normal downmix
Use the amix filter:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex amix=inputs=2:duration=longest output.mp3
Or the amerge filter:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex amerge=inputs=2 -ac 2 output.mp3
Downmix each input into specific output channel
Use the amerge and pan filters:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex "amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3" output.mp3
mono + mono → stereo
Use the join filter:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex join=inputs=2:channel_layout=stereo output.mp3
Or amerge:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex amerge=inputs=2 output.mp3
mono + mono → mono
Use the amix filter:
ffmpeg -i input0.mp3 -i input1.mp3 -filter_complex amix=inputs=2:duration=longest output.mp3
More info and examples
See FFmpeg Wiki: Audio Channels
Check this out:
ffmpeg -y -i ad_sound/whistle.mp3 -i ad_sound/4s.wav -filter_complex "[0:0][1:0] amix=inputs=2:duration=longest" -c:a libmp3lame ad_sound/outputnow.mp3
I think it will help.
The amix filter helps to mix multiple audio inputs into a single output.
If you run the following command:
ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
This command will mix 3 input audio streams (I used two mp3 files, in the example below) into a single output with the same duration as the first input and a dropout transition time of 3 seconds.
The amix filter accepts the following parameters:
inputs:
The number of inputs. If unspecified, it defaults to 2.
duration:
How to determine the end-of-stream.
longest:
The duration of the longest input. (default)
shortest:
The duration of the shortest input.
first:
The duration of the first input.
dropout_transition:
The transition time, in seconds, for volume renormalization when an input stream ends. The default value is 2 seconds.
For example, I ran the following command in Ubuntu:
FFMPEG version: 3.2.1-1
UBUNTU 16.04.1
ffmpeg -i background.mp3 -i bSound.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=0 -codec:a libmp3lame -q:a 0 OUTPUT.mp3
-codec:a libmp3lame -q:a 0 was used to set a variable bit rate. Remember that, you need to install the libmp3lame library, if is necessary. But, it will work even without the -codec:a libmp3lame -q:a 0 part.
Reference: https://ffmpeg.org/ffmpeg-filters.html#amix
For merging two audio files with different volumes and different duration following command will work:
ffmpeg -y -i audio1.mp3 -i audio2.mp3 -filter_complex "[0:0]volume=0.09[a];[1:0]volume=1.8[b];[a][b]amix=inputs=2:duration=longest" -c:a libmp3lame output.mp3
Here duration can be change to longest or to shortest, you can also change the volume levels according to your need.
If you're looking to add background music to some voice use the following command as in the gaps the music will become loud automatically:
ffmpeg -i bgmusic.mp3 -i audio.mp3 -filter_complex "[1:a]asplit=2[sc][mix];[0:a][sc]sidechaincompress=threshold=0.003:ratio=20[bg]; [bg][mix]amerge[final]" -map [final] final.mp3
In this threshold is something whose value will decide how much loud the audio should be, the less the threshold more the audio will be. Ratio gives how much the other audio should be compressed, the more the ratio the more the compression is.
If they are different length, you can use apad to add a silent sound to the shortest one
With Bash
set 'amovie=a.mp3 [gg]; amovie=b.mp3 [hh]; [gg][hh] amerge'
ffmpeg -f lavfi -i "$1" -q 0 c.mp3
Example
You can use the following command arguments:
// Command is here
let commandValue = "-y -i \(recordedAudioPath) -i \(backgroundAudio) -filter_complex [\(0):a][\(1):a]amerge=inputs=\(2)[a] -map [a] -ac \(2) -shortest -preset ultrafast \(outputPath)"
MobileFFmpeg.execute(commandValue)

ffmpeg stream offset command (-itsoffset) not working

I would really appreciate if someone could give some pointers regarding the use of itsoffset with ffmpeg. I have read a number of posts on this subject, some of them explain very clearly how to re-synchronize audio and video with -itsoffset, but I haven't been able to make it work.
My avi file is encoded with ffmpeg, in two passes, using the following command for the second pass:
ffmpeg -i whole-vts_01.avs -pass 2 -y -vcodec libxvid -vtag XVID -b:v 1300K -g 240 -trellis 2 -mbd rd -flags +mv4+aic -acodec ac3 -ac 2 -ar 48000 -b:a 128k output.avi
For whatever reason, I end up with a 1 sec delay in the video (or the audio is 1 sec early). It doesn't happen too often but I see it from time to time.
Among other attempts, I have tried the following:
(1) ffmpeg -i output.avi -itsoffset 00:00:01.0 -i output.avi -vcodec copy -acodec copy -map 0:0 -map 1:1 output-resynched.avi
(2) ffmpeg -i output.avi -itsoffset 00:00:01.0 -i output.ac3 -vcodec copy -acodec copy -map 0:0 -map 1:0 output-resynched2.avi
(3) ffmpeg -itsoffset -00:00:01.00 -i output.avi output-resynched8.avi
(4) ffmpeg -i output.avi -itsoffset -1.0 -i output.avi -vcodec copy -acodec copy -map 0:1 -map 1:0 output-resynched13.avi
Here are the results:
Audio garbled and only 5m 35 s long vs. 1h 41m.
(Output.ac3 is audio component of output.avi) Video and audio
identical to original, offset didn't work
Audio did get shifted, but original encoding parameters replaced with default ones (as expected).
Audio garbled and only 9m 56s long vs. 1h 41m.
I see that many people explain, and apparently use the process described above, but it doesn't seem to be working for me. Am I missing something obvious? I would very much like to be able to use -itsoffset as it is cleaner than my workaround solution.
FWIW, here is a different, and longer way of obtaining the desired result:
First create a shifted video only file using -ss:
ffmpeg -i output.avi -ss 1.0 -vcodec copy -an oupput_videoshifted.avi
Then extract the audio:
ffmpeg -i output.avi -vn -acodec copy outputaudioonly.ac3
And finally remux both components:
ffmpeg -i output_videoshifted.avi -i output_audioonly.ac3 -vcodec copy -acodec copy -map 0:0 -map 1:0 output-resynched14.avi
The process works, is fast enough, but I would really prefer to use the one pass -itsoffset solution.
Here is what I did and it work for me
The first input setting -i and the second input is come from the same one video file.
Delay 1 second in first input video and the second input audio just make a copy
ffmpeg -y -itsoffset 00:00:01.000 -i "d:\Video1.mp4" -i "d:\Video1.mp4"
-map 0:v -map 1:a -vcodec copy -acodec copy
-f mp4 -threads 2 -v warning "Video2.mp4"
Delay 1 second in second input audio and the first input video just make a copy
ffmpeg -y -i "d:\Video1.mp4" -itsoffset 00:00:01.000 -i "d:\Video1.mp4"
-map 0:v -map 1:a -vcodec copy -acodec copy
-f mp4 -threads 2 -v warning "Video2.mp4"
The problem is located on -vcodec copy -acodec copy because the shifting will only work on keyframes. I have had the same problem.
Just don't copy (audio/)video, try the thing with -itsoffset, but use
-vcodec libxvid -vtag XVID -b:v 1300K -g 240 -trellis 2 -mbd rd -flags +mv4+aic -acodec ac3 -ac 2 -ar 48000 -b:a 128k
for re-encoding. It should work.

Resources