Script pour convertir des musiques

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

Je précise que je ne connais absolument pas le bash. J'ai besoin d'un script qui me converti mes musiques (ogg et flac) au format mp3. Seulement, il ne faut pas changer la hiérarchie des fichiers ni leurs tags !

J'ai commencé un petit algorithme :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ALGO DE CONVERTION
# Dans mon dossier musique, les fichiers sont triés ainsi :
#   Artiste > Album > fichier.extension
# L'algo entre dans le dossier de chaque artiste, puis de chaque album
# Il observe le format des fichiers et si besoin les convertis (en gardant le nom du     #  fichier et ses tags !!)

POUR chaque_artiste FAIRE POUR artiste:
    ENTRER DANS artiste

    POUR chaque_album FAIRE POUR album:
        ENTRER DANS album

        POUR chaque_chanson FAIRE POUR chanson:
            SI chanson.format == "flac":
                flac_vers_mp3(chanson)
            SINON SI chanson.format == "ogg":
                ogg_vers_mp3(chanson)
            SINON chanson.format == "mp3":
                ignorer()
        FIN POUR
    FIN POUR
FIN POUR

Je pensais réaliser ce programme en Bash, ce qui me parait le choix le plus logique. Seulement je ne connais absolument pas ce langage, bien qu'il ne doit pas trop différer du Python ou du Ruby (deux langages que je connais mieux). Le problème, c'est que j'ai peur de faire une bêtise et du coup de mettre le bazar dans toutes mon organisation. Et surtout pour les tags, je ne sais absolument pas comment m'y prendre…

Du coup, je me demandais si vous connaissiez un script déjà écrit, je ne dois pas être le premier à avoir besoin de ça…

Merci de votre aide !

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0

J'avais écrit un script en python, ça te permet d'avoir tous les outils python avec (en particulier si tu veux manipuler les tags). J'appelais ffmpeg pour faire les conversions des fichiers d'un dossier (des vidéos youtube téléchargées avec un autre script), qui est très simple à utiliser.

+0 -0
Auteur du sujet

Et il conservait les tags des musiques aussi ? (C'est vraiment quelque chose de super important, car au pire Rhythmbox est capable de refaire toutes la hiérarchie mais il a besoin des tags!)

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

Salut,

@Wizix : tu te compliques la vie de manière extraordinaire. ^^ Pas besoin de faire toutes ces boucles imbriquées, quelque chose comme :

1
2
3
4
5
find musique -type f -iname "*.flac" -or -iname "*.ogg" -print0 | while IFS= read -r -d $'\0' line; do
    file=$(echo -n $line | sed 's/.\(ogg\|flac\)$//')
    file="${file}.mp3"
    ffmpeg -i "$line" "$file"  
done

devrait faire l'affaire (test sur des copies avant).

Édité par adri1

I don't mind that you think slowly, but I do mind that you are publishing faster. – W. Pauli

+1 -0
Auteur du sujet

Salut à tous !

J'ai retenu la réponse de @adri1 qui est celle que je recherchais. Bon je ne la trouve pas forcément si simple et finalement les boucles imbriquées n'étaient pas si méchantes ! :p

Le problème c'est que je suis incapable de comprendre ton petit script, mais il fonctionne ! Le problème c'est qu'il bloque à un fichier :

1
Bastille/All This Bad Blood/08. Oblivion.ogg: No such file or directory

Alors que le fichier est bien là !
Aussi il faudrait pouvoir faire en sorte que le script supprime le ogg/flac après que celui-ci soit converti. Je ne sais absolument pas si ça marche mais j'ai rajouté ça :

1
2
3
4
5
6
find Musique -type f -iname "*.flac" -or -iname "*.ogg" -print0 | while IFS= read -r -d $'\0' line; do
    file=$(echo -n $line | sed 's/.\(ogg\|flac\)$//')
    file="${file}.mp3"
    ffmpeg -i "$line" "$file" -y
    rm "$line" // là!
done

Merci de votre aide!

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Salut,

Le problème c'est que je suis incapable de comprendre ton petit script, mais il fonctionne !

Wizix

Pour l'explication :

  • La commande find(1) est utilisée pour opérer des recherches au sein d'une arborescence de dossiers. Dans l'exemple, il lui est demandé de rechercher les fichiers (option -type f) dont le nom se termine, sans ternir compte des majuscules ou minuscules, par .flac ou .ogg (options -iname "*.flac" -or -iname "*.ogg") et qui sont présents dans le dossier Musique ou ses sous-dossiers.
  • Normalement, la commande find affiche chacun de ses résultats sur une ligne, mais il est possible de lui demander de séparer chaque résultat par un caractère nul à l'aide de l'option -print0 (c'est utile en cas de noms de fichier tordus, mais dans ce cas ci c'est superflu).
  • La commande read (qui est une fonction interne de bash(1)) lit par défaut une ligne depuis l'entrée standard, la scinde en plusieurs parties suivant la valeur de la variable IFS et assigne chacune d'elle aux variables spécifiées comme derniers arguments. Dans ce cas ci, la variable IFS est mise à zéro, ce qui fait que la séparation de la ligne est désactivée. Pour ce qui est des options : l'option -r précise que le caractère \ doit être traité comme tel et l'option -d $'\0' spécifie qu'une ligne est délimitée par un caractère nul et non par un caractère de fin de ligne. Enfin, chaque ligne est assignée à la variable ligne.
  • La commande sed(1) opère différentes opérations sur un flux de texte. En l'occurrence, il lui est demandé de supprimer la première suite de caractères composée de n'importe quel caractère (.) suivie des caractères ogg ou flac (\(ogg\|flac\)) si cette dernière est rencontrée à la fin d'une ligne ($). Le texte ainsi modifié (le nom d'un fichier, donc) est assigné à la variable file.
  • Le texte .mp3 est ajouté au contenu de la variable file.
  • La commande ffmpeg(1) est appelée.

