Encontrei este tópico ao tentar codificar diretamente MP3s a partir de arquivos de origem FLAC. A resposta de Boehj fornece uma opção de script decente, mas eu pessoalmente prefiro usar o FFmpeg, então esse é o script do Bash que criei para lidar com essa tarefa. Testado e funciona muito bem no macOS Sierra (10.12.2).
Requisitos: Você já deve ter ffmpeg
e lame
já instalado no seu Mac. A maneira mais fácil de fazer isso é através do Homebrew. Primeiro, verifique se o Homebrew está instalado assim:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Em seguida, execute este comando para instalar ffmpeg
e lame
:
brew install ffmpeg lame
Feito isso, você estará pronto para executar este script. Esse script procurará arquivos FLAC no diretório, path/to/FLAC/files
mas isso pode ser alterado simplesmente .
se os arquivos FLAC estiverem no mesmo diretório em que você está executando esse script. Quando executado, ele cria um mp3/
subdiretório no qual todos os arquivos MP3 serão colocou.
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
Algumas anotações sobre as coisas que aprendi “The Hard Way ™” para que outros possam ganhar com o que fiz de maneira diferente neste script em comparação com outras pessoas na Internet.
- Os
grep
comandos para análise de tags (usando o FFprobe, instalado com o FFmpeg) não diferenciam maiúsculas de minúsculas, usando a -i
opção para fazê-lo grep -i
.
- O
cut
comando a seguir agora está limitado a dividir a saída apenas com base no primeiro =
em um nome de tag com a -f 2-
opção que faz o comando cut -d '=' -f 2-
. Por exemplo, o Pavement tem uma música intitulada “5-4 = Unity” e se apenas o segundo pedaço fosse selecionado por meio de corte, esse título seria truncado para “5-4”.
- Para o controle e total de faixas-números eu adicionei um tubo extra para
sed
que se livrar de zeros à esquerda: sed 's/^0*//'
.
- Em scripts semelhantes na Internet, a saída FFmpeg é algo parecido
-f wav
e isso realmente comprimiria a saída FFmpeg, o que não faz sentido em uma configuração de canal em que o LAME a recodificará. Em vez disso, a saída aqui é definida como -f s16le -acodec pcm_s16le
basicamente saída RAW; perfeito para canalizar áudio para outro processo como este.
- Para lidar com a saída RAW no lado LAME do tubo, tive que adicionar a
-r
opção.
- Além disso, observe as
--tt
, --ta
, --tl
, --tn
e --tg
opções de tag ID3v2 para LAME. Quando o áudio é transmitido / transmitido de um processo para LAME, os metadados do arquivo de origem são perdidos. Uma opção sugerida é obter FFmpeg para salvar os metadados para um arquivo de texto, definindo a opção com -f ffmetadata "[metadata filename here]"
e, em seguida, executar o FFmpeg novamente com a algo como isto: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1
. Isso funciona, mas observe o requisito para um arquivo de destino. Parece que o FFmpeg importa apenas metadados quando pode copiar o arquivo, o que parece ser um processo muito inútil. Usando FFprobe para obter valores e, em seguida, colocá-los em LAME com --tt
, --ta
, --tl
, --tn
e --tg
opções funciona melhor; todos os metadados são gravados no local, portanto é necessário gerar um arquivo duplicado.