Como eu pesquisaria em um diretório de arquivos mp3 músicas com uma determinada duração? Ex:
findmp3 -min=03:00 -max=03:15 /music/mp3/ebm/
Retornaria todos os arquivos mp3 no emb/
diretório com duração de música entre 3:00 e 3:15 minutos.
Eu uso Linux Mint, Ubuntu e também CentOS.
Responder1
Primeiro install mp3info
, ele deve estar nos repositórios da sua distribuição (você não disse, então presumo que você esteja usando algum tipo de Linux). Se você possui uma distribuição baseada em Debian, você pode fazer isso com
sudo apt-get install mp3info
Depois de mp3info
instalado, você pode pesquisar no diretório music
por músicas de uma determinada duração com 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
O comando acima irá procurar music/
arquivos mp3 e imprimir seu nome e duração se essa duração for maior ou igual a 180 segundos (3:00) e menor ou igual a 195 segundos (3:15). Veja man mp3info
para mais detalhes sobre seu formato de saída.
Se você quiser inserir horários no formato MM:SS, fica um pouco mais complexo:
#!/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
Salve o script acima como findmp3
e execute-o assim:
findmp3 3:00 3:15 music/
Responder2
Duvido que exista uma findmp3
ferramenta. Seguindo a filosofia unix, ele pode ser construído a partir find
de arquivos encontrados .mp3
, outra ferramenta para relatar o comprimento de cada arquivo find
encontrado e alguma cola de processamento de shell/texto.
SoXé um utilitário comumente disponível para trabalhar com arquivos de som (sox é para o som o que sed ou awk são para arquivos de texto). O comandosoxi
exibe informações sobre um arquivo de som. Em particular, soxi -D
imprime a duração em segundos.
Para cada .mp3
arquivo, o trecho abaixo chama soxi
e analisa sua saída. Se a duração estiver dentro do intervalo desejado, a sh
chamada retorna um status de sucesso, então a -print
ação é executada para imprimir o nome do arquivo.
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
No bash, ksh93 ou zsh, você pode usar globbing recursivo em vez de find
. Em ksh, execute set -o globstar
primeiro. No bash, execute shopt -s globstar
primeiro. Observe que no bash (mas não no ksh ou zsh), **/
recorre por meio de links simbólicos para diretórios.
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
Responder3
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
linha única:
find . -name \*.mp3 -exec mp3info -p '%S %f\n' {} +|awk '$1>=180&&$1<=195'|cut -d' ' -f2-
Ou no OS X:
mdfind 'kMDItemDurationSeconds>=180&&kMDItemDurationSeconds<=195&&kMDItemContentType=public.mp3' -onlyin .
Responder4
ffmpeg -i yourmp3.mp3 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g' |awk {'print $1'}
Com o comando acima, você pode obter sua duração. Assim, você pode criar um script para especificar um domínio para duração. Além disso, você pode usar:
find yourPath -iname "*mp3" -exec ffmpeg -i {} 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g' |awk {'print $1'}
Substitua yourPath pela raiz do seu repositório mp3.