Conversão de áudio sem perdas de FLAC para ALAC usando ffmpeg

13

Tanto o ALAC quanto o FLAC são formatos de áudio sem perdas e os arquivos geralmente terão mais ou menos o mesmo tamanho quando convertidos de um formato para outro. Eu uso ffmpeg -i track.flac track.m4apara converter entre esses dois formatos, mas percebo que os arquivos ALAC resultantes são muito menores que os originais. Ao usar um software conversor como o MediaHuman Audio Converter, o tamanho dos ALACs permanecerá com o mesmo tamanho dos FLACs, então acho que estou perdendo alguns sinalizadores aqui que estão causando ffmpega redução da amostra do sinal.

DarthPaghius
fonte
ffmpeggeralmente precisa -acodecde qualquer destino para ter certeza de que a conversa está correta. Existem muitos front-ends que são usados, ffmpegmas notei que muitos não incluem o ALAC como uma opção de saída.
Vegan Fanatic

Respostas:

23

Ok, provavelmente fui um pouco rápido em perguntar aqui, mas, para referência futura, aqui está a resposta:

Deve-se passar o sinalizador -acodec alacpara ffmpeguma conversão sem perdas entre FLAC e ALAC:

ffmpeg -i track.flac -acodec alac track.m4a

DarthPaghius
fonte
6
Para explicar o que está acontecendo aqui: .m4a é uma variante da Apple do formato de arquivo MP4. O FFmpeg e a maioria dos outros s / w serão padronizados para o codificador AAC ao enviar para mp4ou m4a, portanto, a -acodecopção expressa é necessária.
Gyan
2
Alguns arquivos FLAC contêm uma miniatura da capa do álbum. Você pode adicionar -vcodec copypara incluir nos seus novos arquivos ALAC.
21319 Sean
2

E para converter um diretório inteiro ...

Uso

pushd './Music/Some Album [flac]'
bash flac-to-alac.sh 

flac-to-alac.sh:

#!/usr/bin/env bash
my_bin="$(dirname $0)/flac-to-alac-ffmpeg.sh"
find . -type f -name '*.flac' -exec "$my_bin" {} \;

flac-to-alac-ffmpeg.sh:

#!/usr/bin/env bash
set -e # fail if there's any error
set -u

my_file=$1
my_new="$(echo $(dirname "$my_file")/$(basename "$my_file" .flac).m4a)"
echo "$my_file"
ffmpeg -y -v 0 -i "$my_file" -acodec alac "$my_new"
# only gets here if the conversion didn't fail
#rm "$my_file"

Alternativa:

Eu pensei que eu poderia fazer isso funcionar em um único comando, mas não escapa caracteres especiais, como [.

Parecia tão promissor ...

#!/usr/bin/env bash
set -e # exit immediately on error
set -u # error if a variable is misspelled

while read -r my_file; do
  # ./foo/bar.flac => ./foo/bar.m4a
  my_new="$(dirname "$my_file")/$(basename "$my_file" .flac).m4a"

  ffmpeg -i "$my_file" -acodec alac "$my_new"

  # safe because of set -e, but still do a test run
  #rm "$my_file"
done <<< "$(find . -type f -name '*.flac')"
CoolAJ86
fonte
2
Aqui está uma frase que eu uso para a conversão: for i in *.flac; do echo $i; ffmpeg -i "$i" -y -v 0 -vcodec copy -acodec alac "${i%.flac}".m4a && rm -f "$i"; done
Paul Lindner
@PaulLindner Parece uma opção perfeita para diretórios únicos, sem recursão.
CoolAJ86 13/03