En fait, le script aurait pu être écrit de manière plus légère comme suit :

1
2
3
4
find Musique -type f -name "*.flac" -or -name "*.ogg" | while read line; do
    file="${line%.*}.mp3"
    ffmpeg -i "$line" "$file"
done

La suite ${line%.*} signifie : « supprime du contenu de la variable line la pemière suite de caractères commençant par un point en débutant ta recherche par la fin ».

Le problème c'est qu'il bloque à un fichier :

1
Bastille/All This Bad Blood/08. Oblivion.ogg: No such file or directory

Alors que le fichier est bien là !

Wizix

Le nom de fichier affiché est bien le bon ? Il n'a pas subi une modifications ?

Édité par Taurre

+0 -0
Auteur du sujet

Merci je comprend un peu mieux. Mais en faite, le script ne va pas du tout. Toutes les musiques converties dans mon dossier de test ne font qu'une dizaine de secondes au format MP3 et à chaque fois qu'un fichier se fait convertir, j'ai une erreur comme quoi il n'existe pas (mais l'erreur est ignorée et passe au suivant…)

Voici ce que m'affiche la console (imaginez pour chaque fichier) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
ffmpeg version 2.4.3-1ubuntu1~trusty6 Copyright (c) 2000-2014 the FFmpeg developers
  built on Nov 22 2014 17:07:19 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --prefix=/usr --extra-version='1ubuntu1~trusty6' --build-suffix=-ffmpeg --toolchain=hardened --extra-cflags= --extra-cxxflags= --libdir=/usr/lib/x86_64-linux-gnu --shlibdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --enable-shared --disable-stripping --enable-avresample --enable-avisynth --enable-fontconfig --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-opengl --enable-x11grab --enable-libxvid --enable-libx265 --enable-libdc1394 --enable-libiec61883 --enable-libzvbi --enable-libzmq --enable-frei0r --enable-libx264 --enable-libsoxr --enable-openal --enable-libopencv
  libavutil      54.  7.100 / 54.  7.100
  libavcodec     56.  1.100 / 56.  1.100
  libavformat    56.  4.101 / 56.  4.101
  libavdevice    56.  0.100 / 56.  0.100
  libavfilter     5.  1.100 /  5.  1.100
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  0.100 /  3.  0.100
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  0.100 / 53.  0.100
Input #0, ogg, from 'Musique/Coldplay/Parachutes/04. Sparks.ogg':
  Duration: 00:03:47.08, start: 0.000000, bitrate: 144 kb/s
    Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 160 kb/s
    Metadata:
      ARTIST          : Coldplay
      ALBUM           : Parachutes
      TITLE           : Sparks
      track           : 4
      TRACKTOTAL      : 10
      disc            : 10
      MUSICBRAINZ_TRACKID: 22d49305-4e35-4a69-8638-05ac5f734065
      MUSICBRAINZ_ARTISTID: cc197bad-dc9c-440d-a5b5-d52ba2e14234
      MUSICBRAINZ_ALBUMID: 435fc965-9121-461e-b8da-d9b505c9dc9b
      DISCID          : 8909cc0a
      MUSICBRAINZ_DISCID: 6eW10RD1xgHwJJvfZng1.o0z8lE-
Output #0, mp3, to 'Musique/Coldplay/Parachutes/04. Sparks.mp3':
  Metadata:
    TSSE            : Lavf56.4.101
    Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp
    Metadata:
      ARTIST          : Coldplay
      ALBUM           : Parachutes
      TITLE           : Sparks
      track           : 4
      TRACKTOTAL      : 10
      disc            : 10
      MUSICBRAINZ_TRACKID: 22d49305-4e35-4a69-8638-05ac5f734065
      MUSICBRAINZ_ARTISTID: cc197bad-dc9c-440d-a5b5-d52ba2e14234
      MUSICBRAINZ_ALBUMID: 435fc965-9121-461e-b8da-d9b505c9dc9b
      DISCID          : 8909cc0a
      MUSICBRAINZ_DISCID: 6eW10RD1xgHwJJvfZng1.o0z8lE-
      encoder         : Lavc56.1.100 libmp3lame
Stream mapping:
  Stream #0:0 -> #0:0 (vorbis (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
size=     218kB time=00:00:13.90 bitrate= 128.3kbits/s    
video:0kB audio:218kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.101449%
ffmpeg version 2.4.3-1ubuntu1~trusty6 Copyright (c) 2000-2014 the FFmpeg developers
  built on Nov 22 2014 17:07:19 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --prefix=/usr --extra-version='1ubuntu1~trusty6' --build-suffix=-ffmpeg --toolchain=hardened --extra-cflags= --extra-cxxflags= --libdir=/usr/lib/x86_64-linux-gnu --shlibdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --enable-shared --disable-stripping --enable-avresample --enable-avisynth --enable-fontconfig --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-opengl --enable-x11grab --enable-libxvid --enable-libx265 --enable-libdc1394 --enable-libiec61883 --enable-libzvbi --enable-libzmq --enable-frei0r --enable-libx264 --enable-libsoxr --enable-openal --enable-libopencv
  libavutil      54.  7.100 / 54.  7.100
  libavcodec     56.  1.100 / 56.  1.100
  libavformat    56.  4.101 / 56.  4.101
  libavdevice    56.  0.100 / 56.  0.100
  libavfilter     5.  1.100 /  5.  1.100
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  0.100 /  3.  0.100
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  0.100 / 53.  0.100
ue/Coldplay/Parachutes/10. Everything's Not Lost _ Life Is for Living.ogg: No such file or directory
rm: impossible de supprimer «ue/Coldplay/Parachutes/10. Everything's Not Lost _ Life Is for Living.ogg»: Aucun fichier ou dossier de ce type

Par exemple ici, la chanson Sparks de Coldplay est convertie en MP3 mais ne fait que 14 secondes contre 3 minutes et quelques au format OGG ou FLAC je ne sais plus…

Et voici le script que j'utilise :

1
2
3
4
5
find Musique -type f -name "*.flac" -or -name "*.ogg" | while read line; do
    file="${line%.*}.mp3"
    ffmpeg -i "$line" "$file" -y
    rm "$line"
done

Et non les fichiers ne subissent aucunes modifications à ce que je sache, je ferme toutes mes applis et lance le script, le problème arrive quand même! Mais je me disait que c'était peut être parce que il cherche un fichier du nom de ue/Coldplay/Parachutes/10. Everything's Not Lost _ Life Is for Living.ogg alors que c'est Musique/Coldplay/Parachutes/10. Everything's Not Lost _ Life Is for Living.ogg, non ?

Merci de votre aide !

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Tout d'abord, je te conseil vivement de ne jamais placer d'instructions de suppression au sein d'un script qui est en cours d'essai. En l'occurrence, tu as de la chance que tes fichiers n'aient pas été supprimer alors que la conversion s'est mal passée. Ensuite, peux-tu me donner la sortie du script ci-dessous (si tu souhaites l'exécuter en appelant un interpréteur, utilise la commande sh -ex ton_script.sh) ?

