Bash script para convertir todos * flac a * .mp3 con FFmpeg?


28

Quiero convertir todos * .flac a * .mp3 en la carpeta específica.

Esto es lo que he intentado, pero no funciona:

# change to the home directory
cd ~/music
# convert all *.flac files
ffmpeg -i *.flac -acodec libmp3lame *.mp3
# (optional: check whether there are any errors printed on the terminal)
sleep 60

¿Cómo conseguir mi objetivo?


3
intentaste "FOR LOOP"?
Danila Ladner

@DanilaLadner Todavía no. Gracias por la pista
Kevin Dong

Escribí un script que hace esto, en paralelo, y copia las etiquetas en: http://tuxhelp.org/#flac-distiller

Lo siento, lo olvido. Después de convertir el nombre del archivo, conviértase en file.avi.mp3, puede usar: cambie el nombre de "s / .avi // g" * .avi.mp3 para eliminar .avi.

1
Dé un descanso a la computadora después del trabajo duro.
MeowMeow

Respuestas:


37

Prueba esto:

for i in *.flac ; do 
    ffmpeg -i "$i" -acodec libmp3lame "$(basename "${i/.flac}")".mp3
    sleep 60
done

1
No funciona con archivos que contienen espacio. ¿Cómo puedo modificar $(basename "${i/.flac}")para manejar espacios?
ppr

1
@ppr Intenta poner esta línea justo antes del forbucle: IFS = $ '\ n'
mkc

66
Resolví el problema espacial cambiando $(basename "${i/.flac}").mp3a "$(basename "${i/.flac}").mp3"(poniendo comillas)
MalcolmOcean

50

Una solución simple de 1 revestimiento: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;

http://lewisdiamond.blogspot.ca/2012/01/converting-flac-to-mp3.html

Tenga en cuenta que esto se aplicará recursivamente en el directorio dado. Es decir, si ejecuta esto desde su carpeta Música, convertirá todos los flacs de las subcarpetas y producirá un .mp3 al lado. También puede hacerlo sin ffmpeg utilizando directamente flac y lame (es decir, leer w / flac, pipe to lame, salida a un archivo .mp3), como se muestra en el enlace.


Puedes usar -maxdepth 1I think like en la respuesta de X Tian para limitar la recursividad.

2
Sí tu puedes. También puede usar ls canalizado a xargs o un bucle for. Solo estoy asumiendo (posiblemente incorrecto) que una búsqueda recursiva es más de lo que el OP necesitaba (es decir, cambiar todo el .flac de mi biblioteca de música).
Lewis Diamond

16
Este comando es genial, sin embargo; Terminas con archivos llamados * .flac.mp3. Usando su mando, se me ocurrió esto ...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Shane

2
Sí, como expliqué en el blog, me gusta este aspecto de agregar .mp3 porque me dice que estos archivos provienen de una fuente sin pérdidas, que debería encontrarse en algún lugar de mi disco duro.
Lewis Diamond

El comentario de @Shane funcionó para mí.
Chaudhry Waqas

8

Si tiene algunos espacios en blanco en los nombres de archivo:

for a in *.flac; do
  f="${a[@]/%flac/mp3}"
  ffmpeg -i "$a" -qscale:a 0 "$f"
done

Tengo una carpeta con una mezcla de archivos mp4 y wav. ¿Cómo los convierto a mp3? Gracias.
kRazzy R

2

Tomé todo lo que encontré aquí (y tal vez en algunos otros sitios) y creé una pequeña herramienta para no solo crear mp3 de flacs de forma recursiva, sino también preservar rutas relativas para crearlos en otros lugares con soporte de subprocesos múltiples.

Ah, y sí, ya veo, no utilicé ffmpeg en ese caso, porque mi OSMC no proporcionó paquetes para ffmpeg, solo avconv, pero como ya estás aquí, supongo que ya sabes, es "básicamente" el igual, al menos para la parte más importante. Simplemente reemplace el comando "avconv" con "ffmpeg". Mis primeras ejecuciones fueron con el contenedor ffmpeg y exactamente las mismas opciones.

De ninguna manera soy un hacker bash, pero lo logré, como mi primer bashscript con las demandas dadas, y tal vez alguien se beneficie. Estoy abierto a cualquier sugerencia de su parte, pero hasta ahora me funciona.

mi script para activar las 4 instancias, una para cada núcleo, es así:

#!/bin/bash
# this should be quite self-explanatory 
for i in {1..4}
do
echo "started instance no: $i"
/home/osmc/transform.sh . &
# sleeping time can be shorter, this is just so, that 
# not all 4 processes will want to start with the same 
# file, during runtime collisions should not become an issue
sleep 5
done
echo "all instances started"

