Как мне искать в каталоге mp3-файлов песни определенной длительности. Пример:
findmp3 -min=03:00 -max=03:15 /music/mp3/ebm/
Возвращает все mp3-файлы в emb/
каталоге, длительность песен которых составляет от 3:00 до 3:15 минут.
Я использую 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
Подробнее о формате вывода см. здесь.
Если вы хотите иметь возможность вводить время в формате ММ:СС, все становится немного сложнее:
#!/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
Сомневаюсь, что есть существующий findmp3
инструмент. Следуя философии unix, его можно построить из find
поиска .mp3
файлов, другого инструмента для отчета о длине каждого find
найденного файла и некоторого клея для обработки оболочки/текста.
SoXобщедоступная утилита для работы со звуковыми файлами (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 shopt -s globstar
сначала запустите. Обратите внимание, что в bash (но не в ksh или zsh) **/
рекурсия выполняется через символические ссылки на каталоги.
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-репозитория.