Come posso passare da .flac a .mp3 usando LAME e FLAC usando solo il Terminale?


31

Per molto tempo ho usato una relativa tecnica goffa che coinvolge Audacity con un plugin LAME. Va bene, immagino, ma il fascino dell'approccio Terminal è che posso essere un po 'più preciso con il mio [options]e forse usare binari più aggiornati.

Inoltre, il mio MacBook sta invecchiando un po 'adesso e se riesco a liberarmi di una GUI non necessaria, tanto meglio.

Grazie in anticipo.


1
otterrai effettivamente punti per farlo;)
Mortimer

Haha ... ho risposto alla domanda ma sta dicendo che non posso confermare la mia risposta per due giorni. Scusate. Sto ancora cercando di capire come funzionano le cose qui intorno. Sito fantastico. : D
boehj,

Risposte:


41

Conversione di un singolo file senza preservare i tag

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

Uno script di shell che conserva alcuni tag 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

Per usare lo script, salvalo da qualche parte ~/bin/flac2mp3e rendilo eseguibile con chmod +x ~/bin/flac2mp3.

Ciò converte tutti i file flac nella cartella Music:

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

O leggermente più veloce, poiché chiama flac2mp3 solo una volta:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3

2
Dovresti pubblicare qui la risposta, non un riferimento al testo nella domanda. IMHO, dovresti modificare sia la domanda che la risposta e spostare qui la conclusione.
lpacheco,

Ok andrà bene. Scusate.
Boehj,

2
${file%.flac}.mp3è fantastico! In precedenza stavo usando ${x:: ${#x}-3}m4aper cambiare il nome del file della canzone da .wav a .m4a. Fantastico vedere un modo che sembra un po 'più semplice.
Jason Salaz,

1
Sembra che ci sia un bug in un'opzione 3. Forse a causa della versione lame, ma il codice corrente non dice a lame che dovrebbe usare il flusso di input come file di input, e anche il file di output non è specificato, poiché viene utilizzato lo stream, è necessario. Per me il codice finale è: !/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,

Inoltre è bello creare uno script che faccia questo "trova" roba ...
Mehal,

10

ffmpeg manterrebbe i tag (ma non la copertina) per impostazione predefinita.

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

-aq 1corrisponde a -V 1in zoppo. -acodec libfaacconverte i file in AAC:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done

Ho appena fatto questo e ha detto: `` Metadata: comment: Cover (front) encoder: Lavc57.107.100 png `` macOS finder mostra la copertina. ffmpeg 3.4.2 da brew.
Habbie,

Ho quindi capito che il mio ffmpeg era molto vecchio. L'ho aggiornato alla 4.1.3 con lo stesso risultato: file mp3 della stessa dimensione, con copertine funzionanti.
Habbie,

4

ho preso quello che avevate voi ragazzi, ma poi l'ho fatto funzionare ancora più velocemente usando xargsper parallelizzare i lavori.

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

Quindi questo è lo script dall'alto / 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

ed ecco alcune statistiche per l'accelerazione delle prestazioni usando il parallelismo.

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

puoi vedere che ha utilizzato anche le mie CPU in modo più efficace, ho un Intel i7, quindi 8 è probabilmente il giusto numero di processi.


2

Ho trovato questa discussione mentre provavo a fare la codifica diretta di MP3 da file sorgente FLAC. La risposta di Boehj fornisce un'opzione di script decente, ma personalmente preferisco usare FFmpeg, quindi questo è lo script Bash che mi è venuto in mente per gestire questo compito. Testato e funziona alla grande in macOS Sierra (10.12.2).

Perquisites: dovresti avere ffmpege lamegià installato sul tuo Mac. Il modo più semplice per farlo è tramite Homebrew. Per prima cosa assicurati di aver installato Homebrew in questo modo:

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

Quindi eseguire questo comando per installare ffmpege lame:

brew install ffmpeg lame

Fatto ciò, sei pronto per eseguire questo script. Questo script cercherà i file FLAC nella directory path/to/FLAC/filesma che possono essere modificati semplicemente .se i file FLAC si trovano nella stessa directory in cui si sta eseguendo questo script. Quando viene eseguito, verrà creata una mp3/sottodirectory in cui saranno presenti tutti i file MP3 posto.

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

Alcune note sulle cose che ho imparato "The Hard Way ™" in modo che altri possano trarre vantaggio da ciò che ho fatto diversamente in questa sceneggiatura rispetto ad altri su Internet.

  • I grepcomandi per l'analisi dei tag (utilizzando FFprobe installato con FFmpeg) non fanno distinzione tra maiuscole e minuscole utilizzando l' -iopzione per renderlo grep -i.
  • Il cutcomando seguente ora si limita a dividere l'output in base al primo =in un nome tag con l' -f 2-opzione che rende il comando cut -d '=' -f 2-. Ad esempio, Pavement ha una canzone intitolata “5-4 = Unity” e se solo il secondo pezzo fosse stato selezionato tramite taglio quel titolo sarebbe stato troncato a “5-4”.
  • Per track-and totale track-numeri ho aggiunto un tubo in più per sedcui si libera di zeri: sed 's/^0*//'.
  • In script simili su Internet, l'output di FFmpeg è qualcosa di simile -f wave ciò comprimerebbe effettivamente l'output di FFmpeg che non ha senso in una configurazione di pipe in cui LAME lo ricodificherà. Invece l'output qui è impostato su -f s16le -acodec pcm_s16lequale è sostanzialmente l'output RAW; perfetto per il piping dell'audio in un altro processo come questo.
  • Per gestire l'output RAW sul lato LAME della pipe, ho dovuto aggiungere l' -ropzione.
  • Da notare anche i --tt, --ta, --tl, --tne --tgle opzioni di tag ID3v2 per LAME. Quando l'audio viene trasmesso / reindirizzato da un processo a LAME, i metadati dal file di origine vengono persi. Una possibilità suggerito è quello di ottenere FFmpeg per salvare i metadati a un file di testo impostando l'opzione con -f ffmetadata "[metadata filename here]"e poi correre di nuovo FFmpeg con l'qualcosa di simile a questo: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1. Funziona, ma nota i requisiti per un file di destinazione. Sembra che FFmpeg importi i metadati solo quando è in grado di copiare il file, il che sembra un processo molto dispendioso. Utilizzando FFprobe per ottenere i valori e poi impostando a Lame con --tt, --ta, --tl, --tne --tgle opzioni funziona meglio; tutti i metadati sono scritti in posizione, quindi è necessario generare un file duplicato.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.