117

Original Question

I want to be able to generate a new (fully valid) MP3 file from an existing MP3 file to be used as a preview -- try-before-you-buy style. The new file should only contain the first n seconds of the track.

Now, I know I could just "chop the stream" at n seconds (calculating from the bitrate and header size) when delivering the file, but this is a bit dirty and a real PITA on a VBR track. I'd like to be able to generate a proper MP3 file.

Anyone any ideas?

Answers

Both mp3split and ffmpeg are both good solutions. I chose ffmpeg as it is commonly installed on linux servers and is also easily available for windows. Here's some more good command line parameters for generating previews with ffmpeg

  • -t <seconds> chop after specified number of seconds
  • -y force file overwrite
  • -ab <bitrate> set bitrate e.g. -ab 96k
  • -ar <rate Hz> set sampling rate e.g. -ar 22050 for 22.05kHz
  • -map_meta_data <outfile>:<infile> copy track metadata from infile to outfile

instead of setting -ab and -ar, you can copy the original track settings, as Tim Farley suggests, with:

  • -acodec copy
Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
Cheekysoft
  • 35,194
  • 20
  • 73
  • 86
  • I didn't realize ffmpeg could do that. Thank you. – Sridhar Sarnobat Dec 16 '17 at 07:28
  • Just a thought: you may want to skip the beginning of the original song. Say, you can use 30 seconds piece starting at the *third* of the song. In some songs, the first 30 seconds doesn't tell you much as it's just a "setting up the scene" part - for instance *Pink Floyd*'s [Shine On You Crazy Diamond](http://www.youtube.com/watch?v=9FtgbIQyWxk). – Tomas Sedovic Sep 04 '08 at 15:18
  • Just as note, I had a really bad time with ffmpeg, mptsplit and mp3cutter on CentOS, all of them reporting "Header Missing". So, I had to go with MP3 Class and some maths to cut by filesize. – Gardner Feb 28 '13 at 19:36
  • I haven't used it for this specific purpose, but I bet [ffmpeg](http://ffmpeg.mplayerhq.hu/) can do it. – grapefrukt Sep 04 '08 at 14:38

8 Answers8

163

I also recommend ffmpeg, but the command line suggested by John Boker has an unintended side effect: it re-encodes the file to the default bitrate (which is 64 kb/s in the version I have here at least). This might give your customers a false impression of the quality of your sound files, and it also takes longer to do.

Here's a command line that will slice to 30 seconds without transcoding:

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

The -acodec switch tells ffmpeg to use the special "copy" codec which does not transcode. It is lightning fast.

