Totaliser durée MP3 d'un dossier en bash ou équivalent
Le
Baton .rouge

Bonjour
j'ai besoin de connaitre la durée d'acoute des MP3 dans un dossier
(récursif apprécié) en ligne de commande.
Avec GUI j'en ai testé mais pas trouvé de fiable en CLI.
Merci de vos lumières
--
Les assistés du CAC 40 :
http://www.youtube.com/watch?feature=player_detailpage&v=W5Yx_diRxA8#tH
j'ai besoin de connaitre la durée d'acoute des MP3 dans un dossier
(récursif apprécié) en ligne de commande.
Avec GUI j'en ai testé mais pas trouvé de fiable en CLI.
Merci de vos lumières
--
Les assistés du CAC 40 :
http://www.youtube.com/watch?feature=player_detailpage&v=W5Yx_diRxA8#tH
fr.comp.os.linux.configuration
(
Bonjour,
C'est probablement moche, plantogène, pas compatible avec quoi que ce
soit mais ça fait le boulot attendu avec bash, sed, awk et ffmpeg.
Par contre tu auras perdu le reliquat des dixièmes et centièmes de
seconde du temps total (les dixièmes et centièmes pour chaque morceau
sont par contre bien additionnés au temps total).
Tu colles tout ça dans un script et tu l'appelles avec en paramètre le
nom du répertoire qui contient tes mp3.
Cerise sur le gateau, en le modifiant légèrement tu peux rendre ce
script plus souple de manière à ce qu'il accepte un deuxième paramètre
qui soit l'extension des fichiers (.avi, .mp4, etc, tant que le format
des fichiers récupéré par find est supporté par ffmpeg).
#/bin/sh
TOTAL=0
get_length() {
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' | sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
}
secs2time() {
SEC=$(echo $1 | awk -F "." '{print $1}')
h=$(expr $SEC / 3600)
m=$(expr $SEC % 3600 / 60)
s=$(expr $SEC % 60)
printf "%02d:%02d:%02dn" $h $m $s
}
for MP3 in $(find $1 -type f -name "*.mp3")
do
MP3_LENGTH=$(get_length $MP3)
TOTAL=$(echo $TOTAL+$MP3_LENGTH | bc -l)
done
TOTAL=$(secs2time $TOTAL)
echo "Total time fo $1: $TOTAL"
De rien
--
Mais l'ombre des plaisirs s'enfuit
Toujours plus loin vers l'inconnu.
-- H.F. Thiéfaine, La môme kaléïdoscope
Il y a ffprobe pour avoir une sortie sous une forme exploitable :
for i in Beethoven/*.ogg; ffprobe -loglevel warning -show_format -of flat $i
fr.comp.os.linux.configuration
(
Merci, je ne connaissais pas.
--
Mais l'ombre des plaisirs s'enfuit
Toujours plus loin vers l'inconnu.
-- H.F. Thiéfaine, La môme kaléïdoscope
Il y a un truc appelé soxi, de la « famille » sox, que je n'ai jamais
utilisé mais qui semble pouvoir faire l'affaire d'après le man :
soxi -Td (fichiers)
(C'est peut-être limité à certains fichiers, le man parle de « files with
a self-describing header ».)
--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
C'est mieux avé les accents (F. Patte)
Merci à vous.
Je viens aussi de trouver çà :
find -type f -name "*.mp3" -print0 | xargs -0 mplayer -vo dummy -ao
dummy -identify 2>/dev/null | perl -nle '/ID_LENGTH=([0-9.]+)/ && ($t
+=$1) && printf "%02d:%02d:%02dn",$t/3600,$t/60%60,$t%60' | tail -n 1
Je vais tester le tout pour voir lequel est le plus juste.
Pour exemple, entre les GUI, les outils windows et les script, j'avais
jusqu'à 5% d'erreur de temps. Sur 300h, c'est autrement plus gènant
que que 30mn
--
Les assistés du CAC 40 :
http://www.youtube.com/watch?feature=player_detailpage&v=W5Yx_diRxA8#tH
Avec zsh, tu pourrais écrire directement « mplayer **/*.mp3(.) ».
C'est quoi cette version de MPlayer ?
Je te conseille de mettre le printf dans un bloc END, ça t'évitera le tail
et toutes les conversions inutiles.
Mais il faut que tu aies conscience que détecter la durée d'un morceau de
musique, tout particulièrement au format MP3, n'est pas forcément précis. Si
tu as besoin de précision, tu n'échapperas pas au fait de décoder, ou au
moins parser, tous les fichiers en entier.
Dans quelques cas, il peut être intéressant d'utiliser "set $(cmd)" au
lieu des awk et head/tail.
Il bien entendu dans ce cas que l'information cherchée arrive toujours
au même rang.
En passant, j'en profite (je me posais la question sans réponse jusque
là il y a quelques mois):
Si la ligne est longue (exemple, j'essaye d'obtenir le champ
correspondant au nombre de paquets téléchargés dans /proc/net/netstat
(càd vers la fin), est-ce qu'un "set" est efficace ou vaut-il mieux
chercher une autre méthode?
Salut,
--
mireero
le 11/04/2015 à 10:11, mireero
UUOG : il n'y a pas de raison d'utiliser grep avant awk,
awk '/pattern_du_grep/{ ... }'
fait la même chose.
Ensuite, on peut tirer parti du fait qu'awk utilise atof(3) pour
convertir une chaîne de caractère en nombre, ce qui supprime la virgule
finale sans avoir à faire un sub() dans awk.
ffmpeg -i "$1" 2>&1 |
awk '/Duration: /{split($2, t, ":"); print 60 * (60 * t[1] + t[2]) + t[3]}'
Je ne comprends pas ce que tu veux faire, peux-tu donner un exemple
avec set ?
Je ne comprends pas non plus, /proc/net/netstat est multiligne, que
fais-tu avec set ?
--
Benoit Izac
le 10/04/2015 à 22:58, Nicolas George a écrit dans le message
Pas tout à fait équivalent :
% find . -type f | wc -l
162994
% ls **/*(.) | wc -l
27652
% ls **/*(.D) | wc -l
zsh: argument list too long: ls
0
% find . -type f -exec ls {} + | wc -l
162994
--
Benoit Izac
fr.comp.os.linux.configuration
(
C'est en effet _beaucoup_ plus joli.
Je me le garde dans un coin pour exemple :)
--
Mais l'ombre des plaisirs s'enfuit
Toujours plus loin vers l'inconnu.
-- H.F. Thiéfaine, La môme kaléïdoscope