Encontré este hilo al intentar realizar una codificación directa de archivos MP3 desde archivos fuente de FLAC. La respuesta de Boehj proporciona una opción de script decente, pero personalmente prefiero usar FFmpeg, así que este es el script de Bash que vine con para manejar esta tarea. Probado y funciona muy bien en macOS Sierra (10.12.2).
Requisitos: Debes tener ffmpeg
y lame
ya instalados en tu Mac. La forma más fácil de hacerlo es a través de Homebrew. Primero asegúrese de tener Homebrew instalado de esta manera:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Luego ejecuta este comando para instalar ffmpeg
y lame
:
brew install ffmpeg lame
Una vez hecho esto, ya está listo para ejecutar este script. Este script buscará los archivos FLAC en el directorio path/to/FLAC/files
, pero se puede cambiar para que simplemente sea .
si los archivos FLAC están en el mismo directorio en el que está ejecutando este script. Cuando se ejecute, se 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 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 otras en Internet.
- Los comandos
grep
para el análisis de etiquetas (usando FFprobe que se instala con FFmpeg) no distinguen entre mayúsculas y minúsculas al utilizar -i
Opción para hacer que sea grep -i
.
- El siguiente comando
cut
ahora está limitado a dividir la salida solo en base al primer =
en un nombre de etiqueta con la opción -f 2-
que hace el comando cut -d '=' -f 2-
. Por ejemplo, Pavement tiene una canción titulada "5-4 = Unidad" y si solo es la segunda parte se seleccionaron por corte y ese título se habría truncado a "5-4".
- Para los números de pista y total de pistas, agregué una canalización adicional a
sed
que elimina los ceros iniciales: sed 's/^0*//'
.
- En scripts similares en Internet, la salida de FFmpeg es algo así como
-f wav
y eso en realidad comprimiría la salida de FFmpeg, lo cual no tiene sentido en una configuración de tubería donde LAME lo va a recodificar. En su lugar, la salida aquí se establece en -f s16le -acodec pcm_s16le
, que es básicamente una 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 opción
-r
.
- También tenga en cuenta las opciones de etiqueta
--tt
, --ta
, --tl
, --tn
y --tg
ID3v2 para LAME. Cuando el audio se transmite / canaliza desde un proceso a LAME, los metadatos del archivo fuente se pierden. Una opción sugerida es hacer que FFmpeg guarde los metadatos en un archivo de texto configurando la opción con -f ffmetadata "[metadata filename here]"
y luego ejecutando FFmpeg nuevamente con 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 inútil. Usar FFprobe para obtener valores y luego establecerlos en LAME con las opciones --tt
, --ta
, --tl
, --tn
y --tg
funciona mejor; todos los metadatos están escritos en su lugar, por lo que se debe generar un archivo duplicado.