Comment passer de .flac à .mp3 en utilisant LAME & FLAC en utilisant le terminal seul?

31

Depuis longtemps, j'utilise une technique relativement maladroite qui implique Audacity avec un plugin LAME. C'est bien, je suppose, mais l'attrait de l'approche Terminal est que je peux être un peu plus fin avec mes [options]et peut-être utiliser des binaires plus à jour.

De plus, mon MacBook vieillit un peu maintenant et si je peux me débarrasser d'une interface graphique inutile, tant mieux.

Merci d'avance.

boehj
la source
1
vous obtiendrez des points pour cela;)
Mortimer le
Haha ... J'ai répondu à la question mais ça dit que je ne peux pas confirmer ma réponse pendant deux jours. Désolé. Toujours en train de comprendre comment les choses fonctionnent ici. Site génial. : D
boehj

Réponses:

41

Conversion d'un seul fichier sans conserver les balises

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

Un script shell qui conserve certaines balises ID3

#!/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

Pour utiliser le script, il suffit de l'enregistrer quelque part comme ~/bin/flac2mp3et de le rendre exécutable avec chmod +x ~/bin/flac2mp3.

Cela convertirait tous les fichiers flac de votre dossier Musique:

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

Ou légèrement plus rapide, car il n'appelle flac2mp3 qu'une seule fois:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3
boehj
la source
2
Vous devez poster la réponse ici, pas une référence au texte de la question. À mon humble avis, vous devez modifier à la fois la question et la réponse et déplacer ici la conclusion.
lpacheco
OK je le ferai. Désolé.
boehj
2
${file%.flac}.mp3est génial! Auparavant, j'utilisais ${x:: ${#x}-3}m4apour changer le nom de fichier de la chanson de .wav en .m4a. Génial de voir un moyen qui semble un peu plus facile.
Jason Salaz
1
Il semble qu'il y ait un bogue dans une option 3. Peut-être à cause de la version boiteuse, mais le code actuel ne dit pas à lame qu'il devrait utiliser le flux d'entrée comme fichier d'entrée, et que le fichier de sortie n'est pas spécifié, puisque le flux est utilisé, il est nécessaire. Pour moi, le code final est: !/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
De plus, il est agréable de créer un script qui fait ce "truc" de recherche ...
Mehal
10

ffmpeg conserverait les balises (mais pas les illustrations) par défaut.

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

-aq 1correspond à -V 1boiteux. -acodec libfaacconvertirait les fichiers en AAC:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done
Lri
la source
Je viens de le faire et il a dit: `` `` Métadonnées: commentaire: Encodeur de couverture (avant): Lavc57.107.100 png '' `` MacOS Finder montre la pochette. ffmpeg 3.4.2 de l'infusion.
Habbie
J'ai alors réalisé que mon ffmpeg était très vieux. Je l'ai mis à jour vers 4.1.3 avec le même résultat - des fichiers mp3 de la même taille, avec une pochette fonctionnelle.
Habbie
4

J'ai pris ce que vous aviez, mais je l'ai fait fonctionner encore plus rapidement en utilisant xargspour paralléliser les travaux.

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

Ensuite, voici le script ci-dessus / 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

et voici quelques statistiques pour l'accélération des performances en utilisant le parallélisme.

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

vous pouvez voir qu'il a également utilisé mes processeurs plus efficacement, j'ai un Intel i7, donc 8 est probablement le bon nombre de processus.

Jake Plimack
la source
2

Trouvé ce fil en essayant de faire l'encodage direct des MP3 à partir des fichiers source FLAC. La réponse de Boehj fournit une option de script décente, mais je préfère personnellement utiliser FFmpeg, c'est donc le script Bash que j'ai trouvé pour gérer cette tâche. Testé et fonctionne très bien dans macOS Sierra (10.12.2).

Les avantages indirects: Vous devriez avoir ffmpeget lamedéjà installé sur votre Mac. La façon la plus simple de le faire est via Homebrew. Assurez-vous d'abord que Homebrew est installé comme ceci:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Exécutez ensuite cette commande pour installer ffmpeget lame:

brew install ffmpeg lame

Une fois cela fait, vous êtes prêt à exécuter ce script. Ce script recherchera les fichiers FLAC dans le répertoire, path/to/FLAC/filesmais cela peut être modifié simplement .si les fichiers FLAC se trouvent dans le même répertoire que celui dans mp3/lequel vous exécutez ce script. Lorsqu'il s'exécute, il crée un sous-répertoire où tous les fichiers MP3 seront mis.

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

Quelques notes sur des choses que j'ai apprises «The Hard Way ™» afin que d'autres puissent tirer profit de ce que j'ai fait différemment dans ce script par rapport à d'autres sur Internet.

  • Les grepcommandes pour l'analyse des balises (en utilisant FFprobe qui est installé avec FFmpeg) ne respectent pas la casse en utilisant l' -ioption pour le rendregrep -i .
  • La cutcommande suivante se limite désormais à diviser la sortie uniquement sur la base du premier =dans un nom de balise avec l' -f 2-option qui rend la commande cut -d '=' -f 2-. Par exemple, Pavement a une chanson intitulée «5-4 = Unity» et si seulement le deuxième morceau avait été sélectionné via la coupe, ce titre aurait été tronqué à «5-4».
  • Pour les numéros de piste - et de piste totale -, j'ai ajouté un tube supplémentaire sedqui supprime les zéros non significatifs:sed 's/^0*//' .
  • Dans des scripts similaires sur Internet, la sortie FFmpeg ressemble à quelque chose -f wavet cela compresserait en fait la sortie FFmpeg, ce qui n'a aucun sens dans une configuration de canal où LAME va le ré-encoder. Au lieu de cela, la sortie ici est définie sur-f s16le -acodec pcm_s16le laquelle est essentiellement la sortie RAW; parfait pour diriger l'audio vers un autre processus comme celui-ci.
  • Pour gérer la sortie RAW du côté LAME du tuyau, j'ai dû ajouter l' -roption.
  • A noter également les --tt, --ta, --tl, --tnet les --tgoptions de tag ID3v2 pour BOITEUX. Lorsque l'audio est diffusé / canalisé d'un processus dans LAME, les métadonnées du fichier source sont perdues. Une option proposée est d'obtenir FFmpeg pour enregistrer les métadonnées dans un fichier texte en définissant l'option avec -f ffmetadata "[metadata filename here]"puis à nouveau FFmpeg courir avec quelque chose comme ceci: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1. Cela fonctionne, mais notez l'exigence d'un fichier de destination. On dirait que FFmpeg importe uniquement des métadonnées lorsqu'il peut copier le fichier, ce qui semble être un processus très coûteux. En utilisant FFprobe pour obtenir des valeurs, puis les mettre en BOITEUX avec --tt, --ta, --tl, --tnet les --tgoptions fonctionne mieux; toutes les métadonnées sont écrites sur place, donc un fichier en double doit être généré.
JakeGould
la source