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.


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

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

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.


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.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.