79

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.

Community
  • 1
  • 1
marcgg
  • 65,020
  • 52
  • 178
  • 231

2 Answers2

121

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

David Schuler
  • 2,375
  • 1
  • 14
  • 6
Michael Madsen
  • 54,231
  • 8
  • 72
  • 83
  • 4
    I think this will not work now, the postion of -acodec matters so should be: ffmpeg -ss 30 -t 70 -i inputfile.mp3 -acodec copy outputfile.mp3 – Federico Mar 13 '15 at 17:58
  • 1
    it also appears that the `-i` option should be first – e271p314 Mar 23 '15 at 06:41
  • making the -i first will make it fail to skip to the first 30s, the -ss should always come before the -i – Big Zak Apr 27 '16 at 07:21
  • 1
    -t should come after -i. ffmpeg -ss 30 -i inputfile.mp3 -t 70 -acodec copy outputfile.mp3 – bgth Apr 12 '21 at 01:46
24

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
Pau Coma Ramirez
  • 4,261
  • 1
  • 20
  • 19
  • 1
    Nice explaination. If anyone got error check this -> https://stackoverflow.com/a/63431041/7783718 – Abhay Koradiya Dec 05 '20 at 13:13
  • Make sure to make `-i input.mp3` the first param of ffmpeg – Natim Jan 20 '21 at 11:09
  • 1
    Hi @Natim, thanks for your comment. Could you elaborate on why you recommend to make the input the first parameter? – Pau Coma Ramirez Jan 20 '21 at 16:30
  • When I used `ffmpeg -ss 59:05 -c:a copy -t 90 -i input.mp3 output.mp3` with ffmpeg 4.3.1 I encountered a `Unknown decoder 'copy'` which was fixed by putting the `-i` in first position (or at least before `-c:a copy`) – Natim Jan 21 '21 at 12:23
  • 1
    aha, yes, it has to do with the "option" `-c:a copy`, if you put `-c:a copy` before the definition of the input `-i input.mp` ffmpeg is attempting to force the decoder to the one that you have specified. `copy` is not a decoder but instructs ffmpeg to copy directly without decoding and re-encoding the the input file, this is why you need to specify it after defining the input file in the case of stream copying. [More info on copy](https://stackoverflow.com/a/38381173/2078851) – Pau Coma Ramirez Jan 21 '21 at 12:50
  • what is `samples` number? etc `Start: 3s+(((00756samples))) (3.017142857s)`. This value causes the output to be inaccurate. – Farzad Nov 10 '21 at 13:49
  • Hi Farzad, samples in this context is describing a specific point in time in samples instead of fractions of a second. The audio bit stream is sampled at 44100 Hz --> This means 44100 samples in a second. 3 seconds and 756 samples is the same as 3 seconds and 756/44100 seconds = 0.017142857 seconds . This was the exact position where the trimmed version started/ended with respect to the original. – Pau Coma Ramirez Nov 11 '21 at 13:19