Encontré este hilo mientras intentaba hacer una codificación directa de MP3 a partir de archivos fuente FLAC. Respuesta de Boehj proporciona una opción de scripting decente, pero personalmente prefiero usar FFmpeg, así que este es el Bash script que se me ocurrió para manejar esta tarea. Probado y funciona muy bien en MacOS Sierra (10.12.2).
Permisos: Deberías tener ffmpeg
y lame
ya instalado en tu Mac. La forma más fácil de hacerlo es a través de Homebrew. Primero asegúrate de que tienes Homebrew instalado así:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
A continuación, ejecute este comando para instalar ffmpeg
y lame
:
brew install ffmpeg lame
Una vez hecho esto, estás listo para ejecutar este script. Este script buscará los archivos FLAC en el directorio path/to/FLAC/files
pero se puede cambiar para que sea simplemente .
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 se colocarán todos los archivos MP3.
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 las 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.
- El
grep
para el análisis sintáctico de las etiquetas (utilizando FFprobe que se instala con FFmpeg) no distinguen entre mayúsculas y minúsculas utilizando el -i
opción para hacerlo grep -i
.
- Lo siguiente
cut
se limita ahora a dividir la salida sólo en función del primer =
en un nombre de etiqueta con el -f 2-
que hace que el comando cut -d '=' -f 2-
. Por ejemplo, Pavimento tiene una canción titulada "5-4=Unidad" y si sólo se seleccionara el segundo trozo vía corte ese título se habría truncado a "5-4".
- Para los números de pista -y de pista total- he añadido una tubería adicional a
sed
que elimina los ceros a la izquierda: sed 's/^0*//'
.
- En otros scripts scripts de Internet, la salida de FFmpeg es algo así como
-f wav
y eso en realidad comprimiría la salida de FFmpeg, lo que no tiene sentido en una configuración de tuberías donde LAME va a recodificarla. En lugar de eso, la salida aquí se establece en -f s16le -acodec pcm_s16le
que es básicamente la salida RAW; perfecto para canalizar el audio a otro proceso como este.
- Para hacer frente a la salida RAW en el lado LAME de la tubería, tuve que añadir el
-r
opción.
- También hay que tener en cuenta el
--tt
, --ta
, --tl
, --tn
y --tg
Opciones de etiquetas ID3v2 para LAME. Cuando se transmite el audio desde un proceso a LAME, se pierden los metadatos del archivo de origen. Una opción sugerida es hacer que FFmpeg guarde los metadatos en un archivo de texto estableciendo la opción con -f ffmetadata "[metadata filename here]"
y luego ejecutar 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 ten en cuenta el requisito de un archivo de destino. Parece que FFmpeg sólo importa los metadatos cuando puede copiar el archivo, lo que parece un proceso muy desperdiciado. Usando FFprobe para obtener los valores y luego establecerlos en LAME con --tt
, --ta
, --tl
, --tn
y --tg
funciona mejor; todos los metadatos se escriben en su lugar, por lo que es necesario generar un archivo duplicado.