NOTE: the command was updated based on comment from Oben Sonne

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
Tim Farley
  • 11,720
  • 4
  • 29
  • 30
  • 26
    Recent `ffmpeg` versions (at least since 0.10.6) interpret options differently based on position. Input-related options must appear before `-i ...` and output-releated options must appear after `-i ...`. This means `ffmpeg -t 30 -i inputfile.mp3 -acodec copy outputfile.mp3` would *now* be the correct answer. – Oben Sonne Dec 30 '12 at 20:41
  • Can i extract 30 second audio from 15 second input file, it means if file grater then 30 second then extract 30 second but if file 15 second then repeat and extract complete 30 second. – Girish Patidar Jan 11 '16 at 10:01
  • 10
    If you want to set starting time (offset) you can use [`-ss hh:mm:ss[.xxx]`](https://ffmpeg.org/ffmpeg.html#Main-options). Example: `ffmpeg -t 30 -ss 00:00:15.500 -i inputfile.mp3 -acodec copy outputfile.mp3` will slice to *30 seconds* starting from *00h 00m 15s 500ms*. – patryk.beza May 09 '16 at 15:08
  • 2
    for some reason above command didn't worked for me but if i changed it to: `ffmpeg -i inputfile.mp3 -t 30 -acodec copy outputfile.mp3` then it's working perfectly – Krishnendu Jun 28 '16 at 05:27
  • For me the -t and -s options must be used separately in 2 commands. But it works, thanks! – Yan King Yin Jan 21 '17 at 14:25
69

If you wish to REMOVE the first 30 seconds (and keep the remainder) then use this:

ffmpeg -ss 30 -i inputfile.mp3 -acodec copy outputfile.mp3
Tim
  • 1,585
  • 1
  • 18
  • 23
the.jxc
  • 3,373
  • 21
  • 21
18

try:

ffmpeg -t 30 -i inputfile.mp3 outputfile.mp3
John Boker
  • 82,559
  • 17
  • 97
  • 130
15

This command also works perfectly. I cropped my music files from 20 to 40 seconds.

-y : force output file to overwrite.

ffmpeg -i test.mp3 -ss 00:00:20 -to 00:00:40 -c copy -y temp.mp3
petezurich
  • 9,280
  • 9
  • 43
  • 57
Rahul Chauhan
  • 1,424
  • 14
  • 13
11

you can use mp3cut:

cutmp3 -i foo.mp3 -O 30s.mp3 -a 0:00.0 -b 0:30.0

It's in ubuntu repo, so just: sudo apt-get install cutmp3.

Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
6

You might want to try Mp3Splt.

I've used it before in a C# service that simply wrapped the mp3splt.exe win32 process. I assume something similar could be done in your Linux/PHP scenario.

Ryan Duffield
  • 18,497
  • 6
  • 40
  • 40
1

I have got an error while doing the same

Invalid audio stream. Exactly one MP3 audio stream is required.
Could not write header for output file #0 (incorrect codec parameters     ?): Invalid argumentStream mapping:

Fix for me was:

ffmpeg -ss 00:02:43.00 -t 00:00:10 -i input.mp3 -codec:a libmp3lame out.mp3
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
0

My package medipack is a very simple command-line app as a wrapper over ffmpeg.

you can achieve trimming your video using these commands:

medipack trim input.mp3 -s 00:00 -e 00:30 -o output.mp3
medipack trim input.mp3 -s 00:00 -t 00:30 -o output.mp3

you can view options of trim subcommand as:

srb@srb-pc:$ medipack trim -h
usage: medipack trim [-h] [-s START] [-e END | -t TIME] [-o OUTPUT] [inp]

positional arguments:
  inp                   input video file ex: input.mp4

optional arguments:
  -h, --help            show this help message and exit
  -s START, --start START
                        start time for cuting in format hh:mm:ss or mm:ss
  -e END, --end END     end time for cuting in format hh:mm:ss or mm:ss
  -t TIME, --time TIME  clip duration in format hh:mm:ss or mm:ss
  -o OUTPUT, --output OUTPUT

you could also explore other options using medipack -h

srb@srb-pc:$ medipack --help
usage: medipack.py [-h] [-v] {trim,crop,resize,extract} ...

positional arguments:
  {trim,crop,resize,extract}

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         Display version number

you may visit my repo https://github.com/srbcheema1/medipack and checkout examples in README.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
srbcheema1
  • 544
  • 4
  • 16
  • 1
    What's the advantage of this wrapper? Because it doesn't seem any simpler than `ffmpeg -i input -ss -to output` – llogan Sep 03 '19 at 17:01
  • I have aslo added an option of `-t` which can be used alternatively to `-e` which mean suppose i was to trim next 4min 36 sec video, i need not to worry adding those times manually, also i have provided similar ease while cropping the videos, see the examples in README you will get the point why is its CLI more easier than simple ffmpeg. I agree that its not that powerful but for normal person its handy tool. – srbcheema1 Sep 03 '19 at 17:21
  • 2
    `ffmpeg` has the `-to` option which is what your `-t` probably does. – llogan Sep 03 '19 at 17:22
  • what about the crop %age option mentioned in README under crop suboption, is that also available ?? I just created that tool on demand by someone who paid me few bucks, as they dont want to worry about the large cli options list, just they wanted a tool that could do certain tasks with ease, even if there are all options in ffmpeg, but still it would be difficult for noob to find all of them in its command-line help section. this tool has a simple help section easy for a noob to understand – srbcheema1 Sep 03 '19 at 17:26
  • Sure, `-vf "crop=iw*0.1:ih*0.1:0:0"` – llogan Sep 03 '19 at 18:09
  • here the first argument of crop subcommand is width of output video and second one is height of output video,third and fourth is top-left point cordinates. I have provided them the way to mention top-left and bottom-right corner cordinates in terms of percentages. moreover we need not to remember the order and also may skip a value which will by default go to 0(for left,top) or max_width,height(for right,bottom). My main focus was to make it easier to do this on commandline, all one has to do is type `medipack crop` and press tab or `medipack crop -h` – srbcheema1 Sep 03 '19 at 18:21
  • @llogan in `-vf "crop=iw*0.1:ih*0.1:0:0"` you haven't mentioned percentage from bottom just you have mentioned the output height %age. suppose my use case was to crop video 30% from bottom, I would have to do is `medipack crop inp.mp4 -b 30` while ffmpeg woud have done `-vf "crop=iw:ih*0.7:0:0"`. see the calculation one has to do in mind for calculating value to be multiplied by `ih`. it becomes bit difficult when the top-left corner isnt at 0,0 – srbcheema1 Sep 03 '19 at 18:27
  • It was just a rough example to show the syntax. See [crop filter docs](https://ffmpeg.org/ffmpeg-filters.html#crop). – llogan Sep 03 '19 at 18:28
  • basically that was the motivation behind building the wrapper, to reduce search and docs-lookup for a person with minimal requirements. myself i use ffmpeg directly most of the time, but the wrapper was mainly for people with minimal requirements and less technical background. – srbcheema1 Sep 03 '19 at 19:51