Wie gehe ich mit LAME & FLAC von .flac zu .mp3, wenn ich nur das Terminal benutze?

31

Ich verwende seit langer Zeit eine relativ klobige Technik, die Audacity mit einem LAME-Plugin einbezieht. Ich denke, das ist in Ordnung, aber der Reiz des Terminal-Ansatzes besteht darin, dass ich mit meinen [options]Binärdateien etwas feiner arbeiten und vielleicht aktuellere verwenden kann.

Außerdem altert mein MacBook jetzt ein wenig und wenn ich eine unnötige Benutzeroberfläche loswerden kann, umso besser.

Danke im Voraus.

boehj
quelle
1
du bekommst tatsächlich Punkte dafür;)
Mortimer
Haha ... Ich habe die Frage beantwortet, aber es heißt, ich kann meine Antwort seit zwei Tagen nicht bestätigen. Es tut uns leid. Ich finde immer noch heraus, wie die Dinge hier funktionieren. Tolle Seite. : D
boehj

Antworten:

41

Konvertieren einer einzelnen Datei ohne Beibehaltung von Tags

brew install lame
flac --decode --stdout test.flac | lame --preset extreme - test.mp3
  • --decode --stdout = -dc
  • lame - $outfile = Eingabe von STDIN
  • --preset extreme= ~ 245 kbit / s VBR

Ein Shell-Skript, das einige ID3-Tags beibehält

#!/bin/bash

for f in "$@"; do
    [[ "$f" != *.flac ]] && continue
    album="$(metaflac --show-tag=album "$f" | sed 's/[^=]*=//')"
    artist="$(metaflac --show-tag=artist "$f" | sed 's/[^=]*=//')"
    date="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    title="$(metaflac --show-tag=title "$f" | sed 's/[^=]*=//')"
    year="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    genre="$(metaflac --show-tag=genre "$f" | sed 's/[^=]*=//')"
    tracknumber="$(metaflac --show-tag=tracknumber "$f" | sed 's/[^=]*=//')"

    flac --decode --stdout "$f" | lame --preset extreme --add-id3v2 --tt "$title" --ta "$artist" --tl "$album" --ty "$year" --tn "$tracknumber" --tg "$genre" - "${f%.flac}.mp3"
done

Um das Skript zu benutzen, speichern Sie es einfach irgendwo ~/bin/flac2mp3und machen es mit ausführbar chmod +x ~/bin/flac2mp3.

Dies würde alle flac-Dateien in Ihrem Musikordner konvertieren:

find ~/Music/ -name '*.flac' -exec ~/bin/flac2mp3 {} \;

