Skrypt Bash do konwersji wszystkich * flac na * .mp3 z FFmpeg?

28

Chcę przekonwertować wszystkie pliki * .flac do * .mp3 w określonym folderze.

Oto, co próbowałem, ale nie działa:

# 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

Jak zdobyć mój cel?

Kevin Dong
źródło
3
próbowałeś „FOR LOOP”?
Danila Ladner
@DanilaLadner Jeszcze nie. Dzięki za wskazówkę.
Kevin Dong
Napisałem skrypt, który robi to równolegle i
Przepraszam, zapomniałem o tym. Po przekonwertowaniu nazwy pliku na file.avi.mp3 możesz użyć: zmień nazwę „s / .avi // g” * .avi.mp3, aby usunąć .avi.
1
Po ciężkiej pracy przerwij pracę komputera.
MeowMeow

Odpowiedzi:

37

Spróbuj tego:

for i in *.flac ; do 
    ffmpeg -i "$i" -acodec libmp3lame "$(basename "${i/.flac}")".mp3
    sleep 60
done
mkc
źródło
1
Nie działa z plikami zawierającymi przestrzeń. Jak mogę zmodyfikować, $(basename "${i/.flac}")aby obsługiwać spacje?
ppr
1
@ppr Spróbuj umieścić tę linię tuż przed forpętlą: IFS = $ '\ n'
mkc
6
Rozwiązałem problem z przestrzenią, zmieniając $(basename "${i/.flac}").mp3na "$(basename "${i/.flac}").mp3"(wstawianie cytatów)
MalcolmOcean,
50

Proste rozwiązanie 1-liniowe: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;

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

Zauważ, że zostanie to zastosowane rekurencyjnie w danym katalogu. To znaczy, jeśli uruchomisz to z folderu Music, skonwertuje wszystkie pliki flac z podfolderów i wygeneruje obok .mp3. Możesz to również zrobić bez ffmpeg, bezpośrednio używając flac i lame (tj. Czytaj w / flac, potok do lame, wyprowadzaj do pliku .mp3), jak pokazano w linku.

Lewis Diamond
źródło
Możesz użyć -maxdepth 1, jak sądzę, w odpowiedzi X Tiana, aby ograniczyć rekurencyjność.
2
Tak, możesz. Możesz także użyć ls piped do xargs lub pętli for. Po prostu przyjmuję (prawdopodobnie błędne) założenie, że wyszukiwanie rekurencyjne jest bardziej zgodne z tym, czego potrzebuje OP (tj. Zmieniam cały plik .flac z mojej biblioteki muzycznej).
Lewis Diamond
16
To polecenie jest jednak świetne; W rezultacie otrzymujesz pliki o nazwie * .flac.mp3. Korzystając z twojego polecenia, wymyśliłem to ...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Shane
2
Tak, jak wyjaśniłem na blogu, podoba mi się ten aspekt dodawania .mp3, ponieważ mówi mi, że pliki te pochodzą z bezstratnego źródła, które należy znaleźć gdzieś na moim dysku twardym.
Lewis Diamond,
Komentarz @Shane zadziałał dla mnie.
Chaudhry Waqas
8

Jeśli masz nazwy białych znaków w nazwach plików:

for a in *.flac; do
  f="${a[@]/%flac/mp3}"
  ffmpeg -i "$a" -qscale:a 0 "$f"
done
Daeseong Kim
źródło
Mam folder z mieszanką plików MP4 i WAV. Jak przekonwertować je wszystkie na mp3? Dziękuję Ci.
kRazzy R
2

Wziąłem wszystko, co tu znalazłem (i może na niektórych innych stronach) i stworzyłem małe narzędzie, które nie tylko rekursywnie tworzy pliki mp3 flacs, ale także zachowuje ścieżki względne, aby tworzyć je gdzie indziej z obsługą wielowątkowości.

och, i tak, rozumiem, nie użyłem ffmpeg w tym przypadku, ponieważ mój OSMC nie dostarczył pakietów dla ffmpeg, tylko avconv, ale skoro już tu jesteś, myślę, że wiesz, to „w zasadzie” to samo - przynajmniej dla najważniejszej części. Wystarczy zamienić polecenie „avconv” na „ffmpeg”. Moje pierwsze uruchomienia były z binem ffmpeg i dokładnie tymi samymi opcjami.