1
2
3
4
5
6
7
#! /bin/sh -ex

find Musique -type f -name "*.flac" -or -name "*.ogg" | while read line; do
    file="${line%.*}.mp3"
    ffmpeg -loglevel warning -i "$line" -f mp3 -c:a mp3 -b:a 320k -y "$file"
    rm "$line"
done

EDIT: petite correction du script.

Édité par Taurre

+0 -0
Staff

Soit dit en passant : l'encodage MP3 donne de moins bons résultats que le Vorbis (l'encodage utilisé pour le son au sein du format Ogg), surtout lors des compressions fortes (débit inférieur ou égale à 128 kb/s). Également, le FLAC opère une compression sans pertes à l'inverse du MP3 et de Vorbis, ce qui fait qu'il est utilisé pour conserver des musiques de bonnes qualités. Enfin, garde à l'esprit qu'en convertissant de Vorbis vers MP3 tu opères une nouvelle compression sur un flux qui a déjà été compressé, ce qui réduit encore sa qualité.

Aussi, réfléchis bien avant de convertir tes fichiers vers le format MP3 parce qu'après, tu ne pourras plus faire machine arrière (sauf à récupérer tous les originaux). ;)

Édité par Taurre

+0 -0
Auteur du sujet

Alors je vais essayer de répondre à toutes tes remarques.
Pour la suppression des fichiers, j'effectues mes tests sur des fichiers mis dans un autre dossier, rien à craindre (je les copie).

