Script Bash para converter todos * flac em * .mp3 com FFmpeg?


28

Quero converter todos os arquivos * .flac em * .mp3 na pasta específica.

Isto é o que eu tentei, mas não 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

Como conseguir meu objetivo?


3
você tentou "FOR LOOP"?
Danila Ladner

@DanilaLadner Ainda não. Obrigado pela pista.
Kevin Dong

Eu escrevi um script que faz isso em paralelo e copia as tags: http://tuxhelp.org/#flac-distiller

Desculpe, eu esqueci. Depois que o nome do arquivo de conversão se tornar file.avi.mp3, você poderá usar: renomear "s / .avi // g" * .avi.mp3 para remover .avi.

11
Dê uma pausa no computador após um trabalho árduo.
MeowMeow

Respostas:


37

Tente o seguinte:

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

11
Não está funcionando com arquivos que contêm espaço. Como posso modificar $(basename "${i/.flac}")para lidar com espaços?
ppr

11
@ppr Tente colocar esta linha imediatamente antes do forloop: IFS = $ '\ n'
mkc

6
Resolvi o problema de espaço mudando $(basename "${i/.flac}").mp3para "$(basename "${i/.flac}").mp3"(colocando aspas)
MalcolmOcean

50

Uma solução simples de 1 liner: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;

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

Observe que isso será aplicado recursivamente no diretório fornecido. Ou seja, se você executar isso na sua pasta Música, ele converterá todos os flacs das subpastas e produzirá um .mp3 ao lado. Você também pode fazê-lo sem o ffmpeg usando diretamente flac e lame (ou seja, leia w / flac, pipe to lame, faça a saída para um arquivo .mp3), conforme mostrado no link.


Você pode usar o -maxdepth 1que penso na resposta de X Tian para limitar a recursividade.

2
Sim você pode. Você também pode usar ls canalizado para xargs ou um loop for. Estou apenas assumindo (possivelmente errado) que uma pesquisa recursiva é mais do que o OP precisava (ou seja, mude todo o .flac da minha biblioteca de músicas).
Lewis Diamond

16
Este comando é ótimo - no entanto; Você acaba com os arquivos chamados * .flac.mp3. Usando o seu comando, eu vim com isso ...find -name "*.flac" -exec bash -c 'ffmpeg -i "{}" -y -acodec libmp3lame -ab 128k "${0/.flac}.mp3"' {} \;
Shane

2
Sim, como expliquei no blog, eu gosto desse aspecto de adicionar o .mp3 porque ele me diz que esses arquivos vêm de uma fonte sem perdas, que deve ser encontrada em algum lugar do meu disco rígido.
Lewis Diamond

O comentário do @Shane funcionou para mim.
Chaudhry Waqas 19/02

8

Se você tiver alguns espaços em branco nos nomes dos arquivos:

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

Eu tenho uma pasta com uma mistura de arquivos mp4 e wav. Como faço para converter todos eles em mp3? Obrigado.
Krazzy R

2

Peguei tudo o que encontrei aqui (e talvez em alguns outros sites) e criei uma pequena ferramenta para não apenas criar mp3s de flacs recursivamente, mas também preservar caminhos relativos para criá-los em outros lugares com suporte a multithread.

ah, e sim, entendi, eu não usei ffmpeg nesse caso, porque meu OSMC não forneceu pacotes para ffmpeg, apenas avconv, mas como você já está aqui, acho que sabe, é "basicamente" o mesmo - pelo menos para a parte mais importante. Apenas substitua o comando "avconv" por "ffmpeg". Minhas primeiras execuções foram com a caixa ffmpeg e as mesmas opções.

Eu não sou um hacker do bash, mas o gerenciei como meu primeiro bashscript com as demandas fornecidas, e talvez alguém se beneficie. Estou aberto a sugestões do seu lado, mas até agora funciona para mim.

meu script para girar as 4 instâncias, uma para cada núcleo, é assim:

#!/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 o script de trabalho 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 pode ser encontrado em https://github.com/erdnuesse/flac-to-mp3

Atenciosamente, Kay


bem-vindo a bordo, bom esforço. +1
Alex Stragies

1

Eu trabalhei na resposta do @ Ketan usando avconv, pois o ffmpeg não funciona bem por aqui.

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

Isso converte flacarquivos em uma pasta em mp3arquivos e move-os para uma pasta "mp3" existente. Os arquivos serão nomeados no 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

11
A expressão sed precisa de um final ''
Jaime M.

1

O GNU Parallel é feito para este tipo de tarefas:

# 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

Ele executará os trabalhos em paralelo (um trabalho por núcleo da CPU) e verifique se a saída no terminal não está misturada.

Para saber mais, passe 15 minutos lendo o capítulo 1 + 2: https://zenodo.org/record/1146014


Isso parece interessante. Você poderia explicar o que a {.}.mp3 :::construção faz? Ou consulte a seção do manual que explica isso?
jottr 29/11


0

Por exemplo, se você tiver vários arquivos avi:

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

0

Se puder ajudar ... Escrevi um pequeno script bash para fazer isso ... Você precisa ter o ffmpeg / flac instalado.

Como funciona:

São necessários 2 argumentos:

  1. A pasta da sua biblioteca de músicas (flac / ogg / mp3 ...)
  2. A pasta de destino (você precisa criá-la antes).

Produz:

  • Uma cópia exata da pasta de origem na pasta de destino, com:
    • os arquivos não flac copiados para.
    • os arquivos flac transformados em mp3 (VBR de alta qualidade)
  • Um arquivo run.sh com os comandos para converter os arquivos flac (esse script é executado 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

Para converter recursivamente em mp3 todos os arquivos flac ou wav em pastas aninhadas, usei 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"' \;

Ele criará uma pasta chamada "mp3" dentro da pasta com arquivos flac ou wav e, dentro da pasta mp3, salvará os arquivos mp3 relativos com uma taxa de bits de 320kbps, sem manter a extensão antiga do arquivo no nome.


0

O nome do arquivo é "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. Tem algumas sugestões sobre o seu script.
llogan 29/03

-1

para um in * .flac

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

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

feito


2
bem-vindo à U&L, sua resposta dificilmente adiciona algo à resposta aceita pelo @Ketan há quatro anos.
Archemar

-2

Sei que isso chega muito tarde, mas, para memória, veja meu script "batchaudiocvt" no sourceforge. É um script de shell (bastante grande) projetado para conversão em massa eficiente de arquivos de áudio, entre muitos formatos. Em particular, faz o possível para converter as tags comuns.


Esta pergunta é sobre como lidar com o loop no shell. O usuário já conhece o comando que deseja usar para fazer a conversão.
G-Man diz 'Reinstate Monica'

Bem-vindo ao Stack Exchange . Você é Eric Dujardin ? Nesse caso, seria bom usar o formulário de contato e selecionar '' Preciso mesclar perfis de usuário '' para mesclar suas contas.
Scott

Desculpe, eu estava apenas tentando ajudar com o objetivo declarado de converter os arquivos. De qualquer forma, o script fornecido pode valer a pena ser lido.
Eric Dujardin
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.