Pesquise na coleção de mp3 músicas com uma determinada duração

Pesquise na coleção de mp3 músicas com uma determinada duração

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 mp3infoinstalado, você pode pesquisar no diretório musicpor 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 mp3infopara 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 findmp3e execute-o assim:

findmp3 3:00 3:15 music/

Responder2

Duvido que exista uma findmp3ferramenta. Seguindo a filosofia unix, ele pode ser construído a partir findde arquivos encontrados .mp3, outra ferramenta para relatar o comprimento de cada arquivo findencontrado 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 comandosoxiexibe informações sobre um arquivo de som. Em particular, soxi -Dimprime a duração em segundos.

Para cada .mp3arquivo, o trecho abaixo chama soxie analisa sua saída. Se a duração estiver dentro do intervalo desejado, a shchamada retorna um status de sucesso, então a -printaçã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 globstarprimeiro. No bash, execute shopt -s globstarprimeiro. 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

mp3infolinha ú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.

informação relacionada