Мне нужно преобразовать около 1,5 ТБ или аудиофайлы в формате flac или wav. Их нужно преобразовать в mp3-файлы, сохранив важные метаданные, обложку и т. д., а битрейт должен быть 320k.
Только это легко:
ffmpeg -i "$flacFile" -ab 320k -map_metadata 0 -id3v2_version 3 -vsync 2 "$mp3File" < /dev/null
Но проблема в том, чтобы сделать это быстрее. Команда сверху использует только 12,5% ЦП. Я бы предпочел использовать 80%. Итак, я поиграл с флагом потоков, но это не делает его быстрее или медленнее:
ffmpeg -i "$flacFile" -ab 320k -map_metadata 0 -id3v2_version 3 -vsync 2 -threads 4 "$mp3File" < /dev/null
Но он использует мой процессор только на 13%. Я думаю, что он использует только один поток. Кстати, у моего процессора 8 физических ядер (+ гиперпоточность).
Итак, моя идея сейчас состоит в том, чтобы каким-то образом одновременно запускать несколько экземпляров ffmpeg, но я понятия не имею, как это сделать правильно.
Это мой текущий скрипт, который берет все файлы flac/wav из одного каталога (рекурсивно) и конвертирует их в файлы mp3 в новом каталоге с точно такой же структурой:
#!/bin/bash
SOURCE_DIR="/home/fedora/audiodata_flac"
TARGET_DIR="/home/fedora/audiodata_mp3"
echo "FLAC/WAV files will be read from '$SOURCE_DIR' and MP3 files will be written to '$TARGET_DIR'!"
read -p "Are you sure? (y/N)" -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]] ; then # Continue if user enters "y"
# Find all flac/wav files in the given SOURCE_DIR and iterate over them:
find "${SOURCE_DIR}" -type f \( -iname "*.flac" -or -iname "*.wav" \) -print0 | while IFS= read -r -d '' flacFile; do
if [[ "$(basename "${flacFile}")" != ._* ]] ; then # Skip files starting with "._"
tmpVar="${flacFile%.*}.mp3"
mp3File="${tmpVar/$SOURCE_DIR/$TARGET_DIR}"
mp3FilePath=$(dirname "${mp3File}")
mkdir -p "${mp3FilePath}"
if [ ! -f "$mp3File" ]; then # If the mp3 file doesn't exist already
echo "Input: $flacFile"
echo "Output: $mp3File"
ffmpeg -i "$flacFile" -ab 320k -map_metadata 0 -id3v2_version 3 -vsync 2 "$mp3File" < /dev/null
fi
fi
done
fi
Я имею в виду, что я мог бы добавить &
к команде ffmpeg, но это привело бы к одновременному запуску тысяч экземпляров ffmpeg, что слишком много.
[bash] xargs
и прочитайте несколько ответов.xargs
уже должен быть в вашей системе, тогда как вам, скорее всего, придется установитьgnuparallel
. Удачи. - person shellter   schedule 12.07.2019