¿Cómo paso de .flac a .mp3 usando LAME & FLAC usando solo la Terminal?

31

Durante mucho tiempo he estado usando una técnica relativamente torpe que involucra a Audacity con un complemento LAME. Esto está bien, supongo, pero el atractivo del enfoque de Terminal es que puedo ser un poco más fino con mi [options]y tal vez usar binarios más actualizados.

Además, mi MacBook está envejeciendo un poco ahora y si puedo deshacerme de una GUI innecesaria, mucho mejor.

Gracias por adelantado.

boehj
fuente
1
en realidad obtendrá puntos por hacerlo;)
Mortimer
Jaja ... he respondido la pregunta pero dice que no puedo confirmar mi respuesta durante dos días. Lo siento. Todavía estoy averiguando cómo funcionan las cosas por aquí. Sitio impresionante. : D
boehj

Respuestas:

41

Convertir un solo archivo sin preservar etiquetas

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

Un script de shell que conserva algunas etiquetas 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

Para usar el script, simplemente guárdelo en algún lugar ~/bin/flac2mp3y hágalo ejecutable con chmod +x ~/bin/flac2mp3.

Esto convertiría todos los archivos flac en su carpeta Música:

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

O un poco más rápido, ya que solo llama a flac2mp3 una vez:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3
boehj
fuente
2
Debe publicar la respuesta aquí, no una referencia al texto en la pregunta. En mi humilde opinión, debe editar tanto la pregunta como la respuesta y mover aquí la conclusión.
lpacheco
OK lo haré. Lo siento.
boehj
2
${file%.flac}.mp3¡es increíble! Anteriormente estaba usando ${x:: ${#x}-3}m4apara cambiar el nombre de archivo de la canción de .wav a .m4a. Impresionante ver una forma que parece un poco más fácil.
Jason Salaz
1
Parece que hay un error en una Opción 3. Posiblemente debido a una versión pobre, pero el código actual no le dice a la mala que debe usar la secuencia de entrada como archivo de entrada, y tampoco se especifica el archivo de salida, ya que la secuencia se usa, es necesario. Para mí el código final es: !/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
También es bueno crear un script que haga estas cosas de 'encontrar' ...
Mehal
10

ffmpeg conservaría las etiquetas (pero no la portada) de forma predeterminada.

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

-aq 1corresponde a -V 1cojo. -acodec libfaacconvertiría los archivos a AAC:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done
Lri
fuente
Acabo de hacer esto y decía: `` `` Metadatos: comentario: codificador de cubierta (frontal): Lavc57.107.100 png `` `MacOS Finder muestra la portada. ffmpeg 3.4.2 de la cerveza.
Habbie
Entonces me di cuenta de que mi ffmpeg era muy viejo. Lo actualicé a 4.1.3 con el mismo resultado: archivos mp3 del mismo tamaño, con una portada que funciona.
Habbie
4

Tomé lo que ustedes tenían, pero luego lo hice correr aún más rápido usando xargspara paralelizar los trabajos.

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

Entonces este es el script de arriba / 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

y heres algunas estadísticas para la aceleración del rendimiento usando paralelismo.

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

puede ver que también utilizó mis CPU de manera más efectiva, tengo un Intel i7, por lo que 8 es probablemente la cantidad correcta de procesos.

Jake Plimack
fuente
2

Encontré este hilo mientras intentaba hacer una codificación directa de MP3 desde archivos fuente FLAC. La respuesta de Boehj proporciona una opción de script decente, pero personalmente prefiero usar FFmpeg, por lo que este es el script Bash que se me ocurrió para manejar esta tarea. Probado y funciona muy bien en macOS Sierra (10.12.2).

Gratificaciones: Usted debe tener ffmpegy lameya instalado en su Mac. La forma más fácil de hacerlo es a través de Homebrew. Primero asegúrese de tener Homebrew instalado así:

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

Luego ejecute este comando para instalar ffmpegy lame:

brew install ffmpeg lame

Una vez hecho esto, está listo para ejecutar este script. Este script buscará archivos FLAC en el directorio, path/to/FLAC/filespero eso se puede cambiar para que simplemente se encuentre .si los archivos FLAC están en el mismo directorio en el que está ejecutando este script. Cuando se ejecute, creará un mp3/subdirectorio donde estarán todos los archivos MP3. metido.

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

Algunas notas sobre cosas que aprendí "The Hard Way ™" para que otros puedan beneficiarse de lo que hice de manera diferente en este script en comparación con otros en Internet.

  • Los grepcomandos para el análisis de etiquetas (usando FFprobe que se instala con FFmpeg) no distinguen entre mayúsculas y minúsculas, utilizando la -iopción para hacerlo grep -i.
  • El siguiente cutcomando ahora se limita a dividir la salida solo en función del primero =en un nombre de etiqueta con la -f 2-opción que hace el comando cut -d '=' -f 2-. Por ejemplo, Pavimento tiene una canción titulada “5-4 = Unidad” y si solo se seleccionara el segundo fragmento por corte, ese título se habría truncado a “5-4”.
  • Para rastreo y seguimiento de números totales añadí un tubo adicional a sedla que se deshace de los ceros iniciales: sed 's/^0*//'.
  • En scripts similares en Internet, la salida de FFmpeg es algo así -f wavy eso realmente comprimiría la salida de FFmpeg, lo que no tiene sentido en una configuración de tubería donde LAME la va a volver a codificar. En cambio, la salida aquí se establece en -f s16le -acodec pcm_s16leque es básicamente salida RAW; perfecto para canalizar audio a otro proceso como este.
  • Para lidiar con la salida RAW en el lado LAME de la tubería, tuve que agregar la -ropción.
  • También tenga en cuenta los --tt, --ta, --tl, --tny --tgopciones de etiquetas ID3v2 para LAME. Cuando el audio se transmite / transmite de un proceso a LAME, se pierden los metadatos del archivo fuente. Una opción sugerida es conseguir FFmpeg para guardar los metadatos de un archivo de texto mediante el establecimiento de la opción con -f ffmetadata "[metadata filename here]"y ejecutando FFmpeg de nuevo con el algo como esto: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1. Eso funciona, pero tenga en cuenta el requisito de un archivo de destino. Parece que FFmpeg solo importa metadatos cuando puede copiar el archivo, lo que parece un proceso muy derrochador. Usando FFprobe para obtener valores y luego colocarlos en LAME con --tt, --ta, --tl, --tny --tgopciones funciona mejor; Todos los metadatos se escriben en su lugar, por lo que es necesario generar un archivo duplicado.
JakeGould
fuente