1

I have a directory tracks with 3 files track1.mp3, track2.mp3, track3.mp3. I want to select a random chunk of 10 seconds from each file and combine these chunks into a new file called sample.mp3. How do I do this using ffmpeg?

I am pretty new to ffmpeg and all I managed to do so far is splitting a file into chunks

ffmpeg -i track1.mp3 -f segment -segment_time 10 -c copy out%03d.mp3

Someone, please help. I am on Mac OSX high sierra and bash shell

Tony Vincent
  • 113
  • 5

1 Answers1

3

You can use the following bash script:

numFiles=3
maxStart=10
idx=1
for randomStart in $(jot -r $numFiles 0 $maxStart); do
    ffmpeg -y -ss "$randomStart" -i "track${idx}.mp3" -t 10 -c:a copy "track${idx}-chunk.mp3"
    idx=$((idx + 1))
done

Here, you have to specify the number of files (track1 through track3) and the maximum start position (e.g., if your files are only 20 seconds long, you should at most start from 00:00:10).

The jot utility is used to create random numbers between 0 and $maxStart (i.e., 10 in the above example). On Linux, jot is not available; instead use shuf -n $numFiles -i 0-$maxStart.

Then, concatenate the chunks (see the FFmpeg Wiki entry):

ffmpeg -f concat -safe 0 -i <(for f in ./*-chunk.mp3; do echo "file '$PWD/$f'"; done) -c copy output.mp3

It uses special shell syntax to construct a temporary concatenation file. This will copy the bitstreams, so no re-encoding is done.

slhck
  • 223,558
  • 70
  • 607
  • 592
  • Thanks for a great answer. You have been very helpful, I have no means of knowing the length of my files beforehand – Tony Vincent Mar 27 '18 at 07:55
  • In this case you would have to approach it differently: iterate through the files, run a first pass with ffmpeg or ffprobe to [get their length in seconds](https://superuser.com/a/945604/48078), and use that to generate a new random number for the maximum start position. But that's where I'd stop using Bash and use Python or Ruby instead. – slhck Mar 27 '18 at 07:58