Bash script per convertire tutto * flac in * .mp3 con FFmpeg?


28

Voglio convertire tutto * .flac in * .mp3 nella cartella specifica.

Questo è quello che ho provato, ma non funziona:

# 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

Come raggiungere il mio obiettivo?


3
hai provato "FOR LOOP"?
Danila Ladner,

@DanilaLadner Non ancora. Grazie per l'indizio.
Kevin Dong,

Ho scritto una sceneggiatura che fa questo, in parallelo, e copia i tag su: http://tuxhelp.org/#flac-distiller

Scusa se l'ho dimenticato. Dopo aver convertito il nome del file diventa file.avi.mp3 puoi usare: rinomina "s / .avi // g" * .avi.mp3 per rimuovere .avi.

1
Dare la rottura del computer dopo un duro lavoro.
MeowMeow,

Risposte:


37

Prova questo:

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

1
Non funziona con file contenenti spazio. Come posso modificare $(basename "${i/.flac}")per gestire gli spazi?
ppr

1
@ppr Prova a mettere questa riga appena prima del forciclo: IFS = $ '\ n'
mkc

6
Ho risolto il problema dello spazio cambiando $(basename "${i/.flac}").mp3in "$(basename "${i/.flac}").mp3"(inserendo delle virgolette)
MalcolmOcean

50

Una semplice soluzione da 1 liner: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;

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

Si noti che questo verrà applicato in modo ricorsivo nella directory specificata. Cioè se lo esegui dalla tua cartella Music, convertirà tutti i flac dalle sottocartelle e produrrà un .mp3 accanto ad esso. Puoi anche farlo senza ffmpeg usando direttamente flac e lame (cioè leggi w / flac, pipe to lame, output in un file .mp3), come mostrato nel link.


Puoi usare -maxdepth 1Penso come nella risposta di X Tian per limitare la ricorsività.

2
Si, puoi. Puoi anche usare ls reindirizzato su xargs o un ciclo for. Sto solo assumendo (forse sbagliato) che una ricerca ricorsiva è più lungo ciò di cui l'OP aveva bisogno (cioè cambia tutto il .flac dalla mia libreria musicale).
Lewis Diamond,

16
Questo comando è fantastico, tuttavia; Si finisce con i file chiamati * .flac.mp3. Usando il tuo comando, mi è venuto in mente questo ...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Shane,

2
Sì, come ho spiegato nel blog, mi piace questo aspetto dell'aggiunta di .mp3 perché mi dice che questo file proviene da una fonte senza perdita, che dovrebbe essere trovata da qualche parte sul mio disco rigido.
Lewis Diamond,

Il commento di @Shane ha funzionato per me.
Chaudhry Waqas,

8

Se hai alcuni spazi bianchi nei nomi dei file:

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

Ho una cartella con un misto di file mp4 e wav. Come posso convertirli tutti in mp3? Grazie.
kRazzy R,

2

Ho preso tutto quello che ho trovato qui (e forse su alcuni altri siti) e ho creato un piccolo strumento non solo per creare ricorsivamente mp3s di flacs, ma anche per preservare i percorsi relativi per crearli altrove con supporto multithread.

oh, e sì, vedo, non ho usato ffmpeg in quel caso, perché il mio OSMC non ha fornito pacchetti per ffmpeg, solo avconv, ma dato che sei già qui, immagino che tu sappia, è "sostanzialmente" il lo stesso - almeno per la parte più importante. Sostituisci semplicemente il comando "avconv" con "ffmpeg". Le mie prime corse sono state con il bin ffmpeg e le stesse opzioni esatte.

Non sono affatto un hacker bash, ma ci sono riuscito, come il mio primo bashscript con le richieste date, e forse qualcuno ne trarrà beneficio. Sono aperto a qualsiasi suggerimento da parte tua, ma finora funziona per me.

il mio script per far girare le 4 istanze, una per ogni core, è così:

#!/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"

E lo script lavoratore in questo modo:

#!/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

che puoi trovare su https://github.com/erdnuesse/flac-to-mp3

Saluti, Kay


benvenuti a bordo, ottimo sforzo. +1
Alex Stragies,

1

Ho lavorato sulla risposta di @ Ketan usando avconv, poiché ffmpeg non funziona bene qui.

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

Questo converte i flacfile in una cartella in mp3file e si sposta quindi in una cartella "mp3" esistente. I file verranno denominati nel modello "nome_originale.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
l'espressione di sed ha bisogno di un finale '
Jaime M.

1

GNU Parallel è realizzato per questo tipo di attività:

# 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

Eseguirà i lavori in parallelo (un lavoro per core della CPU) e assicurerà che l'output sul terminale non sia mischiato insieme.

Per saperne di più, passa 15 minuti a leggere il capitolo 1 + 2: https://zenodo.org/record/1146014


Questo sembra interessante. Potresti spiegare cosa fa il {.}.mp3 :::costrutto? Oppure fai riferimento alla sezione del manuale che lo spiega?
jottr


0

Ad esempio, se hai più file avi:

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

0

Se può aiutare .... Ho scritto un piccolo script bash per farlo .... Devi aver installato ffmpeg / flac.

Come funziona:

Sono necessari 2 argomenti:

  1. La cartella della tua libreria musicale (flac / ogg / mp3 ...)
  2. La cartella di destinazione (è necessario crearla prima).

Produce:

  • Una copia esatta dalla cartella di origine nella cartella di destinazione, con:
    • i file non flac copiati.
    • i file flac trasformati in mp3 (alta qualità VBR)
  • Un file run.sh con i comandi per convertire i file flac (questo script viene eseguito automaticamente).

#!/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

Per convertire ricorsivamente in mp3 tutti i file flac o wav in cartelle nidificate, ho usato questo 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"' \;

Creerà una cartella denominata "mp3" all'interno di quella con file flac o wav e, all'interno della cartella mp3, salverà i file mp3 relativi con un bitrate di 320kbps, senza mantenere la vecchia estensione nel nome.


0

Il nome del file è "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

Prendi in considerazione l'utilizzo di shellcheck.net. Ha alcuni suggerimenti per quanto riguarda la tua sceneggiatura.
Llogan

-1

per un in * .flac

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

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

fatto


2
benvenuti in U&L, la tua risposta non aggiunge quasi nulla alla risposta accettata da @Ketan quattro anni fa.
Archemar,

-2

Mi rendo conto che arriva abbastanza tardi, ma per memoria, vedi il mio script "batchaudiocvt" su sourceforge. È uno script shell (abbastanza grande) progettato per un'efficiente conversione di massa di file audio, tra molti formati. In particolare, fa del suo meglio per convertire i soliti tag.


Questa domanda riguarda come gestire il loop nella shell. L'utente conosce già il comando che desidera utilizzare per eseguire la conversione.
G-Man dice "Ripristina Monica" il

Benvenuto in Stack Exchange . Sei Eric Dujardin ? In tal caso, sarebbe utile utilizzare il modulo di contatto e selezionare '' Devo unire i profili utente '' per unire i tuoi account.
Scott,

Spiacenti, stavo solo cercando di aiutarti con l'obiettivo dichiarato di convertire i file. Comunque lo script fornito può valere la pena di essere letto.
Eric Dujardin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.