特定の曲の長さの曲のmp3コレクションを検索

特定の曲の長さの曲のmp3コレクションを検索

mp3 ファイルのディレクトリで特定の長さの曲を検索するにはどうすればよいでしょうか。例:

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

emb/ディレクトリ内の曲の長さが 3:00 から 3:15 分までのすべての mp3 ファイルを返します。

私は Linux Mint、Ubuntu、CentOS を使用しています。

答え1

まずインストールしてくださいmp3info。これはあなたのディストリビューションのリポジトリにあるはずです(あなたが何も言わないので、何らかのLinuxを使っていると思います)。Debianベースのディストリビューションをお持ちの場合は、

sudo apt-get install mp3info

インストールしたら、次のコマンドを使用してmp3info、ディレクトリ内musicで特定の長さの曲を検索できます。

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

上記のコマンドはmusic/、mp3 ファイルを検索し、長さが 180 秒 (3:00) 以上 195 秒 (3:15) 以下の場合に、その名前と長さを出力します。man mp3info出力形式の詳細については、を参照してください。

MM:SS 形式で時間を入力できるようにする場合は、少し複雑になります。

#!/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

上記のスクリプトをfindmp3次のように保存し、実行します。

findmp3 3:00 3:15 music/

答え2

既存のツールがあるとは思えません。UNIX の哲学に従えば、ファイルを検索するためのツール、見つかった各ファイルの長さを報告する別のツール、およびシェル/テキスト処理の接着剤findmp3から構築できます。find.mp3find

ソックスは、サウンドファイルを扱うための一般的なユーティリティです(soxはサウンドファイルに対するものであり、sedやawkはテキストファイルに対するものです)。コマンドsoxiサウンド ファイルに関する情報を表示します。特に、soxi -D継続時間を秒単位で出力します。

.mp3ファイルについて、以下のスニペットが呼び出してsoxiその出力を解析します。期間が希望の範囲内であれば、sh呼び出しは成功ステータスを返すので、-printアクションが実行されてファイル名が印刷されます。

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

bash、ksh93、または zsh では、 の代わりに再帰グロブを使用できますfind。ksh では、set -o globstar最初に を実行します。bash では、最初に を実行します。bash では (ksh または zsh ではそうではありません)、ディレクトリへのシンボリック リンクを再帰的に実行するshopt -s globstarことに注意してください。**/

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

答え3

使用方法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一発ギャグ:

find . -name \*.mp3 -exec mp3info -p '%S %f\n' {} +|awk '$1>=180&&$1<=195'|cut -d' ' -f2-

または OS X の場合:

mdfind 'kMDItemDurationSeconds>=180&&kMDItemDurationSeconds<=195&&kMDItemContentType=public.mp3' -onlyin .

答え4

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

上記のコマンドを使用すると、期間を取得できます。そのため、期間のドメインを指定するスクリプトを作成できます。また、以下も使用できます。

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

yourPath を mp3 リポジトリのルートに置き換えます。

関連情報