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 ffmpeg
y lame
ya 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 ffmpeg
y 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/files
pero 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
grep
comandos para el análisis de etiquetas (usando FFprobe que se instala con FFmpeg) no distinguen entre mayúsculas y minúsculas, utilizando la -i
opción para hacerlo grep -i
.
- El siguiente
cut
comando 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
sed
la que se deshace de los ceros iniciales: sed 's/^0*//'
.
- En scripts similares en Internet, la salida de FFmpeg es algo así
-f wav
y 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_s16le
que 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
-r
opción.
- También tenga en cuenta los
--tt
, --ta
, --tl
, --tn
y --tg
opciones 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
, --tn
y --tg
opciones funciona mejor; Todos los metadatos se escriben en su lugar, por lo que es necesario generar un archivo duplicado.