How to crop a mp3 from x to x+n using ffmpeg?

Following this question I decided to use ffmpeg to crop MP3s. On another question I found this way of doing it:

ffmpeg -t 30 -acodec copy -i inputfile.mp3 outputfile.mp3

The problem is that I don't want to crop the first 30 seconds, I want to crop from x to x+n, like from 30s to 100s. How would I go and do this?

I'm reading the man for ffmpeg but this is not really straightforward, especially since I just discovered about ffmpeg and I'm not familiar with audio/video editing softwares, so any pointers would be appreciated.


Solution 1:

Take a look at the -t and -ss arguments. They should do what you want.

-t duration

Restrict the transcoded/captured video sequence to the duration specified in seconds. hh:mm:ss[.xxx] syntax is also supported.

-ss position'

Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported.

For example, ffmpeg -ss 30 -t 70 -i inputfile.mp3 -acodec copy outputfile.mp3 should do the trick for the range you mentioned (30s-100s).

Solution 2:

To expand a bit on Michael Madsens' Answer:

I've found either of the following satisfactory for trimming my audio files:

  • ffmpeg -ss <start position>-t<duration> -i inputfile -c:a copy outputfile
  • ffmpeg -ss <start position>-i inputfile -t<duration> -c:a copy outputfile

Note: -acodec is an alias for codec:a which can be specified also as c:a

As specified in the Main Options FFMPEG Documentation

-t duration (input/output)

  • When used as an input option (before -i), limit the duration of data read from the input file.
  • When used as an output option (before an output url), stop writing the output after its duration reaches duration.

-ss position (input/output)

  • When used as an input option (before -i), seeks in this input file to position.
  • When used as an output option (before an output url), decodes but discards input until the timestamps reach position.

duration and position follow the Time Duration Syntax :

  • [-][HH:]MM:SS[.m...] or [-]S+[.m...][s|ms|us]

Side Note: An answer on How to detect intervals of silence with FFMPEG may also be of interest.


Differences between seeking and duration as input or output

Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it will be preserved.

I did a couple Tests on the following file:

Input #0, mp3, from 'test16s.mp3':
  Duration: 00:00:16.20, start: 0.025057, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s

Aligned the outputs in Audacity in comparison to the original and got the following:

  • ffmpeg -ss 3 -t 5 -i test16s.mp3 -c:a copy out.mp3
    • Start: 3s+00756samples (3.017142857s)
    • End: 8s+02062samples (8.04675737s)
    • Duration : 5s+01306samples (5.029614512s)
  • ffmpeg -ss 3 -i test16s.mp3 -t 5 -c:a copy out.mp3
    • Start: 3s+00756samples (3.017142857s)
    • End: 8s+00910samples (8.020634921s)
    • Duration : 5s+00154samples (5.003492063s)
  • ffmpeg -i test16s.mp3 -ss 3 -t 5 -c:a copy out.mp3
    • Warning: This created a file that some mp3 decoders gave error on attempting to open.
    • Start: 2s+42184samples (2.956553288s)
    • End: 8s+01071samples (8.024285714s)
    • Duration : 5s+02987samples (5.067732426s)
  • ffmpeg -t 5 -i test16s.mp3 -ss 3 -c:a copy out.mp3
    • Warning: This created a file that some mp3 decoders gave error on attempting to open.
    • Start: 2s+42184samples (2.956553288s)
    • End: 5s+02043samples (5.046326531s)
    • Duration : 2s+03959samples (2.089773243)

In an attempt to get to see the seek jump I found interesting results using :

  • ffmpeg -ss <secs> -i test16s.mp3 -t 5 -c:a copy out.mp3

    • <secs> = 3, 2.99, 2.98, 2.97
      • Start: 3s+00756samples (3.017142857s), Duration:5s+00154
    • <secs> = 2.96
      • Start: same as above, Duration: 4s+41951
    • <secs> = 2.95
      • Start: 2s+43704 (2.991020408), End:7s+42707 Duration:4s+43103
    • <secs> = 2.94,2.93
      • Start: same as above, Duration: 4s+41951
    • <secs> = 2.92
      • Start: 2s+42552 (2.964897959s), Duration: 4s+43103
  • ffmpeg -ss <secs> -t 5 -i test16s.mp3 -c:a copy out.mp3

    • <secs> = 3
      • Start: 3s+00756 (3.017142857s), Duration:5s+01306 (5.029614512s)
    • <secs> = 2.99, 2.98, 2.97
      • Start: same, Duration: 5s+00155
    • <secs> = 2.96
      • Start: same, Duration: 4s+43103
    • <secs> = 2.95
      • Start: 2s+43704 (2.991020408), End:7s+43859 Duration:5s+00155
    • <secs> = 2.94,2.93
      • Start: same, Duration: 4s+43103
    • <secs> = 2.92
      • Start: 2s+42552 (2.964897959s), Duration: 5s+00155

Concluding that with a Stream Copy, appears as if the minimal seek resolution in my specific file ,(Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s), was:

  • Seek Step of : 1152 samples, 26.122449 ms
  • Seek position Error of up to 70 ms