Ich habe diesen Thread gefunden, als ich versucht habe, MP3s direkt aus FLAC-Quelldateien zu codieren. Boehjs Antwort bietet eine anständige Skriptoption , aber ich persönlich bevorzuge FFmpeg. Dies ist also das Bash-Skript, das ich für diese Aufgabe entwickelt habe. Getestet und funktioniert hervorragend in macOS Sierra (10.12.2).
Sporteln: Sie sollten ffmpeg
und lame
auf Ihrem Mac installiert ist . Am einfachsten geht das über Homebrew. Stellen Sie zunächst sicher, dass Homebrew folgendermaßen installiert ist:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Führen Sie dann diesen Befehl aus, um zu installieren ffmpeg
und lame
:
brew install ffmpeg lame
Sobald dies erledigt ist, können Sie dieses Skript ausführen. Dieses Skript sucht nach FLAC-Dateien im Verzeichnis. Dies path/to/FLAC/files
kann jedoch einfach geändert werden, .
wenn sich die FLAC-Dateien in dem Verzeichnis befinden, in dem Sie dieses Skript ausführen. Bei der Ausführung wird ein mp3/
Unterverzeichnis erstellt, in dem sich alle MP3-Dateien befinden platziert.
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
Einige Notizen zu Dingen, die ich in „The Hard Way ™“ gelernt habe, damit andere von dem profitieren können, was ich in diesem Skript anders gemacht habe als andere im Internet.
- Bei den
grep
Befehlen zum Parsen von Tags (mit FFprobe, das mit FFmpeg installiert wurde) wird die Groß- und Kleinschreibung nicht berücksichtigt , wenn die -i
Option aktiviert wird grep -i
.
- Der folgende
cut
Befehl ist jetzt darauf beschränkt, die Ausgabe nur basierend auf dem ersten =
in einem Tag-Namen mit der -f 2-
Option zu teilen, die den Befehl ausführt cut -d '=' -f 2-
. Zum Beispiel hat Pavement einen Song mit dem Titel "5-4 = Unity" und wenn nur der zweite Chunk per Cut ausgewählt worden wäre, wäre dieser Titel auf "5-4" gekürzt worden.
- Für spur und Gesamtspurnummern hinzugefügt I ein zusätzliches Rohr zu
sed
denen der führenden Nullen entledigt: sed 's/^0*//'
.
- In ähnlichen Skripten im Internet ist die FFmpeg-Ausgabe so etwas wie
-f wav
und das würde die FFmpeg-Ausgabe tatsächlich komprimieren, was in einer Pipe-Konfiguration, in der LAME sie neu codieren wird, keinen Sinn macht. Stattdessen wird hier die Ausgabe festgelegt, bei -f s16le -acodec pcm_s16le
der es sich im Grunde um eine RAW-Ausgabe handelt. Perfekt, um Audio an einen anderen Prozess wie diesen weiterzuleiten.
- Um mit der RAW-Ausgabe auf der LAME-Seite der Pipe fertig zu werden, musste ich die
-r
Option hinzufügen .
- Beachten Sie auch die
--tt
, --ta
, --tl
, --tn
und --tg
ID3v2 - Tag - Optionen für LAME. Wenn Audio von einem Prozess in LAME gestreamt / weitergeleitet wird, gehen die Metadaten aus der Quelldatei verloren. Eine vorgeschlagene Option ist FFmpeg bekommt die Metadaten in eine Textdatei zu speichern , indem Sie die Option mit der Einstellung -f ffmetadata "[metadata filename here]"
und dann FFmpeg wieder mit dem etwas wie folgt ausgeführt werden : -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1
. Das funktioniert, aber beachten Sie die Anforderung für eine Zieldatei. FFmpeg importiert anscheinend nur Metadaten, wenn es die Datei kopieren kann. Dies scheint ein sehr verschwenderischer Prozess zu sein. Mit FFprobe Werte zu erhalten und sie dann in LAME Einstellung mit --tt
, --ta
, --tl
, --tn
und --tg
Optionen besser funktionieren; Alle Metadaten sind an Ort und Stelle geschrieben, so dass doppelte Dateien generiert werden müssen.