12

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.

llogan
  • 12,348
LarryM
  • 587

4 Answers4

10

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...

andrew.46
  • 39,359
7

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.
llogan
  • 12,348
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
Aenfa
  • 418
0

You can simply use a combination of the areverse and atrim filters. Use the areverse filter to reverse the audio, and then use the atrim filter to trim off the first 4 seconds (which is actually the last 4 seconds), and then use the areverse filter again one last time and you're done.

ffmpeg -i input.mp3 -af areverse,atrim=4,areverse output.mp3