Y el script de trabajo como este:

#!/bin/bash
# take care of spaces
IFS=$'\n'
# my music folders, remote is the source, local the target dir
remote=/mnt/music/FLAC
local=/mnt/1tb/mp3
# for all flac files start loop
for i in $(find $remote -type f -iname '*.flac' );
do
## SET VARIABLES for PATHS and FILENAMES
## this might be able to be super short with sed and complex one-liner,
## but I s*ck at regex
fullfile=$i
# strip extension
filename="${i##*/}"
# add new extension
filename="${filename%.*}.mp3"
# get full dirname from inputfile
fulldir=$(dirname "${i}")
# strip leading dirs from full input dir
# count the dirs, add two, then you're good.
reldir="$(echo $fulldir | cut -d'/' -f5-)"
# some subdirs in my collection even have a flac subdir, you might
# ignore this, it strips only if it exists
reldir=${reldir//flac}
# combine target dir and relative dir
outdir="$local/$reldir"
# generate the full output filename for conversion
outfile="$outdir/$filename"
# create whole target directory - yes, I need it only once, but hey,
# it works, didn't want to start a if not exist statement... should I? 
mkdir -p "$outdir"
# run conversion - finally... you may want or need to replace 
# "avconv" with "ffmpeg"
avconv -n -nostats -loglevel info -i "$fullfile" -codec:a libmp3lame -qscale:a 0 "$outfile"
done

que se puede encontrar en https://github.com/erdnuesse/flac-to-mp3

Saludos, Kay.


bienvenido a bordo, buen esfuerzo. +1
Alex Stragies

1

Trabajé en la respuesta de @ Ketan usando avconv, ya que ffmpeg no funciona bien aquí.

for i in *.flac ; do 
    avconv -i "$i" "./mp3/$i".mp3
done

Esto convierte los flacarchivos de una carpeta en mp3archivos y luego los mueve a una carpeta "mp3" existente. Los archivos se nombrarán en el modelo "original_name.flac.mp3"


1
find . -maxdepth 1 -type f -name '*.flac' | while IFS= read -r f; do
  ffmpeg -i  "$f" -acodec libmp3lame "$( sed -e's/\.flac/.mp3/g' <<< $f )"
done

1
La expresión sed necesita un final '
Jaime M.

1

GNU Parallel está hecho para este tipo de tareas:

# change to the home directory
cd ~/music
# convert all *.flac files
parallel ffmpeg -i {} -acodec libmp3lame {.}.mp3 ::: *.flac
# (optional: check whether there are any errors printed on the terminal)
sleep 60

Ejecutará los trabajos en paralelo (un trabajo por núcleo de CPU) y se asegurará de que la salida en el terminal no se mezcle.

Para obtener más información, pase 15 minutos leyendo el capítulo 1 + 2: https://zenodo.org/record/1146014


Esto se ve interesante. ¿Podría explicar lo que hace la {.}.mp3 :::construcción? ¿O consulte la sección del manual que lo explica?
jottr


0

Por ejemplo, si tiene varios archivos avi:

ls *.avi | xargs -I {} ffmpeg -i {} {}.mp3

0

Si puede ayudar ... He escrito un pequeño script bash para hacer esto ... Necesitas tener instalado ffmpeg / flac.

Cómo funciona:

Se necesitan 2 argumentos:

  1. La carpeta de tu biblioteca de música (flac / ogg / mp3 ...)
  2. La carpeta de destino (debe crearla antes).

Produce:

  • Una copia exacta de la carpeta de origen a la carpeta de destino, con:
    • los archivos no flac copiados.
    • los archivos flac transformados a mp3 (VBR de alta calidad)
  • Un archivo run.sh con los comandos para convertir los archivos flac (este script se ejecuta automáticamente).

#!/bin/bash

FLAC_PATH=$1
CONV_PATH=$2

DEBUG=0;

function usage {
  echo "";
  echo "    This script convert all flac files from a folder to mp3 files to a second folder";
  echo "";
  echo "    Usage :";
  echo "        ./conv.sh {Source Folder} {Destination Folder}";
  echo "        note : booth folder must exist before starting this script";
  echo "               files other than flac are copied to the destination folder";
  echo "";
}

if [ ! -d "$2" ]; then
  echo "";
  echo " ERROR : [$2] is not a directory.";
  usage
  exit 1
fi;

if [ ! -d "$2" ]; then
  echo "";
  echo " ERROR : [$2] is not a directory.";
  usage
  exit 1
fi;

COMMANDS="run.sh"
echo "" > run.sh
echo " convert from $FLAC_PATH to $CONV_PATH ";

find "${FLAC_PATH}" -type f |while read myFile; do
  SRC_DIR=${myFile%/*}
  SRC_FILE=${myFile##*/}
  DST_DIR=$CONV_PATH/$SRC_DIR
  mkdir -p "${DST_DIR}"
  # TEST if the file is a flac ....
  metaflac --show-md5sum "${myFile}" 2>/dev/null 1>/dev/null
  if [ $? -eq 0 ]; then
    echo -n "  *** $myFile [FLAC !] : "
    DST_FILE=${myFile%.*}
    OUT_PATH="${DST_DIR}/$( echo $SRC_FILE | sed -e 's/.flac$/.mp3/')"

    if [ $DEBUG == 1 ]; then
      echo "  SRC = $myFile";
      echo "  OUT = $OUT_PATH"
    fi;

    if [ -f "$OUT_PATH" ]; then
      echo "  exist, do nothing !";
    else
      echo "  add to compress list !";
      echo "ffmpeg -y -i \"${myFile}\" -codec:a libmp3lame -q:a 0 -map_metadata 0 -id3v2_version 3 \"${OUT_PATH}\" " >> $COMMANDS
    fi;

  else
     echo -n "  *** $SRC_FILE  [NOT FLAC] : "
     if [ -f "${CONV_PATH}/${myFile}" ]; then
       echo " exist, do nothing !"
     else
       echo "  copy."
       cp "${myFile}" "${CONV_PATH}/${myFile}"
     fi
  fi

done;

echo " And now, CONVERT THE FLAC's!!! "
sh run.sh

0

Para convertir recursivamente en mp3 todos los archivos flac o wav en carpetas anidadas, utilicé este comando:

find '~/Music/' -iname '*.flac' , -iname '*.wav' -exec bash -c 'D=$(dirname "{}"); B=$(basename "{}"); mkdir "$D/mp3/"; ffmpeg -i "{}" -ab 320k -map_metadata 0 -id3v2_version 3 -acodec libmp3lame "$D/mp3/${B%.*}.mp3"' \;

Creará una carpeta llamada "mp3" dentro de la que contiene archivos flac o wav y, dentro de la carpeta mp3, guardará los archivos mp3 relativos con una tasa de bits de 320 kbps, sin mantener la antigua extensión de archivo en el nombre.


0

El nombre del archivo es "wav2mp3"

#!/bin/sh
# put the script to /usr/local/sbin
EXT_IN=$1
QUALITY=$2

if [ "${EXT_IN}" = "" -o "${QUALITY}" = "" ]; then
    printf "Usage: wav2mp3 \<in_file_ext\> \<quality\> \ne.g. wav2mp3 wav 2\n"
    exit 1
fi

#String delimeter
SAVEIFS=${IFS}
IFS='
'
# List of the files in directory lower than current to array
FILES_LIST=`find . -type f  -name "*.${EXT_IN}"`
for FILE in ${FILES_LIST}; do
    echo $FILE
    PREFIX=`echo $FILE | awk -F \. 'OFS="."{ $NF="" }1' | sed 's/.$//'`
    echo $PREFIX
    ffmpeg -i $FILE -codec:a libmp3lame -qscale:a $QUALITY $PREFIX.mp3
done

Considere usar shellcheck.net. Tiene bastantes sugerencias con respecto a su secuencia de comandos.
lema

-1

para un in * .flac

hacer OUTF =echo "$a" | sed s/\.flac$/.mp3/g

ffmpeg -i "$ a" -acodec libmp3lame "$ OUTF"

hecho


2
bienvenido a U&L, su respuesta casi no agrega nada a @Ketan aceptó la respuesta hace cuatro años.
Archemar

-2

Me doy cuenta de que esto llega bastante tarde, pero para la memoria, vea mi script "batchaudiocvt" en sourceforge. Es un script de shell (bastante grande) diseñado para la conversión masiva eficiente de archivos de audio, entre muchos formatos. En particular, hace todo lo posible para convertir las etiquetas habituales.


Esta pregunta es sobre cómo manejar el bucle en el shell. El usuario ya conoce el comando que desea usar para realizar la conversión.
G-Man dice 'reinstalar a Monica' el

Bienvenido a Stack Exchange . ¿Eres Eric Dujardin ? Si es así, sería bueno usar el formulario de contacto y seleccionar "Necesito fusionar los perfiles de usuario" para fusionar sus cuentas.
Scott

Lo siento, solo estaba tratando de ayudar con el objetivo declarado de convertir los archivos. De todos modos, el guión proporcionado puede valer la pena leerlo.
Eric Dujardin el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.