Pesquisar coleção de músicas em MP3 com um determinado comprimento de música

5

Como eu procuraria um diretório de arquivos mp3 para músicas entre um determinado tamanho. Ex:

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

Devolveria todos os arquivos mp3 no diretório emb/ , com um comprimento de música entre 3:00 e 3:15 minutos de duração.

Eu uso Linux Mint, Ubuntu e CentOS.

    
por a coder 13.10.2013 / 21:51

4 respostas

3

Primeiro instale mp3info , ele deve estar nos repositórios de sua distribuição (você não disse, então eu suponho que você esteja usando algum tipo de Linux). Se você tem uma distribuição baseada no Debian, você pode fazê-lo com

sudo apt-get install mp3info

Quando o mp3info estiver instalado, você poderá pesquisar o diretório music para músicas de um determinado tamanho 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/ para arquivos mp3, e imprimir seu nome e comprimento se esse comprimento 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 o 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/
    
por 14.10.2013 / 00:11
3

Eu duvido que exista uma ferramenta findmp3 existente. Seguindo a filosofia unix, ele pode ser construído a partir de find para encontrar .mp3 arquivos, outra ferramenta para relatar o tamanho de cada arquivo que find encontra e alguma cola de processamento de shell / texto.

SoX é um utilitário comumente disponível para trabalhar com arquivos de som (sox é soar o que sed ou awk são para texto arquivos). O comando soxi exibe informações sobre um arquivo de som. Em particular, soxi -D imprime a duração em segundos.

Para cada arquivo .mp3 , o snippet abaixo chama soxi e analisa sua saída. Se a duração estiver dentro do intervalo desejado, a chamada sh retornará um status de sucesso, portanto, a ação -print será 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 globalização recursiva em vez de find . Em ksh, execute set -o globstar primeiro. No bash, execute shopt -s globstar primeiro. Note que no bash (mas não no ksh ou zsh), **/ recorre através 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
    
por 13.10.2013 / 23:52
1

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 oneliner:

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 .

    
por 17.06.2014 / 20:49
0
ffmpeg -i  yourmp3.mp3  2>&1 | grep Duration | sed 's/Duration: \(.*\), start//g'  |awk {'print $1'}

Com o comando acima, você pode obter a sua duração, assim você pode script para especificar um domínio para a duração. Além disso, você pode usar:

find yourPath -iname "*mp3" -exec ffmpeg -i  {}   2>&1 | grep Duration | sed 's/Duration: \(.*\), start//g'  |awk {'print $1'}

Substitua o yourPath pela raiz do seu repositório de mp3.

    
por 13.10.2013 / 23:31

Tags