Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/01/2019, à 23:33

vallo

[Résolu]Boucle pour convertir par lot des wav en mp3

Bonjour
J'essaie - mais en vain - d'écrire un script shell pour convertir plusieurs fichiers .wav en .mp3 avec ffmpeg.
Ces fichiers sont disséminés sur un gros disque utilisé par des applications musicales ou matériels (home studio).
Logique du programme :
- lancer une recherche des fichiers .wav par find avec sortie dans un fichier texte (nom avec chemin relatif;taille en octets)
- lecture en boucle du fichier obtenu avec while read ligne
- suppression de l'extension .wav pour chaque ligne et mise en variable temporaire
- ajout de l'extension .mp3 à la variable temporaire pour chaque ligne
- ffmpeg -i fichier_wav fichier_mp3

Tous les essais faits en matière d'écriture des variables (backquote, simple quote, double quote, {} ....) se soldent par un échec.

#!/bin/bash
ficout="FilesToConvert.txt" # contient chemin complet et nom des fichiers à convertir
	while read ligne
	do
		echo "ligne inscrite dans le fichier => " ${ligne} # affiche le nom du fichier complet à traiter 
	        fic=$(echo -e "$ligne\n"|cut -d';' -f1) # fichier à traiter avec son chemin complet. Le champ 2 est la taille du fichier
		echo "Nom complet du fichier à traiter => "$fic # affiche la ligne "interprétée". Tronquée aux passages 2 et 4
	        fic_supp=${fic%.*} #suppression de l'extension
		echo "Fichier à traiter sans extension => " $fic_supp
		ficmp3=${fic_supp}.mp3 # ajout de l'extension .mp3
		echo "Fichier devant normalement être obtenu =>" $ficmp3

		ffmpeg -i $fic $ficmp3
		echo "ffmpeg est fini"
		echo
	done < $ficout

Le dernier test fait sur 4 fichiers .wav situés dans le même répertoire (cf. ci-dessous) aboutit à la conversion d'1 fichier sur 2.
Le suivi des variables dans la boucle montre qu'aux second et quatrième passages, le nom du fichier pris en variable de lecture est tronqué sans que je ne m'explique pourquoi alors que les 4 fichiers sont dans le même dossier et ont donc un début de nom identique. Par suite ffmpeg ne peut convertir les fichiers lors de ces 2 passages.

Merci pour vos solutions.

Pour info le contenu du fichier test est le suivant :

./Matériel/H4N/PROJ001b/TRK2-00.wav;7276430
./Matériel/H4N/PROJ001b/TRK1-00.wav;9280910
./Matériel/H4N/PROJ001b/TRK4-00.wav;5607822
./Matériel/H4N/PROJ001b/TRK3-00.wav;4303498

Pour info, la lecture de chaque ligne dans le fichier de stockage donne pour chaque passage :
- au premier passage, ligne est bien lue => ./Matériel/H4N/PROJ001b/TRK2-00.wav;7276430
- au second passage ligne est tronquée =>  iel/H4N/PROJ001b/TRK1-00.wav;9280910
- au troisième passage, ligne est bien lue => ./Matériel/H4N/PROJ001b/TRK4-00.wav;5607822
- au quatrième passage ligne est tronquée => riel/H4N/PROJ001b/TRK3-00.wav;4303498

Dernière modification par vallo (Le 17/01/2019, à 11:33)

Hors ligne

#2 Le 15/01/2019, à 00:21

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

Complément à mon problème
Je viens de faire tourner le code décrit dans ma question en supprimant la ligne ffmpeg
A ma grande surprise, toutes les variables sont OK puisque chacune des 4 lignes du fichier de stockage est correctement lue !!!
C'est donc ffmpeg qui foire !!! Quid ???
Sortie obtenue

ligne inscrite dans le fichier =>  ./Matériel/H4N/PROJ001b/TRK2-00.wav;7276430
Nom complet du fichier à traiter =>  ./Matériel/H4N/PROJ001b/TRK2-00.wav
Fichier à traiter sans extension =>  ./Matériel/H4N/PROJ001b/TRK2-00
Fichier devant normalement être obtenu => ./Matériel/H4N/PROJ001b/TRK2-00.mp3
ffmpeg est fini

ligne inscrite dans le fichier =>  ./Matériel/H4N/PROJ001b/TRK1-00.wav;9280910
Nom complet du fichier à traiter =>  ./Matériel/H4N/PROJ001b/TRK1-00.wav
Fichier à traiter sans extension =>  ./Matériel/H4N/PROJ001b/TRK1-00
Fichier devant normalement être obtenu => ./Matériel/H4N/PROJ001b/TRK1-00.mp3
ffmpeg est fini

