Como eu vou de .flac para .mp3 usando LAME e FLAC usando apenas o Terminal?

31

Há muito tempo que uso uma técnica desajeitada que envolve o Audacity com um plugin LAME. Tudo bem, eu acho, mas o apelo da abordagem do Terminal é que posso ser um pouco mais refinado com os meus [options]e talvez usar binários mais atualizados.

Além disso, meu MacBook está envelhecendo um pouco agora e, se eu puder me livrar de uma GUI desnecessária, tanto melhor.

Desde já, obrigado.

boehj
fonte
1
você realmente ganhará pontos por fazer isso;)
Mortimer
Haha ... Eu respondi a pergunta, mas está dizendo que não posso confirmar minha resposta por dois dias. Desculpe. Ainda tentando descobrir como as coisas funcionam por aqui. Site incrível. : D
boehj 24/02

Respostas:

41

Convertendo um único arquivo sem preservar tags

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

Um script de shell que preserva algumas tags 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 o script, salve-o em algum lugar ~/bin/flac2mp3e torne-o executável chmod +x ~/bin/flac2mp3.

Isso converteria todos os arquivos flac na sua pasta Music:

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

Ou um pouco mais rápido, pois chama flac2mp3 apenas uma vez:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3
boehj
fonte
2
Você deve postar a resposta aqui, não uma referência ao texto da pergunta. IMHO, você deve editar a pergunta e a resposta e passar aqui a conclusão.
Lpacheco
OK, vai fazer. Desculpe.
24511 Boehj
2
${file%.flac}.mp3é incrível! Anteriormente, eu estava usando ${x:: ${#x}-3}m4apara alterar o nome do arquivo da música de .wav para .m4a. Incrível ver uma maneira que parece um pouco mais fácil.
precisa
1
Parece que há um erro na Opção 3. Possivelmente por causa da versão coxo, mas o código atual não diz ao coxo que ele deve usar o fluxo de entrada como arquivo de entrada e também o arquivo de saída não é especificado, já que o fluxo é usado, é necessário. Para mim, o código final é: !/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 28/02
Também é bom criar um script que faça essas coisas de 'encontrar' ... #
317 Mehal
10

O ffmpeg preservaria as tags (mas não a arte da capa) por padrão.

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

-aq 1corresponde -V 1em coxo. -acodec libfaacconverteria os arquivos para AAC:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done
Lri
fonte
Acabei de fazer isso e ele dizia: `` Metadados: comentário: codificador de capa (frente): Lavc57.107.100 png `` `O localizador do macOS mostra a arte da capa. ffmpeg 3.4.2 da fermentação.
Habbie 23/04
Percebi então que meu ffmpeg era muito antigo. Eu atualizei para 4.1.3 com o mesmo resultado - arquivos mp3 do mesmo tamanho, com arte de capa em funcionamento.
Habbie
4

Peguei o que vocês tinham, mas depois o fiz funcionar ainda mais rápido usando xargspara paralelizar os trabalhos.

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

Então este é o script acima / 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

e aqui estão algumas estatísticas para a aceleração do desempenho 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

você pode ver que ele também utilizou minhas CPUs com mais eficiência, eu tenho um intel i7, então 8 é provavelmente o número certo de processos.

Jake Plimack
fonte
2

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 ffmpege lamejá 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 ffmpege 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/filesmas 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 grepcomandos para análise de tags (usando o FFprobe, instalado com o FFmpeg) não diferenciam maiúsculas de minúsculas, usando a -iopção para fazê-lo grep -i.
  • O cutcomando 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 sedque se livrar de zeros à esquerda: sed 's/^0*//'.
  • Em scripts semelhantes na Internet, a saída FFmpeg é algo parecido -f wave 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_s16lebasicamente 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 -ropção.
  • Além disso, observe as --tt, --ta, --tl, --tne --tgopçõ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, --tne --tgopções funciona melhor; todos os metadados são gravados no local, portanto é necessário gerar um arquivo duplicado.
JakeGould
fonte