Хотите преобразовать мои файлы m4a в файлы mp3 с помощью скрипта. Это бы сэкономило время... У меня более 100 ГБ музыкальных файлов.
ОС: OSX10.14/Терминал против скрипта Bash
Я могу запустить ffmpeg -v 5 -y -i musicFile.m4a -acodec libmp3lame -ac 2 -b:a 320k musicFile.mp3
из терминала. Он преобразует файл, и я могу видеть и воспроизводить файл из itunes.
Когда я запускаю то же самое из сценария bash, он не конвертируется.
ffmpeg -v 5 -y -i $ENTRY_FILE -acodec libmp3lame -ac 2 -b:a 320k $MP3NAME
Мой iPod Nano только что умер, и я купил новый mp3-плеер. Теперь мне нужно преобразовать файлы iTunes из формата AAC в MP3. ffmpeg — признанный конвертер видео и музыкальных файлов.
Когда я запускаю его из сценария bash, я пробовал несколько вещей.
Я добавил ./ перед файлом, что не удалось, потому что он был установлен в /usr/local/bin, а не в тот же каталог.
Я также попробовал sh ffmpeg... и это дало мне возможность выполнить двоичный файл.
#!/usr/bin/env bash
# convert m4a file to mp3
set -e
file_convert() {
ENTRY_FILE=$(printf %q "${entry}")
FILE_NAME=$(printf %q "$(basename "${entry}")")
DIR=$(printf %q "$(dirname "${entry}")")
NAME = "${FILE_NAME%.*}"
EXT = "${FILE_NAME##*.}"
MP3NAME = "${DIR}/${NAME}.mp3"
printf "%*s%s\n" $((indent+2)) '' "$ENTRY_FILE"
printf "%*s\tNew File :\t%s\n" $((indent+2)) '' "$MP3NAME"
if [ $EXT == "m4a" ]
then
printf "%*s\tConverting: \t%s\n" $((index+2)) '' "$ENTRY_FILE"
ffmpeg -v 5 -y -i $ENTRY_FILE -acodec libmp3lame -ac 2 -b:a 320k $MP3NAME
fi
}
walk() {
local indent = "${2:-0}"
printf "\n%*s%s\n\n" "$indent" '' "$1"
# If the entry is a file convert it
for entry in "$1"/*; do [[ -f "$entry" ]] && file_convert; done
# If the entry is a directory recurse
for entry in "$1"/*; do [[ -d "$entry" ]] && walk "$entry" $((indent+2)); done
}
# If the path is empty use the current, otherwise convert relative to absolute; Exec walk()
[[ -z "${1}" ]] && ABS_PATH = "${PWD}" || pushd "${1}" && ABS_PATH = "${PWD}"
walk "${ABS_PATH}"
popd
echo
Я ожидаю, что >./aacToMp3.sh ./music
пройдет по музыкальному каталогу и преобразует каждый файл m4a в .mp3.
Он просматривает файловую систему и распечатывает правильные файлы с экранированными пробелами. Когда он попадает в строку ffmpeg, он останавливается. Я поместил set -e в начало файла, чтобы заставить его завершиться ошибкой в случае сбоя команды. Без set -e он с радостью обходит все музыкальные файлы и выводит их на стандартный вывод.
поместите echo $ENTRY_FILE
и echo $MP3NAME
перед вызовом ffmpeg
и убедитесь, что они получают правильное значение, назначенное им, прежде чем ffmpeg доберется до него
Цитатные переменные.
Вы установили ffmpeg
с помощью доморощенный? Если да, то он будет в /usr/local/bin/ffmpeg
.
Если у вас есть 100 ГБ, вам следует рассмотреть возможность использования Параллельный GNU, особенно на Mac, который, вероятно, будет иметь много ядер ЦП и быстрый флэш-диск.
sh ffmpeg
ожидает, что ffpmeg
будет сценарием оболочки, а не двоичным исполняемым файлом. Почему вы думаете, что это сработает?
Какую ошибку он получает, когда попадает в строку ffmpeg
?
Вместо этого ваши два цикла for entry
должны быть одним циклом for
, содержащим if/elif
тесты. Это предотвратит двойное сканирование содержимого каждого каталога. Не поддавайтесь искушению связать &&
и ||
— вместо этого используйте блоки if
. Никогда не используйте set -e
. Вы можете использовать set -x
, чтобы отслеживать выполнение и показывать, получают ли переменные ожидаемые значения.
@MarkSetchell, к вашему сведению, GNU Parallel здесь не требуется, можно добиться того же с помощью xargs -P
.
@ghoti Я не знаю, как вы удаляете и заменяете расширения на xargs
, а с parallel
это так просто. Пожалуйста, напишите xargs
ответ, если вам это нравится - я всегда рад учиться! На самом деле я не говорил, что parallel
был требуется, я просто предположил, что это, вероятно, будет быстрее, проще и гораздо менее подвержено ошибкам, чем страница bash
.
Если у вас есть много файлов для обработки и приличный многоядерный процессор и быстрый диск, я бы рекомендовал Параллельный GNU, который вы можете установить с доморощенный:
brew install parallel
Затем сделайте копию нескольких файлов в тестовом каталоге и попробуйте:
parallel --dry-run ffmpeg -v 5 -y -i {} -acodec libmp3lame -ac 2 -b:a 320k {.}.mp3 ::: *.m4a
Если это выглядит хорошо, замените --dry-run
на --progress
.
Если это выглядит хорошо, вы можете (сначала сделать резервную копию) и сделать все:
find path/to/music -name "*.m4a" -print0 | parallel -0 --progress ffmpeg -v 5 -y -i {} -acodec libmp3lame -ac 2 -b:a 320k {.}.mp3
Спасибо за ваш вклад.
Через некоторое время я закончил тем, что записал все строки ffmpeg в файл сценария. Рад, что сделал. Я смог быстро отсканировать файл и увидеть некоторые ошибки и исправить их. Это то, что я придумал. В основном я пишу прямой текст на стандартный вывод и направляю его в файл. Который я преобразовал в сценарий оболочки для преобразования каждого файла. Один за раз. Запустил сгенерированный скрипт на ночь.
file_convert() {
ENTRY_FILE=$(printf %q "${entry}")
FILE_NAME=$(printf %q "$(basename "${entry}")")
DIR=$(printf %q "$(dirname "${entry}")")
NAME = "${FILE_NAME%.*}"
EXT = "${FILE_NAME##*.}"
MP3NAME = "${DIR}/${NAME}.mp3"
if [ $EXT == "m4a" ]
then
printf 'echo "Converting %s ..."\n' "$FILE_NAME"
printf 'ffmpeg -v 5 -y -i %s -acodec libmp3lame -ac 2 -b:a 320k %s\n\n' "$ENTRY_FILE" "$MP3NAME"
fi
}
Выход выглядел так.
#!/usr/bin/env bash
echo "Converting 03\ It\'s\ Not\ My\ Time.m4a ..."
ffmpeg -v 5 -y -i /Users/arthuranderson/Documents/work/projects/mp3Convert/music/3\ Doors\ Down/3\ Doors\ Down\ \(Bonus\ Track\ Version\)/03\ It\'s\ Not\ My\ Time.m4a -acodec libmp3lame -ac 2 -b:a 320k /Users/arthuranderson/Documents/work/projects/mp3Convert/music/3\ Doors\ Down/3\ Doors\ Down\ \(Bonus\ Track\ Version\)/03\ It\'s\ Not\ My\ Time.mp3
echo "Converting 01\ Down.m4a ..."
ffmpeg -v 5 -y -i /Users/arthuranderson/Documents/work/projects/mp3Convert/music/311/Greatest\ Hits\ \'93-\'03/01\ Down.m4a -acodec libmp3lame -ac 2 -b:a 320k /Users/arthuranderson/Documents/work/projects/mp3Convert/music/311/Greatest\ Hits\ \'93-\'03/01\ Down.mp3
Марк Я попробую параллельно, когда в следующий раз куплю еще музыку.
Всем спасибо!
Разделите вашу программу, пока проблема не останется.