ligne inscrite dans le fichier =>  ./Matériel/H4N/PROJ001b/TRK4-00.wav;5607822
Nom complet du fichier à traiter =>  ./Matériel/H4N/PROJ001b/TRK4-00.wav
Fichier à traiter sans extension =>  ./Matériel/H4N/PROJ001b/TRK4-00
Fichier devant normalement être obtenu => ./Matériel/H4N/PROJ001b/TRK4-00.mp3
ffmpeg est fini

ligne inscrite dans le fichier =>  ./Matériel/H4N/PROJ001b/TRK3-00.wav;4303498
Nom complet du fichier à traiter =>  ./Matériel/H4N/PROJ001b/TRK3-00.wav
Fichier à traiter sans extension =>  ./Matériel/H4N/PROJ001b/TRK3-00
Fichier devant normalement être obtenu => ./Matériel/H4N/PROJ001b/TRK3-00.mp3
ffmpeg est fini

Dernière modification par vallo (Le 15/01/2019, à 00:25)

Hors ligne

#3 Le 15/01/2019, à 09:18

DonutMan75

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

Hello,
que renvoie la commande si tu :
1) commentes tout tes "echo"
2) remplace la ligne ffmpeg par : echo ffmpeg -i $fic $ficmp3
?

Par ailleurs, je suggère de mettre des quotes systématiquement pour protéger tes variables : $fic --> "$fic"

Bon courage pour la suite smile

Donut

Hors ligne

#4 Le 15/01/2019, à 09:50

pingouinux

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

Bonjour,
J'ai l'impression que le problème vient du fait que ffmpeg pose des questions et lit sur l'entrée standard.
Essaye ceci :

        while read -u 3 ligne
        do
.........................................................;;
        done 3< "$ficout"

Hors ligne

#5 Le 15/01/2019, à 10:16

kholo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

salut,
outre les variables à quotter,

ffmpeg -i "$fic" "$ficmp3"

le fait d'utiliser une fois du bash et une fois cut n'est pas terrible non plus :
pour rappel

maVariable="un texte avec égale (=) en séparateur=des choses et d'autres"
echo "${maVariable}
${maVariable##*=}		; après le dernier =
${maVariable#*=}		; après le premier =
${maVariable%%=*}		; avant le premier =
${maVariable%=*}		; avant le dernier =
"

un peu de lecture ?

Hors ligne

#6 Le 15/01/2019, à 10:48

pingouinux

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

Et pour simplifier l'écriture :

while read -u 3 ligne
do
    fici=${ligne%;*}
    fico=${fici/%.wav/.mp3}
    ffmpeg -i "$fici" "$fico"
    echo "ffmpeg est fini"
    echo
done 3<"$ficout"

Hors ligne

#7 Le 15/01/2019, à 11:32

kholo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

je dirais même plus :

    echo -e "ffmpeg est fini\n..."

...
ou

    ffmpeg -i "$fici" "$fico" && echo -e "${fici} compressé" || echo -e "problème avec ${fici}"

bon, tu me diras en cas de soucis, on aura un retour d'erreur de ffmpeg
donc

    ffmpeg -i "$fici" "$fico" && echo -e "${fici} compressé"

suffirait

Hors ligne

#8 Le 15/01/2019, à 12:27

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

DonutMan75 a écrit :

Hello,
que renvoie la commande si tu :
1) commentes tout tes "echo"
2) remplace la ligne ffmpeg par : echo ffmpeg -i $fic $ficmp3
?

Par ailleurs, je suggère de mettre des quotes systématiquement pour protéger tes variables : $fic --> "$fic"

Bon courage pour la suite smile

Donut

La lecture de ligne est correcte et la boucle est nickel, comme ce que j'avais obtenu en commentant la ligne ffmpeg.
J'obtiens ça

ffmpeg -i ./Matériel/H4N/PROJ001b/TRK2-00.wav ./Matériel/H4N/PROJ001b/TRK2-00.mp3
ffmpeg est fini

ffmpeg -i ./Matériel/H4N/PROJ001b/TRK1-00.wav ./Matériel/H4N/PROJ001b/TRK1-00.mp3
ffmpeg est fini

ffmpeg -i ./Matériel/H4N/PROJ001b/TRK4-00.wav ./Matériel/H4N/PROJ001b/TRK4-00.mp3
ffmpeg est fini

ffmpeg -i ./Matériel/H4N/PROJ001b/TRK3-00.wav ./Matériel/H4N/PROJ001b/TRK3-00.mp3
ffmpeg est fini

Ce qui me fait dire que c'est bien ffmpeg qui met la grouille.
Pour ce qui est de la protection des variables, comme je l'ai dit aussi, j'ai essayé avec backquote, simple quote, double quote .... et résultat toujours identique.
C'est le 2° et 4° passages qui coincent avec une lecture tronquée de la ligne dans le fichier de stockage.
Tous les essais aboutissent à une troncature toujours sur le même caractère mais différent pour la passage 2 et le passage 4.

