Bash скрипт для конвертирования всех * flac в * .mp3 с помощью FFmpeg?


28

Я хочу конвертировать все * .flac в * .mp3 в определенной папке.

Это то, что я пробовал, но не работает:

# 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

Как получить мою цель?


3
ты пробовал "ДЛЯ ПЕТЛИ"?
Данила Ладнер,

@DanilaLadner Еще нет. Спасибо за подсказку.
Кевин Донг

Я написал скрипт, который делает это параллельно и копирует теги: http://tuxhelp.org/#flac-distiller

Извините, я забыл это. После преобразования имени файла в файл file.avi.mp3 вы можете использовать: переименовать «s / .avi // g» * .avi.mp3 для удаления .avi.

1
Дайте компьютеру перерыв после тяжелой работы.
МяуМоу

Ответы:


37

Попробуй это:

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

1
Он не работает с файлами, содержащими пространство. Как я могу изменить $(basename "${i/.flac}")для обработки пробелов?
имп

1
@ppr Попробуйте поместить эту строку непосредственно перед forциклом: IFS = $ '\ n'
mkc

6
Я решил проблему пространства путем изменения $(basename "${i/.flac}").mp3к "$(basename "${i/.flac}").mp3"(положить кавычки вокруг него)
MalcolmOcean

50

Простое решение с 1 вкладышем: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;

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

Обратите внимание, что это будет применяться рекурсивно в данном каталоге. Т.е. если вы запустите это из вашей папки Music, она преобразует все флаки из подпапок и выдает .mp3 рядом с ней. Вы также можете сделать это без ffmpeg, напрямую используя flac и lame (т.е. читайте w / flac, pipe to lame, выводите в файл .mp3), как показано в ссылке.


Вы можете использовать, -maxdepth 1я думаю, как в ответе X Tian, ​​чтобы ограничить рекурсивность.

2
Да, ты можешь. Вы также можете использовать ls piped для xargs или цикл for. Я просто делаю (возможно, ошибочно) предположение, что рекурсивный поиск больше соответствует тому, что нужно ОП (то есть изменяет все .flac из моей музыкальной библиотеки).
Льюис Даймонд

16
Эта команда великолепна - однако; В итоге вы получите файлы с именем * .flac.mp3. Используя вашу команду, я придумал это ...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Шейн

2
Да, как я объяснил в блоге, мне нравится этот аспект добавления .mp3, потому что он говорит мне, что эти файлы взяты из источника без потерь, который должен быть найден где-то на моем жестком диске.
Льюис Даймонд

@ Шейн комментарий работал для меня.
Чаудхри Вакас

8

Если у вас есть пробелы в именах файлов:

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

У меня есть папка со смесью mp4 и wav файлов. Как мне конвертировать их все в mp3? Спасибо.
kRazzy R

2

Я взял все, что нашел здесь (и, возможно, на некоторых других сайтах), и создал небольшой инструмент, чтобы не только рекурсивно создавать mp3-файлы flacs, но и сохранять относительные пути для их создания в другом месте с поддержкой многопоточности.

о, да, я вижу, я не использовал ffmpeg в этом случае, потому что мой OSMC не предоставлял пакеты для ffmpeg, только avconv, но, поскольку вы уже здесь, я думаю, вы знаете, это "в основном" то же самое - по крайней мере, для самой важной части. Просто замените команду "avconv" на "ffmpeg". Мои первые запуски были с бином ffmpeg и такими же параметрами.

Я ни в коем случае не хакер bash, но мне это удалось, как мой первый bashscript с заданными требованиями, и, возможно, кому-то это будет полезно. Я открыт для любых предложений с вашей стороны, но пока это работает для меня.

Мой скрипт для раскрутки 4 экземпляров, по одному на каждое ядро, выглядит так:

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

И рабочий скрипт такой:

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

который можно найти по адресу https://github.com/erdnuesse/flac-to-mp3

С уважением, Кей


добро пожаловать на борт, хороших усилий. +1
Алекс Страгис

1

Я работал над ответом @ Ketan с помощью avconv, так как ffmpeg здесь не очень хорошо работает.

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

Это преобразует flacфайлы в папке в mp3файлы и перемещает их в существующую папку «mp3». Файлы будут названы в модели "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
Выражение sed нуждается в окончании »
Хайме М.

1

GNU Parallel создан для таких задач:

# 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

Он будет запускать задания параллельно (по одному заданию на ядро ​​ЦП) и следить за тем, чтобы выходные данные на терминале не смешивались вместе.

Чтобы узнать больше, потратьте 15 минут на чтение главы 1 + 2: https://zenodo.org/record/1146014


Это выглядит интересно. Не могли бы вы объяснить, что {.}.mp3 :::делает конструкция? Или обратитесь к разделу руководства, в котором это объясняется?
jottr

0

Параллельный FTW (без сомнения, у вас есть более одного ядра - почему бы не использовать их?):

ls *flac | while read f; do ffmpeg -i "$f" -acodec libmp3lame $f.mp3 & done


0

Например, если у вас есть несколько файлов AVI:

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

0

Если это может помочь .... Я написал небольшой bash-скрипт для этого .... Вам нужно установить ffmpeg / flac.

Как это работает:

Требуется 2 аргумента:

  1. Папка вашей музыкальной библиотеки (flac / ogg / mp3 ...)
  2. Папка назначения (вам нужно создать ее раньше).

Это производит:

  • Точная копия из исходной папки в папку назначения, с:
    • файлы без flac, скопированные в.
    • файлы flac, преобразованные в mp3 (высокое качество VBR)
  • Файл run.sh с командами для преобразования файлов flac (этот скрипт выполняется автоматически).

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

Чтобы рекурсивно конвертировать в mp3 все файлы flac или wav во вложенных папках, я использовал эту команду:

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

Он создаст папку с именем «mp3» внутри папки с файлами flac или wav и внутри папки mp3 сохранит относительные mp3-файлы с битрейтом 320 кбит / с без сохранения старого расширения имени в названии.


0

Имя файла "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

Подумайте об использовании shellcheck.net. В нем довольно много предложений относительно вашего сценария.
ллоган

-1

для в * .flac

сделать OUTF =echo "$a" | sed s/\.flac$/.mp3/g

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

сделанный


2
добро пожаловать в U & L, ваш ответ вряд ли что-нибудь добавит к принятому @Ketan ответу четыре года назад.
Архемар

-2

Я понимаю, что это происходит довольно поздно, но что касается памяти, см. Мой скрипт "batchaudiocvt" на sourceforge. Это (довольно большой) сценарий оболочки, разработанный для эффективного массового преобразования аудиофайлов между многими форматами. В частности, он делает все возможное, чтобы конвертировать обычные теги.


Этот вопрос о том, как обрабатывать цикл в оболочке. Пользователь уже знает команду, которую он хочет использовать для преобразования.
G-Man говорит: «Восстановите Монику»

Добро пожаловать в Stack Exchange . Вы Эрик Дюжарден ? Если это так, было бы хорошо использовать контактную форму и выбрать «Мне нужно объединить профили пользователей», чтобы объединить ваши учетные записи.
Скотт

Извините, я просто пытался помочь с заявленной целью конвертации файлов. В любом случае, предоставленный скрипт стоит того, чтобы его прочитать.
Эрик Дюжардин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.