3

Everyday I have about 10 different mp3 files created on my server. What I would like to do is setup a cronjob to run at night and combine the current days tracks into one mp3 track. I don't care so much about the ID3 info, though if such a method has the capability to merge these, then that would be ideal.

Keeping it simple here is what I need to do:

  • Combine .mp3 files from current day
  • Delete the individual files after, as I only need the combined mp3

I'm open to using Python or a Bash script to do this, however any other solutions would work as well. Is this possible to do?

1 Answers1

2

Solution using ffmpeg's concat protocol

You must first find the files you want to merge (newer than one day)

find path/to/files -name '*.mp3' -mtime -1

And merge them as described in another question. Finally the string used for concatination must be modified to be valid for rm (quotes instead of pipes etc).

The final script is then:

#!/bin/bash
concat=$(echo -n "concat:" && find path/to/files -name '*.mp3' -mtime -1 -exec echo -n "{}|" \;)
ffmpeg -i "${concat%|}" -acodec copy output.mp3

IFS=$'\n'
for i in $(echo $concat | sed -e 's/^concat://' -e 's/|$//' -e 's/|/\n/g');
    do rm -i $i
done

${concat%|}strips the final pipe in the variable and the sed expression creates a list of files (one per line) to be deleted by rm.

Sortable solution (needs ffmpeg 1.1 or newer)

With more recent versions of ffmpeg the files that shall be concatenated can be read from a file. This allows easy sorting of the snippets.

#!/bin/bash

IFS=$'\n'

concatlist=$(find /path/to/files -name '*.mp3' -mtime -1 -printf "file '%p'\n" | sort)

ffmpeg -f concat -i <(echo "$concatlist") -c copy output.mp3

for i in $(echo "$concatlist" | sed -e "s/^file '//" -e "s/'$//"); do
    rm -i "$i"
done

This solution fails if one of the filenames contains a single quote ('). If anyone knows how to correct this, please change it.

Tim
  • 2,172
  • I replaced path/to/files with /home/jhvisser/Music/Streamripper_rips however I get the following errors: http://pastebin.com/95TtHkXW – ComputerLocus Oct 08 '13 at 17:34
  • What does echo $concat print after executing the first line? – Tim Oct 08 '13 at 18:27
  • It outputs: concat: – ComputerLocus Oct 08 '13 at 19:52
  • @Fogest Then I assume the find command does not find any .mp3 files that are newer than one day. Are you sure there are some in your specified path? .mp3 is case sensitive (use -iname for case insensitive). Play around with `find path/to/files -name '.mp3' -mtime -1` until you match the files you want. – Tim Oct 08 '13 at 20:19
  • Dammit, stupid mistake on my part. I actually have .aac files that are created. The question is however answered correctly, I just made a mistake. It works now, I just changed the .mp3 to .aac and it outputs an mp3 that plays great! Is there any order for how it combines the audio? I'm guessing alpha order? It doesn't really matter to me, just curious. – ComputerLocus Oct 08 '13 at 20:39
  • Problem: The files are not being deleted. Did I have to change something else since they are .aac files? – ComputerLocus Oct 08 '13 at 20:45
  • And all the aac files are being copied. So now I have multiple copies of each clip. – ComputerLocus Oct 08 '13 at 20:47
  • @Fogest I forgot to quote, does rm -i "$i" work? The files are not in a particular order. I am right now writing another version, which is sortable via sort, but it will probably not work with your old ffmpeg version – Tim Oct 08 '13 at 20:49
  • I do not fully understand your last comment. – Tim Oct 08 '13 at 20:50
  • Nevermind that comment, I think that was something I did. Is there an advantage using the sort version instead of the original one? – ComputerLocus Oct 08 '13 at 22:26
  • Okay just tested. rm -i "$i" is not working. Not being deleted. – ComputerLocus Oct 09 '13 at 01:05