Oder etwas schneller, da flac2mp3 nur einmal aufgerufen wird:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3
boehj
quelle
2
Sie sollten die Antwort hier posten und nicht auf den Text in der Frage verweisen. IMHO, du solltest sowohl Frage als auch Antwort bearbeiten und hier die Schlussfolgerung ziehen.
Lpacheco
OK mach ich. Es tut uns leid.
Boehj
2
${file%.flac}.mp3ist großartig! Früher habe ich verwendet ${x:: ${#x}-3}m4a, um den Dateinamen des Songs von .wav in .m4a zu ändern. Es ist großartig, einen Weg zu sehen, der viel einfacher aussieht.
Jason Salaz
1
Es sieht so aus, als ob es einen Fehler in Option 3 gibt. Möglicherweise aufgrund einer lahmen Version, aber der aktuelle Code sagt nicht, dass er den Eingabestream als Eingabedatei verwenden soll, und auch die Ausgabedatei wird nicht angegeben, da der Stream verwendet wird notwendig. Für mich ist der endgültige Code: !/bin/sh file="$1" outfile=${file%.flac}.mp3 eval $(metaflac --export-tags-to - "$file" | sed "s/=\(.*\)/='\1'/") flac -cd "$file" | lame --preset standard \ --add-id3v2 --tt "$TITLE" --ta "$ARTIST" --tl "$ALBUM" \ --ty "$DATE" --tn "$TRACKNUMBER" --tg "$GENRE" \ - "$outfile"
Mehal
Es ist auch schön, ein Skript zu erstellen, das diese
Dinge
10

ffmpeg würde standardmäßig Tags (aber keine Coverbilder) beibehalten.

for f in *.flac; do ffmpeg -i "$f" -aq 1 "${f%flac}mp3"; done

-aq 1entspricht -V 1in lahm. -acodec libfaacwürde die Dateien in AAC konvertieren:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done
Lri
quelle
Ich habe das gerade gemacht und es hieß: `` `Metadaten: Kommentar: Cover (Front) Encoder: Lavc57.107.100 png` `` macOS finder zeigt das Cover. ffmpeg 3.4.2 von brew.
Habbie
Ich stellte dann fest, dass mein ffmpeg sehr alt war. Ich habe es mit dem gleichen Ergebnis auf 4.1.3 aktualisiert - MP3-Dateien der gleichen Größe mit funktionierendem Cover-Design.
Habbie
4

Ich habe genommen, was ihr habt, habe es dann aber noch schneller gemacht, indem ich xargsdie Jobs parallelisiert habe.

find <directory> -name '*.flac' -print0 | xargs -0 -P8 -n1  /usr/local/bin/flac2mp3

Dann ist dies das Skript von oben / usr / local / bin / flac2mp3

#!/usr/bin/env bash

for f in "$@"; do
  [[ "$f" != *.flac ]] && continue
  album="$(metaflac --show-tag=album "$f" | sed 's/[^=]*=//')"
  artist="$(metaflac --show-tag=artist "$f" | sed 's/[^=]*=//')"
  date="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
  title="$(metaflac --show-tag=title "$f" | sed 's/[^=]*=//')"
  year="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
  genre="$(metaflac --show-tag=genre "$f" | sed 's/[^=]*=//')"
  tracknumber="$(metaflac --show-tag=tracknumber "$f" | sed 's/[^=]*=//')"

  flac --decode --stdout "$f" \ 
         | lame --preset extreme \
                --add-id3v2 \
                 --tt "$title" \
                 --ta "$artist" \
                 --tl "$album" \
                 --ty "$year" \
                 --tn "$tracknumber" \
                 --tg "$genre" \
                 - "${f%.flac}.mp3"
done

und hier sind einige Statistiken für die Leistungssteigerung durch Parallelität.

find <dirOfFlac24s> -name '*.flac -print0 | xargs -0 -P8 -n1 /usr/local/bin/flac2mp320  

0.00s user 0.00s system 60% cpu 0.002 total
115.94s user 1.40s system 359% cpu 32.655 total

time /usr/local/bin/flac2mp320 <dirOfFlac24s>/*.flac
96.63s user 1.46s system 109% cpu 1:29.98 total

Sie können sehen, dass es auch meine CPUs effektiver nutzte, ich habe ein Intel i7, so dass 8 wahrscheinlich die richtige Anzahl von Prozessen ist.

Jake Plimack
quelle
2

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 ffmpegund lameauf 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 ffmpegund 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/fileskann 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 grepBefehlen zum Parsen von Tags (mit FFprobe, das mit FFmpeg installiert wurde) wird die Groß- und Kleinschreibung nicht berücksichtigt , wenn die -iOption aktiviert wird grep -i.
  • Der folgende cutBefehl 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 seddenen der führenden Nullen entledigt: sed 's/^0*//'.
  • In ähnlichen Skripten im Internet ist die FFmpeg-Ausgabe so etwas wie -f wavund 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_s16leder 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 -rOption hinzufügen .
  • Beachten Sie auch die --tt, --ta, --tl, --tnund --tgID3v2 - 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, --tnund --tgOptionen besser funktionieren; Alle Metadaten sind an Ort und Stelle geschrieben, so dass doppelte Dateien generiert werden müssen.
JakeGould
quelle