¿Cómo puedo buscar en un directorio de archivos mp3 canciones de cierta duración? Ex:
findmp3 -min=03:00 -max=03:15 /music/mp3/ebm/
Devolvería todos los archivos mp3 en el emb/
directorio que tengan una duración de canción de entre 3:00 y 3:15 minutos.
Utilizo Linux Mint, Ubuntu y CentOS.
Respuesta1
Primero instálalo mp3info
, debería estar en los repositorios de tu distribución (no lo has dicho, así que supongo que estás usando algún tipo de Linux). Si tienes una distribución basada en Debian, puedes hacerlo con
sudo apt-get install mp3info
Una vez mp3info
instalado, puedes buscar en el directorio music
canciones de cierta duración con este comando:
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
El comando anterior buscará music/
archivos mp3 e imprimirá su nombre y longitud si esa duración es mayor o igual a 180 segundos (3:00) y menor o igual a 195 segundos (3:15). Consulte man mp3info
para obtener más detalles sobre su formato de salida.
Si desea poder ingresar horas en formato MM:SS, se vuelve un poco más complejo:
#!/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
Guarde el script anterior como findmp3
y ejecútelo así:
findmp3 3:00 3:15 music/
Respuesta2
Dudo que exista una findmp3
herramienta. Siguiendo la filosofía de Unix, se puede construir a partir find
de archivos para buscar .mp3
, otra herramienta para informar la longitud de cada archivo que find
se encuentra y algo de pegamento para procesamiento de texto/shell.
SoXes una utilidad comúnmente disponible para trabajar con archivos de sonido (sox es para sonar lo que sed o awk son para archivos de texto). El comandosoxi
muestra información sobre un archivo de sonido. En particular, soxi -D
imprime la duración en segundos.
Para cada .mp3
archivo, el siguiente fragmento llama soxi
y analiza su salida. Si la duración está dentro del rango deseado, la sh
llamada devuelve un estado exitoso, por lo que -print
se ejecuta la acción para imprimir el nombre del archivo.
find /music/mp3/ebm -type f -name .mp3 -exec sh -c '
d=$(soxi -D "$0")
d=${d%.*} # truncate to an integer number of seconds
[ $((d >= 3*60 && d < 3*60+15)) -eq 1 ]
' {} \; -print
En bash, ksh93 o zsh, puedes usar globbing recursivo en lugar de find
. En ksh, ejecute set -o globstar
primero. En bash, ejecuta shopt -s globstar
primero. Tenga en cuenta que en bash (pero no en ksh o zsh), **/
se recurre a través de enlaces simbólicos a directorios.
for f in /music/mp3/ebm/**/*.mp3; do
d=$(soxi -D "$0")
d=${d%.*} # truncate to an integer number of seconds (needed in bash only, ksh93 and zsh understand floating point numbers)
if ((d >= 3*60 && d < 3*60+15)); then
echo "$f"
fi
done
Respuesta3
Usando ffmpeg
:
find . -name \*.mp3|while IFS= read -r l;do ffprobe -v 0 -i "$l" -show_streams|awk -F= '$1=="duration"&&$2>=180&&$2<=195'|read&&echo "$l";done
mp3info
un trazador de líneas:
find . -name \*.mp3 -exec mp3info -p '%S %f\n' {} +|awk '$1>=180&&$1<=195'|cut -d' ' -f2-
O en OS X:
mdfind 'kMDItemDurationSeconds>=180&&kMDItemDurationSeconds<=195&&kMDItemContentType=public.mp3' -onlyin .
Respuesta4
ffmpeg -i yourmp3.mp3 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g' |awk {'print $1'}
Con el comando anterior, puede obtener su duración, por lo que puede crear una secuencia de comandos para especificar un dominio para la duración. También puedes usar:
find yourPath -iname "*mp3" -exec ffmpeg -i {} 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g' |awk {'print $1'}
Reemplace yourPath con la raíz de su repositorio de mp3.