Bash脚本使用FFmpeg将所有* flac转换为* .mp3?


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
您是否尝试过“ FOR LOOP”?
Danila Ladner 2014年

@DanilaLadner尚未。谢谢你的提示。
凯文·董

我编写了一个脚本来并行执行此操作,然后将标签复制到以下位置:http

对不起,我忘记了。转换后的文件名变为file.avi.mp3后,您可以使用:重命名“ s / .avi // g” *。avi.mp3以删除.avi。

1
辛苦工作后让计算机休息一下。
MeowMeow

Answers:


37

尝试这个:

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

1
它不适用于包含空间的文件。如何修改$(basename "${i/.flac}")以处理空格?
ppr

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

注意,这将在给定目录中递归应用。即,如果您从“音乐”文件夹运行此文件,它将转换子文件夹中的所有标记,并在其旁边生成一个.mp3。您也可以通过直接使用flac和lame(即读取w / flac,将管道传递给lame,输出到文件.mp3)来实现,而无需ffmpeg,如链接所示。


您可以-maxdepth 1在X Tian的答案中使用我认为的方法来限制递归。

2
是的你可以。您还可以使用通过管道传递给xargs的ls或for循环。我只是做出(可能是错误的)假设,即递归搜索更多地是根据OP的需要(即,从我的音乐库中更改所有.flac)。
刘易斯·戴蒙德

16
这个命令很棒-但是;您最终得到的文件名为* .flac.mp3。使用您的命令,我想到了...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Shane 2015年

2
是的,正如我在博客中所解释的,我喜欢添加.mp3的这一方面,因为它告诉我这些文件来自无损来源,应在硬盘上找到该文件。
刘易斯·戴蒙德

@Shane评论对我有用。
Chaudhry Waqas

8

如果文件名中有一些空格:

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

我有一个混合了mp4和wav文件的文件夹。如何将它们全部转换为mp3?谢谢。
kRazzy R

2

我把在这里(也许在其他一些网站上)找到的所有东西都用了,创建了一个小工具,不仅可以递归创建flac的mp3,还可以保留相对路径以在多线程支持下在其他地方创建它们。

哦,是的,我知道,在那种情况下,我没有使用ffmpeg,因为我的OSMC没有提供ffmpeg的软件包,只有avconv,但由于您已经在这里,我想您知道,这基本上是同样-至少对于最重要的部分。只需将命令“ avconv”替换为“ ffmpeg”即可。我的第一次运行是使用ffmpeg bin和完全相同的选项。

我绝不是bash黑客,但我做到了,因为我的第一个bashscript具有给定的要求,也许有人会受益。我愿意接受您的任何建议,但到目前为止它对我有用。

我的脚本启动了四个实例,每个核心一个,如下所示:

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

1

我使用avconv处理@Ketan的答案,因为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表达式需要以结尾结尾
Jaime M.

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

它将并行运行作业(每个CPU内核一个作业),并确保终端上的输出没有混合在一起。

要了解更多信息,请花15分钟阅读第1 + 2章:https : //zenodo.org/record/1146014


这看起来很有趣。您能解释一下该{.}.mp3 :::结构的作用吗?还是参考解释它的手册部分?
jottr


0

例如,如果您有多个avi文件:

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

0

如果它可以帮助...。我已经写了一个小的bash脚本来执行此操作。...您需要安装ffmpeg / flac。

怎么运行的:

它需要2个参数:

  1. 音乐库的文件夹(flac / ogg / mp3 ...)
  2. 目标文件夹(您需要先创建它)。

它产生:

  • 从源文件夹到目标文件夹的精确副本,其中包括:
    • 非flac文件复制到。
    • 将flac文件转换为mp3(VBR高品质)
  • 一个带有用于转换flac文件的命令的run.sh文件(此脚本将自动执行)。

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

它将在其中包含flac或wav文件的文件夹中创建一个名为“ mp3”的文件夹,并且在mp3文件夹中,它将以320kbps的比特率保存相对的mp3文件,而无需在名称中保留旧文件扩展名。


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。关于脚本,它有很多建议。
llogan

-1

对于* .flac

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

ffmpeg -i“ $ a” -acodec libmp3lame“ $ OUTF”

做完了


2
欢迎来到U&L,您的答案几乎没有在四年前被@Ketan接受的答案中添加任何内容。
Archemar

-2

我意识到这来得很晚,但是为了记忆起见,请参见sourceforge上的脚本“ batchaudiocvt”。它是一个(很大的)shell脚本,旨在在多种格式之间高效地批量转换音频文件。特别是,它会尽力转换常用标签。


这个问题是关于如何处理外壳中的循环的。用户已经知道他们要用来执行转换的命令。
G-Man说'Reinstate

欢迎使用Stack Exchange。你是埃里克·杜哈丁吗?如果是这样,最好使用联系表格并选择“我需要合并用户个人资料”以合并您的帐户。
斯科特,

抱歉,我只是在帮助您实现转换文件的既定目标。无论如何,提供的脚本可能值得一读。
Eric Dujardin '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.