Je vais essayer les  propositions de kholo et pingouinux

Hors ligne

#9 Le 15/01/2019, à 12:42

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

    ffmpeg -i "$fici" "$fico" && echo -e "${fici} compressé"

En mettant cette ligne, j'obtiens toujours le même résultat

Je continue à tester vos solutions

Hors ligne

#10 Le 15/01/2019, à 23:20

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

pingouinux a écrit :

Bonjour,
J'ai l'impression que le problème vient du fait que ffmpeg pose des questions et lit sur l'entrée standard.
Essaye ceci :

        while read -u 3 ligne
        do
.........................................................;;
        done 3< "$ficout"

TROP FORT pingouinux !!!
Ça marche nickel sur mes 4 fichiers.
J'ai testé une boucle incluant ces 4 fichiers + 5 autres fichiers situés dans un autre répertoire et ÇA MARCHE !

Alors maintenant, je suis obligé de compléter ma demande car j'ai trop galéré sur cette p....n de boucle while read pour ne pas comprendre la solution
- que font les options et/ou paramètres -u et 3 après le while read
- que signifie le 3 "collé" à <"$ficout" ?

Mes recherches m'ont conduit sur plusieurs sites parlant de lire et/ou écrire un fichier en utilisant des "file descriptor" pour éviter tous mélange avec l'entrée standard mais ce n'est pas trop clair pour moi qui n'avait jamais vu ni entendu parler de ce sujet.
Juste une petite synthèse ou un lien expliquant simplement le fd 3 serait super. Je suis persuadé que le sujet va intéresser ceux qui écrivent de petits scripts.
Une lecture et ses pages associées
Autre lecture

Merci encore. Je ne tarderai pas à mettre Résolu

Dernière modification par vallo (Le 16/01/2019, à 00:55)

Hors ligne

#11 Le 16/01/2019, à 01:05

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

Encore une petite question pour pingouinux
Tu proposes de simplifier mon script avec notamment cette ligne

    fico=${fici/%.wav/.mp3}

Je comprends ceci :
- par le %.wav je supprime à partir de la fin du nom de fichier les caractères .wav (donc l'extension)
- par /%.wav/.mp3 je substitue en fait .mp3 à .wav
mais ai-je bon ?

Hors ligne

#12 Le 16/01/2019, à 08:08

pingouinux

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

@vallo #10 :
fd=0 : stdin
fd=1 : stdout
fd=2 : stderr

Si tu ne précises rien pour read, il utilise stdin, ainsi que ffmpeg. Quand ce dernier pose une question et attend une réponse, il lit quelques octets sur $ficout, et le read suivant est décalé.

Pour ne pas mélanger les entrées, il suffit d'utiliser un autre fd pour le read (j'ai choisi 3, mais tu peux utiliser n'importe quel nombre supérieur à 2) :

        while read -u 3 ligne
        do
.........................................................;;
        done 3< "$ficout"

@vallo #11 : Oui

man bash -> Parameter Expansion a écrit :

       ${parameter/pattern/string}
              Pattern  substitution.  The pattern is expanded to produce a pattern just as
              in pathname expansion.  Parameter is expanded and the longest match of  pat‐
              tern  against  its value is replaced with string.  If pattern begins with /,
              all matches of pattern are replaced with string.  Normally  only  the  first
              match is replaced.  If pattern begins with #, it must match at the beginning
              of the expanded value of parameter.  If pattern begins with %, it must match
              at  the  end of the expanded value of parameter.  If string is null, matches
              of pattern are deleted and the /  following  pattern  may  be  omitted.   If
              parameter  is  @  or  *, the substitution operation is applied to each posi‐
              tional parameter in turn, and the  expansion  is  the  resultant  list.   If
              parameter  is  an  array  variable subscripted with @ or *, the substitution
              operation is applied to each member of the array in turn, and the  expansion
              is the resultant list.

Dernière modification par pingouinux (Le 16/01/2019, à 08:08)

Hors ligne

#13 Le 16/01/2019, à 08:56

vallo

Re : [Résolu]Boucle pour convertir par lot des wav en mp3

pingouinux a écrit :

fd=0 : stdin
fd=1 : stdout
fd=2 : stderr

Ça, je l'avais appris il y a bien bien longtemps, mais j'avoue que je ne souvenais pas que c'était un "file descriptor" et surtout que l'on pouvait en créer d'autres !

En fait, ne serait-il pas judicieux, dans des cas de boucles telles que la mienne, de mettre systématiquement des fd tant pour le fichier en entrée que pour celui en sortie s'il y en a un ?

A ma décharge aussi, c'est vrai aussi que l'on voit peu de scripts avec un fd >2 - en tous cas moi - et que donc, il fallait tomber sur un cas particulier pour revenir aux sources.

MERCI encore pour ce dépannage et cet éclairage.

Hors ligne