Search mp3 collection for songs with a certain song length

findmp3

How would I search a directory of mp3 files for songs between a certain length. Ex:

findmp3 -min=03:00 -max=03:15 /music/mp3/ebm/

Would return all mp3 files in the emb/ directory having a song length between 3:00 and 3:15 minutes in length.

I use Linux Mint, Ubuntu, as well as CentOS.

Best Answer

First install mp3info, it should be in the repositories of your distribution (you have not said, so I assume you are using Linux of some sort). If you have a debian-based distribution, you can do so with

sudo apt-get install mp3info

Once mp3info is installed, you can search the directory music for songs of a certain length with this command:

find music/ -name "*mp3" | 
  while IFS= read -r f; do 
   length=$(mp3info -p "%S" "$f"); 
   if [[ "$length" -ge "180" && "$length" -le "195" ]]; then 
     echo "$f"; 
   fi;  
done

The command above will search music/ for mp3 files, and print their name and length if that length is grater or equal to 180 seconds (3:00) and less than or equal to 195 seconds (3:15). See man mp3info for more details on its output format.

If you want to be able to enter times in MM:SS format, it gets a bit more complex:

#!/usr/bin/env bash

## Convert MM:SS to seconds.
## The date is random, you can use your birthday if you want.
## The important part is not specifying a time so that 00:00:00
## is returned.
d=$(date -d "1/1/2013" +%s);

## Now add the number of minutes and seconds
## you give as the first argument
min=$(date -d "1/1/2013 00:$1" +%s);
## The same for the second arument
max=$(date -d "1/1/2013 00:$2" +%s);

## Search the target directory for files
## of the correct length.
find "$3" -name "*mp3" | 
  while IFS= read -r file; do 
   length=$(mp3info -p "%m:%s" "$file"); 
   ## Convert the actual length of the song (mm:ss format)
   ## to seconds so it can be compared.
   lengthsec=$(date -d "1/1/2013 00:$length" +%s);

   ## Compare the length to the $min and $max
   if [[ ($lengthsec -ge $min ) && ($lengthsec -le $max ) ]]; then 
       echo "$file"; 
   fi; 
done

Save the script above as findmp3 and run it like this:

findmp3 3:00 3:15 music/
Related Question