Add silence to the end of an MP3

12

4

Do any of you know of a way of adding silence of a fixed duration to the end of an MP3, in Linux? For example using MEncoder, FFmpeg, etc?

It needs to be command line as it will be scripted and run on our server.

I googled around this and the best I could do is using the pad function in SoX, but that won't work with MP3s.

I could convert it to WAV, use SoX, then convert it back to MP3 again and copy the metadata (minus the duration) from the original to the new MP3. But, before I write a script for that i thought I'd see if there's a one-hit solution.

Max Williams

Posted 2013-01-15T14:06:21.090

Reputation: 2 237

2

I think you can accomplish something like this with mp3DirectCut (Windows only, but they say it's compatible with Linux under Wine), which avoids recompressing the sound data. If you were to go MP3 -> WAV -> MP3, you would be recompressing the already MP3 compressed data stream, losing a lot of quality on the way.

– Breakthrough – 2013-01-15T14:11:30.410

Thanks. Can you run windows software via Wine from the command line? I'd prefer to avoid Wine solutions if possible as i'm reluctant to install Wine on our server. – Max Williams – 2013-01-15T14:47:07.123

Hmm, you might want to avoid the Wine route if you don't have it already. Wine itself is a fairly large download, well above a megabyte or two for a simple MP3 cut/merge tool. I'm sure there's an equivalent, Linux-native solution. If I find any additional tools, I'll be sure to let you know. – Breakthrough – 2013-01-15T16:54:18.263

Answers

9

You can do so easily with SoX's pad argument and the following syntax:

sox <oldfile> <newfile> pad <silence at beginning of file> <silence at end of file>

Example:

sox mp3.mp3 mp3withsilence.mp3 pad 0 1

Those silences are in seconds. (Other usages are possible using a different syntax, so as to insert those silences at specific positions. See the SoX documentation for more.)

Fabien Snauwaert

Posted 2013-01-15T14:06:21.090

Reputation: 342

Is this lossless? – Geremia – 2017-10-02T18:14:26.957

Update: I read in the sox manpage that it converts to an internal format then re-encodes… – Geremia – 2017-10-02T18:26:40.713

MP3 is a lossy format. Encoding and re-encoding to a lossy format will progressively degrade the quality of the audio (whether you hear it or not.) As such, it's best to work with lossless formats and only encode to a lossy format once, at the end. For a list of lossy audio codecs: https://en.wikipedia.org/wiki/Lossy_compression#Audio and for a list of lossless audio codecs https://en.wikipedia.org/wiki/Lossless_compression#Audio

– Fabien Snauwaert – 2017-10-04T08:51:55.173

Well, this worked fine after adding 2 more dll files (https://stackoverflow.com/a/23939403/2518705), but LOL, this converted my 320 kbps mp3 into 128 kbps! Ridiculous! )))

– RAM237 – 2019-03-20T11:14:18.680

I should note I tested it OK with MP3 files (with libmad-0.dll and libmp3lame-0.dll installed, respectively for decoding and encoding MP3s.)

As much as possible, I would recommend working with a lossless format and only convert to MP3 at the end only. – Fabien Snauwaert – 2014-04-01T04:21:12.993

that's really cool - thanks Fabien! – Max Williams – 2014-04-01T08:32:19.200

15

With ffmpeg, you can use the aevalsrc filter to generate silence, and then in a second command use the concat protocol to combine them losslessly:

ffmpeg -filter_complex aevalsrc=0 -t 10 10SecSilence.mp3
ffmpeg -i "concat:input.mp3|10SecSilence.mp3" -c copy output.mp3

You can control the length of silence by altering -t 10 to whatever time in seconds you would prefer. Of course, you only need to generate the silence once, then you can keep the file around and use it to pad each of the files you want to. You may also want to look up the concat demuxer - it's slightly more processor-intensive, but you may find it easier to drop into a shell script.

If you want to do it in a single command, you can use the concat filter - this will require you to re-encode your audio (since filtergraphs are incompatible with -codec copy), so the option above will probably be best for you. But this may be useful for anyone working with raw PCM, looking to add silence to the end before encoding the audio:

ffmpeg -i input.mp3 \
-filter_complex 'aevalsrc=0::d=10[silence];[0:a][silence]concat=n=2:v=0:a=1[out]' \
-map [out] -c:a libmp3lame -q:a 2 output.mp3

Control the length of the silence by changing d=10 to whatever time (in seconds) you want. If you use this method, you may find this FFmpeg MP3 encoding guide useful.

evilsoup

Posted 2013-01-15T14:06:21.090

Reputation: 10 085

Great that you don't have to re-encode. Any way of copying the meta tags to the new file? – StormPooper – 2015-04-23T18:30:32.407

6 years later still works! Thank you :) – pmg – 2019-05-27T20:33:54.493

I got this error message: " No such filter: 'aevalsrc=0::d=10[silence];[0:a][silence]concat=n=2:v=0:a=1[out]' Error initializing complex filters. Invalid argument" when trying to execute it – SZT – 2019-05-28T10:13:13.797

@pmg did you run it exactly as it is? or did you modify it? – SZT – 2019-05-28T10:14:12.577

@SZT: I did the 2 separate commands. First one, to create 3 seconds silence, "exactly as it is" (-t 3 and different filename). Second one I removed the -c copy option (apparently reencoding the files and losing quality, which I really don't care about for my mobile ringing music :-) – pmg – 2019-05-28T11:45:43.593

1for future reference: if you face error like me, try replacing single quotes with double quotes – SZT – 2019-05-28T12:05:52.643

thanks @evilsoup. I just tried that and got the following -

max-thinkpad-linux:~ $ ffmpeg -filter_complex aevalsrc=0 -t 4.61 silence.mp3 ffmpeg version 0.8.4-4:0.8.4-0ubuntu0.12.04.1, Copyright (c) 2000-2012 the Libav developers built on Nov 6 2012 16:51:33 with gcc 4.6.3 *** THIS PROGRAM IS DEPRECATED *** This program is only provided for compatibility and will be removed in a future release. Please use avconv instead. Unrecognized option 'filter_complex' Failed to set value 'aevalsrc=0' for option 'filter_complex' – Max Williams – 2013-01-15T15:31:25.883

@max First of all, you're actually using avconv from the libav project - they're a fork of FFmpeg that Debian & Ubuntu are using instead of the main project, and they provide a crippled version of ffmpeg. Try using avconv instead - the syntax should be the same, just replace ffmpeg with avconv. – evilsoup – 2013-01-15T15:34:22.417

If that doesn't work, try upgrading to a newer version of ffmpeg. Since you're on Ubuntu, you should be able to use this PPA, or for the very latest version you could compile it from source.

– evilsoup – 2013-01-15T15:36:42.587

1

@MaxWilliams Or you could download a static build, which you don't have to compile first. Just download, extract, use.

– slhck – 2013-01-15T20:18:49.003