Conversión de audio sin pérdida de FLAC a ALAC usando ffmpeg

13

Tanto ALAC como FLAC son formatos de audio sin pérdidas y los archivos generalmente tendrán más o menos el mismo tamaño cuando se convierten de un formato a otro. Utilizo ffmpeg -i track.flac track.m4apara convertir entre estos dos formatos, pero noto que los archivos ALAC resultantes son mucho más pequeños que los originales. Cuando se utiliza un software convertidor como el MediaHuman Audio Converter, el tamaño de los ALAC se mantendrá alrededor del mismo tamaño que los FLAC, así que supongo que me faltan algunas banderas que están causando la ffmpegdisminución de la señal.

DarthPaghius
fuente
ffmpeggeneralmente necesita el -acodecdestino de cualquier destino para asegurarse de que la conversación se realiza correctamente. Hay muchos front-end que se usan, ffmpegpero he notado que muchos no incluyen ALAC como una opción de salida.
Fanático vegano

Respuestas:

23

Ok, probablemente fui un poco rápido para preguntar aquí, pero para referencia futura aquí está la respuesta:

Se debe pasar la bandera -acodec alaca ffmpegpara una conversión sin pérdidas entre FLAC y ALAC:

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

DarthPaghius
fuente
66
Para explicar lo que está sucediendo aquí: .m4a es una variante de Apple del formato de archivo MP4. FFmpeg y la mayoría de otros s / w de forma predeterminada el codificador AAC cuando se da salida a mp4o m4a, de ahí el expreso -acodeces necesario opción.
Gyan
2
Algunos archivos FLAC contienen una miniatura de portada de álbum. Puede agregarlos -vcodec copypara incluirlos en sus nuevos archivos ALAC.
Sean
2

Y para convertir un directorio completo ...

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:

Pensé que podía hacer que esto funcionara con un solo comando, pero no escapa a caracteres especiales, como [.

Parecía tan prometedor ...

#!/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
fuente
2
Aquí hay una frase que uso para la conversión: 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 una opción perfecta para directorios individuales, sin recursividad.
CoolAJ86