11

I have a set of MP3 files that I would like to remove the last 4 seconds. I know that if I know the time duration of each file I can do:

ffmpeg -t ${1} -i inputfilename -acodec copy -vcodec copy outputfilename

Where $1 is the duration of the file minus the 4 seconds.

I'd really like something that would just chop the last 4 seconds off regardless of the length of the file. A "stop 4 seconds before the EOF".

Note: I struggled to figure this command line out, if there's an easier version, I love to see it.

3
  • 1
    If these are simple audio mp3s FFmpeg might be overkill for your needs? Sox will do the job fine: sox input.mp3 output.mp3 trim 0 -4. I can write this up if you are interested in using Sox in this way...
    – andrew.46
    Jul 20, 2021 at 9:04
  • This looks fine, but... I did "sudo apt install sox" and when I run the command I get "sox FAIL formats: no handler for file extension 'mp3'" ?
    – LarryM
    Jul 20, 2021 at 12:17
  • Okay, did: sudo apt-get install libsox-fmt-mp3 and now trimming the end works fine - thanks! But I'd also like to trim 2 seconds from the start odf some other files. I tried: sox input.mp3 output.mp3 trim =2 (and other variations) but that doesn't seem to do it. Suggestions?
    – LarryM
    Jul 20, 2021 at 14:05

3 Answers 3

9

Sometimes when dealing with audio files, rather than audio plus video, a more nuanced application than FFmpeg is SoX. Install a fully featured SoX on Ubuntu as follows:

sudo apt-get install sox libsox-fmt-all

And to trim 4 seconds from the end of your mp3 file the following very simple command is required:

sox input.mp3 output.mp3 trim 0 -4

In this example '0' is the starting position at the beginning of the file while '-4' establishes the end position of the required segment: 4 seconds from the end.

Multiple variations on this, with multiple positions and saved segments, are possible. For example, as you have mentioned in the comments, if you only wanted to remove 2 seconds at the beginning of your file the command line would be:

sox input.mp3 output.mp3 trim 2

In this example no end position is required. The SoX man pages contain many more examples of the trim command if you want more complex usage...

3
  • 1
    Perfect, thank you!
    – LarryM
    Jul 21, 2021 at 11:37
  • 1
    @LarryM Great news that it has worked for you :). Can you 'Accept' the answer by clicking on the check or tick mark near the answer and this way future readers of this question will know that this is the best answer. And have a great day!
    – andrew.46
    Jul 22, 2021 at 5:04
  • I just tried this but... it did change my audio file from 192kbps to 128kbps with no intention of doing so. The file size is a lot smaller, and presumably the quality has taken some hit. Without any input telling this app to change quality, this isn't a positive thing.
    – bcsteeve
    Mar 3 at 0:10
5

Adapted from Cut video with ffmpeg:

ffmpeg -i input.mp3 -ss 4 -i input.mp3 -c copy -map 0:a -map 1:a -shortest -f nut - | ffmpeg -y -f nut -i - -c copy -map 0:0 output.mp3

What this does is uses the same input twice in a roundabout method to trim without needing to know duration and without re-encoding.

  1. The second input has 4 seconds cut off from the beginning.
  2. The -shortest option uses the shortest input duration to determine duration of the outputs. This results in cutting off the last 4 seconds from the first input to match the duration of the truncated second input.
  3. Because both streams are needed for -shortest to work they are piped to another ffmpeg to remove the second input.
3
  • It should be -map 0 -map -0:1 or -map 0:0
    – Gyan
    Jul 20, 2021 at 7:37
  • This chopped the first four seconds off the file, not the last four.
    – LarryM
    Jul 20, 2021 at 12:24
  • @LarryM There was a typo as pointed out by Gyan and this time I actually tested the output.
    – llogan
    Jul 20, 2021 at 15:56
2

You can use ffprobe that should come with ffmpeg to get the duration.

dur=$(($(ffprobe -loglevel error -show_entries format=duration -of default=nk=1:nw=1 inputfilename | xargs printf %.0f)-4))
ffmpeg -t ${dur} -i inputfilename -c copy outputfilename

The first line uses ffprobe to get the duration minus 4 seconds then puts it in a var called dur.

I have also used xargs to round the number because bash only accepts whole numbers when doing math operations.

You can use bc if you need more accuracy.

dur=$(ffprobe -loglevel error -show_entries format=duration -of default=nk=1:nw=1 inputfilename)
dur=$(bc <<< ${dur}-4)
ffmpeg -t ${dur} -i inputfilename -c copy outputfilename
2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .