Convertir des fichiers flac en fichiers mp3
Un livre de Wikibooks.
Il faudrait la ranger dans un wikilivre où elle aurait sa place.
Sections |
[modifier] Introduction
Cette page explique comment réaliser un script Bash permettant la conversion d'un lots de fichiers au format FLAC vers le format mp3.
[modifier] Buts
- Profiter des avantages de l'écoute de nos CD préférés sur notre ordinateur avec une compression sans perte de qualité grâce au format FLAC
- Les lecteurs de formats audio compressés (autoradio, par exemple) ne supportent malheureusement que le mp3 et le wma
- Conversion des fichiers en masse, avec la propagation des tags (informations sur l'artiste, le genre, etc)
[modifier] Procédé
Les CD encodés se trouvent, par exemple, dans le répertoire:
~/musique/flac/ARTISTE/ALBUM
Le but est de retrouver la même arborescence pour nos mp3:
~/musique/mp3/ARTISTE/ALBUM
Avant la conversion, les fichiers FLAC devront êtres vérifiés (j'ai personellement eu des erreurs). Après conversion, une seconde vérification sera faite sur le fichier de sortie. Si le fichier de destination existe déjà, il sera vérifié et reconvertis s'il est défectueux. Un fichier de log est créé dans le répertoire racine des fichiers FLAC.
[modifier] Prérequis
[modifier] Le script
Le script est organisé en fonctions:
- Navigation dans les répertoires / sous répertoires de façon récursive
- Création des répertoires cibles
- Tests des fichiers
- Conversions
- Tests d'erreurs
[modifier] Attention !
Ce script écrit des données sur le disque, et n'est pas un logiciel éprouvé ! N'hésitez pas à l'analyser avant de l'exécuter. Encore mieux, créez une session de test sur votre machine. Vous voilà prévenus !
[modifier] Edition du script
- Renseigner la variable SRC_ROOT avec l'emplacement des fichiers FLAC
- Renseigner la variable DEST_ROOT pour l'emplacement des fichiers mp3
[modifier] Exécution
Il suffis d'exécuter, tout est automatisé. Il est possible de passer un autre répertoire de source FLAC en premier argument.
#!/bin/bash
# WARNING:
# This software writes to discs, it can be Dangerous !
# Use it at your own risk ! Never as root !!
# NO WARANTY, for every damage than can be encoured !
# LICENCE:
# This software is free software
# Please read the GPL Licence aviable here:
# http://www.gnu.org/copyleft/gpl.html
# AUTHORS:
# Philippe Steinmann, largement aidé par
# l'exemple tiré de http://pvanhoof.be/wiki/index.php/Converting_flac_to_mp3
# Packets requis:
# flac
# lame
# id3
# mp3check
# Repertoire source (le / de fin est important !)
SRC_ROOT="$HOME/musique/flac/"
if [ ! -z "$1" ]
then
SRC_ROOT="$1"
fi
if [ ! -e "$SRC_ROOT" ]
then
echo "$SRC_ROOT n'existe pas - abandon"
exit 1
fi
# Racine de destination (chemin absolut)
DEST_ROOT="$HOME/musique/mp3"
#DEST_ROOT="/tmp/tests_mp3"
# Format de date
DATE=$(date +%d-%m-%Y)
# Fichier de logs
LOG_FILE="$SRC_ROOT"/flac_to_mp3-$DATE.log
# Variables globales
ARTIST=''
TITLE=''
ALBUM=''
GENRE=''
TRACKNUMBER=''
FDATE=''
# Teste l'etat de $? pour connaitre l'etat de sortie de la derniere commande
# Si l'argument 1 est renseigne, le texte affiche contiendra ce qui y est passe
# Si l'argument 2 contient la chaine "QUIT", le script s'arrete en cas d'erreur
function test_err() {
if [ "$?" != "0" ]
then
if [ -z "$1" ]
then
echo "Une erreur est survenue !"
echo "Une erreur est survenue !" >> "$LOG_FILE"
if [ "$2" == "QUIT" ]
then
echo "-> Abandon !"
exit -1
fi
else
echo "Une erreur est survenue lors $1"
echo "Une erreur est survenue lors $1" >> "$LOG_FILE"
if [ "$2" == "QUIT" ]
then
echo "-> Abandon !"
exit -1
fi
fi
return 1
else
return 0
fi
}
# Cette fonction stocke les meta donnes du
# fichier flac passe en $1
# Il faut que la validité du fichier soit
# testée avant !
function get_meta_flac()
{
ARTIST=$(metaflac "$1" --show-tag=ARTIST | sed s/.*=//g)
TITLE=$(metaflac "$1" --show-tag=TITLE | sed s/.*=//g)
ALBUM=$(metaflac "$1" --show-tag=ALBUM | sed s/.*=//g)
TRACKNUMBER=$(metaflac "$1" --show-tag=TRACKNUMBER | sed s/.*=//g)
FDATE=$(metaflac "$1" --show-tag=DATE | sed s/.*=//g)
GENRE=$(metaflac "$1" --show-tag=GENRE | sed s/.*=//g)
}
# Tester la validite des fichiers flac
# du repertoire passé en $1
function test_flac()
{
local FILE
local EXT
local LEN
local ERR=0
for FILE in "$1"/*
do
# Fichiers uniquement
if [ -f "$FILE" ]
then
# On ne prend que les extentions .flac
LEN=$(echo "$FILE" | wc -m)
LEN=$(($LEN - 6))
EXT=${FILE:LEN}
if [ "$EXT" == ".flac" ]
then
echo "Test de $FILE"
flac --test -s "$FILE"
if [ "$?" != "0" ]
then
echo "renomage $FILE en $FILE.defect"
mv "$FILE" "$FILE.defect"
echo "FLAC défectueux: $FILE" >> "$LOG_FILE"
else
# On poursuit avec ce fichier
get_meta_flac "$FILE"
encode_mp3 "$FILE"
fi
fi
fi
done
}
# Cette fonction cré un repertoire portant
# le nom passé en $1, dans le rép destination
function make_dest_dir()
{
local LEN
local DEST_DIR
local REL
LEN=$(echo "$SRC_ROOT" | wc -m)
LEN=$((LEN - 1))
DEST_DIR=${1:LEN}
DEST_DIR="$DEST_ROOT"/"$DEST_DIR"
REL=${DEST_DIR::1}
if [ "$REL" != "/" ]
then
echo "Chemin relatif -> ignoré"
return 1
fi
#echo "dest: $DEST_DIR"
if [ ! -e "$DEST_DIR" ]
then
echo "creation de $DEST_DIR"
mkdir -p "$DEST_DIR"
test_err "la creation de $DEST_DIR"
fi
}
# Cette fonction encode les mp3 passe en $1
# en le placant dans les rep de estination
function encode_mp3()
{
local LEN
local DEST_FILE
local REL
# Déterminer chemin destination
LEN=$(echo "$SRC_ROOT" | wc -m)
LEN=$((LEN - 1))
DEST_FILE=${1:LEN}
DEST_FILE="$DEST_ROOT"/"$DEST_FILE"
# Changer extention
DEST_FILE=$(echo "$DEST_FILE" | sed s/\.flac/.mp3/g)
# Eviter les chemins relatifs
REL=${DEST_FILE::1}
if [ "$REL" != "/" ]
then
echo "Chemin relatif -> ignoré"
return 1
fi
# Si le fichier existe, on le véridie
if [ -f "$DEST_FILE" ]
then
echo "mp3 deja existant: $DEST_FILE"
echo "-> test $DEST_FILE"
mp3check -e -B -G "$DEST_FILE"
if [ "$?" == "0" ]
then
echo "-->valide: $DEST_FILE"
else
echo "-->invalide -> reencode $DEST_FILE"
# Encodage: je fais confiance aux presets LAME (lame --preset help)
flac -c -d "$1" | lame -h --preset standard -s 44.1 - "$DEST_FILE"
fi
else
echo "encode $DEST_FILE"
# Encodage: je fais confiance aux presets LAME (lame --preset help)
flac -c -d "$1" | lame -h --preset standard -s 44.1 - "$DEST_FILE"
if [ "$?" != "0" ]
then
echo "Erreur encodage de $DEST_FILE" >> "$LOG_FILE"
return 1
fi
fi
# id3 tags
echo "id3 tags sur $DEST_FILE"
id3 -t "$TITLE" -T "$TRACKNUMBER" -a "$ARTIST" -A "$ALBUM" -y "$FDATE" "$DEST_FILE"
# Si le genre est inconnu, id3 quitte, c'est pourquoi on sépare
id3 -g "$GENRE" "$DEST_FILE"
# Tester si l'encodage est OK
mp3check -e -B -G "$DEST_FILE"
if [ "$?" != "0" ]
then
echo "Echec encodage $DEST_FILE"
echo "Echec encodage $DEST_FILE" >> "$LOG_FILE"
fi
echo "DONE -> test $DEST_FILE"
echo ""
}
# Cette fonction sera appelee par travel_dir
# elle recevra le nom durepertoir courant en $1
# et son chemin complet en $2
function exec_in_dir()
{
make_dest_dir "$2"
test_flac "$2"
}
# Utiliser cette fonction pour descendre recursivement dans les
# repertoires
function travel_dir()
{
local DIR
local FILE
# test droit de lecture et si $1 est un repertoire
if [ -r "$1" ]
then
if [ -d "$1" ]
then
DIR="$1"
#echo "traitemnt de $DIR"
else
#echo "$1 n'est pas un repertoire"
return
fi
else
return
fi
# Ajout au tableau DIRSTACK (voir man Bash)
pushd "$DIR" > /dev/null
# Pour tout le contenu, si rep, descendre
for FILE in *
do
if test -d "$FILE" ; then
#echo "Descente dans $FILE"
travel_dir "$FILE"
fi
done
exec_in_dir "$DIR" "$PWD"
# retrait du tableau
popd > /dev/null
}
# Main
echo "" >> "$LOG_FILE"
echo "$0" >> "$LOG_FILE"
echo "Encodage flac -> mp3" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
travel_dir "$SRC_ROOT"
[modifier] Inspiration
Un article similaire, en anglais [1], notamment pour l'utilisation des outils (lame, metaflac, id3), ainsi que la technique pour accéder de manière récursive dans les sous répertoires.