Znalazłem ten wątek podczas próby bezpośredniego kodowania plików MP3 z plików źródłowych FLAC. Odpowiedź Boehja zapewnia przyzwoitą opcję skryptową, ale ja osobiście wolę używać FFmpeg, więc jest to skrypt Bash, który wymyśliłem, aby poradzić sobie z tym zadaniem. Testowane i działa świetnie w macOS Sierra (10.12.2).
Wymagania: Powinieneś mieć ffmpegi lamejuż zainstalować na komputerze Mac. Najłatwiej to zrobić za pomocą Homebrew. Najpierw upewnij się, że masz zainstalowany Homebrew w ten sposób:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Następnie uruchom to polecenie, aby zainstalować ffmpegi lame:
brew install ffmpeg lame
Po zakończeniu możesz uruchomić ten skrypt. Ten skrypt będzie szukał plików FLAC w katalogu, path/to/FLAC/filesale można to zmienić tak, aby .pliki FLAC znajdowały się w tym samym katalogu, w którym uruchamiany jest ten skrypt. Po uruchomieniu utworzy mp3/podkatalog, w którym wszystkie pliki MP3 będą umieszczony.
find -E "path/to/FLAC/files" -type f -iregex ".*\.(FLAC)$" |\
while read full_audio_filepath
do
# Break up the full audio filepath stuff into different directory and filename components.
audio_dirname=$(dirname "${full_audio_filepath}");
audio_basename=$(basename "${full_audio_filepath}");
audio_filename="${audio_basename%.*}";
# audio_extension="${audio_basename##*.}";
# Set the MP3
mp3_dirpath="${audio_dirname}/mp3";
mp3_filepath="${mp3_dirpath}/${audio_filename}.mp3";
# Create the child MP3 directory.
mkdir -p "${mp3_dirpath}";
# Get the track metadata.
mp3_title=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TITLE= | cut -d '=' -f 2- );
mp3_artist=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ARTIST= | cut -d '=' -f 2- );
mp3_album=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ALBUM= | cut -d '=' -f 2- );
mp3_year=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:YEAR= | cut -d '=' -f 2- );
mp3_track=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACK= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_tracktotal=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACKTOTAL= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_genre=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:GENRE= | cut -d '=' -f 2- );
# Where the magic happens.
ffmpeg -y -v quiet -nostdin -i "${full_audio_filepath}" -ar 44100 -sample_fmt s16 -ac 2 -f s16le -acodec pcm_s16le - | \
lame --quiet --add-id3v2 --pad-id3v2 --tt "${mp3_title}" --ta "${mp3_artist}" --tl "${mp3_album}" --tn "${mp3_track}"/"${mp3_tracktotal}" --tg "${mp3_genre}" -r -m s --lowpass 19.7 -V 3 --vbr-new -q 0 -b 96 --scale 0.99 --athaa-sensitivity 1 - "${mp3_filepath}";
done
Kilka notatek o rzeczach, których nauczyłem się „The Hard Way ™”, aby inni mogli czerpać korzyści z tego, co zrobiłem inaczej w tym skrypcie w porównaniu do innych w Internecie.
- Te
grepkomendy dla tagu parsowania (używając FFprobe którym jest zainstalowany z FFmpeg) są wrażliwe na wielkość liter przy użyciu -iopcji, aby go grep -i.
- Następujące
cutpolecenie jest teraz ograniczone do dzielenia danych wyjściowych tylko na podstawie pierwszego =w nazwie znacznika z -f 2-opcją, która tworzy polecenie cut -d '=' -f 2-. Na przykład, Pavement ma utwór zatytułowany „5-4 = Unity”, a gdyby tylko drugi fragment został wybrany przez cięcie, tytuł zostałby skrócony do „5-4”.
- Na torze-torowych i całkowitych numerami dodałem dodatkową rurę
sed, która pozbywa zer wiodących: sed 's/^0*//'.
- W podobnych skryptach w Internecie wyjście FFmpeg jest czymś podobnym
-f wavi faktycznie kompresuje wyjście FFmpeg, co nie ma sensu w konfiguracji potoku, w której LAME zamierza go ponownie zakodować. Zamiast tego ustawia się tutaj wyjście, -f s16le -acodec pcm_s16lektóre jest zasadniczo wyjściem RAW; idealny do przesyłania dźwięku do innego procesu takiego jak ten.
- Aby poradzić sobie z danymi wyjściowymi RAW po stronie LAME rury, musiałem dodać
-ropcję.
- Należy również pamiętać
--tt, --ta, --tl, --tni --tgID3v2 opcji znacznik do LAME. Gdy dźwięk jest przesyłany strumieniowo / przesyłany strumieniowo z jednego procesu do LAME, metadane z pliku źródłowego są tracone. Jednym z sugerowanych opcji jest uzyskanie FFmpeg zapisać metadane w pliku tekstowym poprzez ustawienie opcji z -f ffmetadata "[metadata filename here]"czym działa FFmpeg znowu z czymś takim: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1. To działa, ale zwróć uwagę na wymaganie dotyczące pliku docelowego. Wydaje się, że FFmpeg importuje metadane tylko wtedy, gdy może skopiować plik, co wydaje się bardzo marnotrawstwem. Korzystanie FFprobe uzyskać wartości, a następnie ustawiając je w LAME z --tt, --ta, --tl, --tni --tgopcje działa lepiej; wszystkie metadane są zapisane w miejscu, dlatego należy wygenerować duplikat pliku.