W żadnym wypadku nie jestem hakerem bashowym, ale udało mi się, jako mój pierwszy bashscript z podanymi żądaniami i być może ktoś skorzysta. Jestem otwarty na wszelkie sugestie z twojej strony, ale jak dotąd działa dla mnie.

mój skrypt rozpędzający 4 instancje, po jednym dla każdego rdzenia, wygląda następująco:

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

I skrypt roboczy taki jak ten:

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

który można znaleźć na https://github.com/erdnuesse/flac-to-mp3

Pozdrawiam Kay

Kay Urbach
źródło
witamy na pokładzie, dobry wysiłek. +1
Alex Stragies
1

Pracowałem nad odpowiedzią @ Ketan przy użyciu avconv, ponieważ ffmpeg nie działa tutaj dobrze.

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

Konwertuje to flacpliki w folderze na mp3pliki i przenosi je do istniejącego folderu „mp3”. Pliki zostaną nazwane w modelu „original_name.flac.mp3”

DanBC
źródło
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
X Tian
źródło
1
sed wyrażenie potrzebuje zakończenia ”
Jaime M.
1

GNU Parallel jest stworzony do takich zadań:

# 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

Będzie uruchamiał zadania równolegle (jedno zadanie na rdzeń procesora) i upewniał się, że dane wyjściowe na terminalu nie są pomieszane.

Aby dowiedzieć się więcej, poświęć 15 minut na przeczytanie rozdziału 1 + 2: https://zenodo.org/record/1146014

Ole Tange
źródło
To wygląda interesująco. Czy możesz wyjaśnić, na czym {.}.mp3 :::polega konstrukcja? Lub zapoznaj się z sekcją instrukcji, która to wyjaśnia?
jottr
0

Na przykład, jeśli masz wiele plików avi:

ls *.avi | xargs -I {} ffmpeg -i {} {}.mp3
K-FIVE
źródło
0

Jeśli to może pomóc ... Napisałem mały skrypt bash, aby to zrobić .... Musisz mieć zainstalowany program ffmpeg / flac.

Jak to działa:

Wymaga 2 argumentów:

  1. Folder twojej biblioteki muzycznej (flac / ogg / mp3 ...)
  2. Folder docelowy (musisz go wcześniej utworzyć).

Wytwarza:

  • Dokładna kopia z folderu źródłowego do folderu docelowego z:
    • pliki non flac skopiowane do.
    • pliki flac przekształcone na mp3 (VBR wysokiej jakości)
  • Plik run.sh z poleceniami do konwersji plików flac (ten skrypt jest wykonywany automatycznie).

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

Laurent
źródło
0

Aby rekurencyjnie przekonwertować na mp3 wszystkie pliki flac lub wav w zagnieżdżonych folderach, użyłem tego polecenia:

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"' \;

Stworzy folder o nazwie „mp3” wewnątrz tego z plikami flac lub wav, a wewnątrz folderu mp3 zapisze względne pliki mp3 o przepływności 320 kb / s, bez zachowywania starego rozszerzenia pliku w nazwie.

Riccardo Volpe
źródło
0

Nazwa pliku to „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
DenisVS
źródło
Rozważ użycie shellcheck.net. Ma sporo sugestii dotyczących twojego skryptu.
llogan
-1

dla w * .flac

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

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

gotowy

Peter McConnell
źródło
2
witamy w U&L, twoja odpowiedź prawie nie dodaje niczego do @Ketan zaakceptowanej odpowiedzi cztery lata temu.
Archemar
-2

Zdaję sobie sprawę, że to przychodzi dość późno, ale jeśli chodzi o pamięć, zobacz mój skrypt „batchaudiocvt” na sourceforge. Jest to (dość duży) skrypt powłoki przeznaczony do wydajnej masowej konwersji plików audio między wieloma formatami. W szczególności stara się konwertować zwykłe tagi.

Eric Dujardin
źródło
To pytanie dotyczy sposobu obsługi pętli w powłoce. Użytkownik już zna polecenie, którego chce użyć do konwersji.
G-Man mówi „Reinstate Monica”
Witamy w Stack Exchange . Czy jesteś Eric Dujardin ? Jeśli tak, dobrze byłoby skorzystać z formularza kontaktowego i wybrać opcję „Muszę scalić profile użytkowników”, aby połączyć konta.
Scott
Przepraszam, próbowałem tylko pomóc w osiągnięciu zamierzonego celu konwersji plików. W każdym razie dostarczony skrypt może być wart przeczytania.
Eric Dujardin,