Ensuite, voici le retour de ton script :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sh -ex convert.sh

+ + findread Musique line -type
 f -name *.flac -or -name *.ogg
+ file=Musique/Coldplay/Mylo Xyloto/04. Charlie Brown.mp3
+ ffmpeg -loglevel warning -i Musique/Coldplay/Mylo Xyloto/04. Charlie Brown.ogg -f mp3 -c:a mp3 -b:a 320k -y Musique/Coldplay/Mylo Xyloto/04. Charlie Brown.mp3
+ rm Musique/Coldplay/Mylo Xyloto/04. Charlie Brown.ogg
+ read line
+ file=ue/Coldplay/Mylo Xyloto/13. Don't Let It Break Your Heart.mp3
+ ffmpeg -loglevel warning -i ue/Coldplay/Mylo Xyloto/13. Don't Let It Break Your Heart.ogg -f mp3 -c:a mp3 -b:a 320k -y ue/Coldplay/Mylo Xyloto/13. Don't Let It Break Your Heart.mp3
ue/Coldplay/Mylo Xyloto/13. Don't Let It Break Your Heart.ogg: No such file or directory

Pour le format MP3, j'ai tous les originaux qui sont sur un disque dur à part et j'ai absolument de ce format actuellement ! Autrement je ne m'embêterait pas. ;)

Merci pour ton aide!

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Pour ce qui est du script, je me demande si une commande ne joue pas les trouble-fête en lisant une partie des données sur l'entrée standard. Rencontres-tu le même problème avec ce script ?

1
2
3
4
5
6
7
#! /bin/sh -ex

find Musique -type f -name "*.flac" -or -name "*.ogg" | while read line; do
    file="${line%.*}.mp3"
    ffmpeg </dev/tty -loglevel warning -i "$line" -f mp3 -c:a mp3 -b:a 320k -y "$file"
    rm "$line"
done

Note : j'ai spécifié un débit de 320 kb/s, mais libre à toi de choisir la qualité voulue.

Pour la suppression des fichiers, j'effectues mes tests sur des fichiers mis dans un autre dossier, rien à craindre (je les copie).

[…]

Pour le format MP3, j'ai tous les originaux qui sont sur un disque dur à part et j'ai absolument de ce format actuellement ! Autrement je ne m'embêterait pas. ;)

Wizix

Ok, au temps pour moi. Dans le doute, je préfère toujours le préciser, cela ne mange pas de pain. ^^

Édité par Taurre

+0 -0
Auteur du sujet

T'inquiète pas, tu fais bien de le préciser !

Alors le résultat du script est… Plutôt positif pour le moment. Voici ce que j'ai pour une musique :

1
2
3
4
+ read line
+ file=Musique/Coldplay/Mylo Xyloto/06. M.M.I.X.mp3
+ ffmpeg -loglevel warning -i Musique/Coldplay/Mylo Xyloto/06. M.M.I.X.ogg -f mp3 -c:a mp3 -b:a 320k -y Musique/Coldplay/Mylo Xyloto/06. M.M.I.X.mp3
+ rm Musique/Coldplay/Mylo Xyloto/06. M.M.I.X.ogg

Je regarde si M.M.I.X de Coldplay est bien complète… Oui elle est, 48 secondes comme l'original, par contre les autres (celle qui font environ 4 minutes) font toujours que 16 secondes :(

Merci de ton aide !

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Veux-tu dire que le script ne rencontre plus d'erreur, mais que les musiques n'ont pas la bonne durée ? Si oui, change l'option loglevel de ffmpeg de warning à debug. Ceci va te donner une sortie plus volumineuse. De celle-ci, peux-tu me donner la partie consacrée à la conversion d'une musique qui ne se passe pas correctement ? Si non, l'erreur est-elle toujours la même (fichier introuvable dû au fait qu'une partie du chemin est tronquée) ?

Édité par Taurre

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte