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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Doug713705
Le #26348485
Le 09-04-2015, Baton rouge nous expliquait dans
fr.comp.os.linux.configuration
(
Bonjour



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.



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"

Merci de vos lumières



De rien

--
Mais l'ombre des plaisirs s'enfuit
Toujours plus loin vers l'inconnu.
-- H.F. Thiéfaine, La môme kaléïdoscope
Nicolas George
Le #26348487
Doug713705 , dans le message écrit :
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' | sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'



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
Doug713705
Le #26348501
Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(
Doug713705 , dans le message écrit :
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' | sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'



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



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
Lucas Levrel
Le #26348530
Le 10 avril 2015, Doug713705 a écrit :

Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(
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



Merci, je ne connaissais pas.



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)
Baton .rouge
Le #26348582
On Fri, 10 Apr 2015 10:28:45 +0200, Lucas Levrel

Le 10 avril 2015, Doug713705 a écrit :

Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(
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



Merci, je ne connaissais pas.



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 ».)




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
Nicolas George
Le #26348611
Baton .rouge , dans le message
find -type f -name "*.mp3" -print0 | xargs -0



Avec zsh, tu pourrais écrire directement « mplayer **/*.mp3(.) ».

mplayer -vo dummy -ao dummy



C'est quoi cette version de MPlayer ?

-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 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.
mireero
Le #26348638
On 04/10/2015 12:20 AM, Doug713705 wrote:
get_length() {
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' | sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
}



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
Benoit Izac
Le #26348652
Bonjour,

le 11/04/2015 à 10:11, mireero
get_length() {
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' |
sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
}





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]}'

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.



Je ne comprends pas ce que tu veux faire, peux-tu donner un exemple
avec set ?

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?



Je ne comprends pas non plus, /proc/net/netstat est multiligne, que
fais-tu avec set ?

--
Benoit Izac
Benoit Izac
Le #26348657
Bonjour,

le 10/04/2015 à 22:58, Nicolas George a écrit dans le message

find -type f -name "*.mp3" -print0 | xargs -0



Avec zsh, tu pourrais écrire directement « mplayer **/*.mp3(.) ».



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
Doug713705
Le #26348655
Le 11-04-2015, Benoit Izac nous expliquait dans
fr.comp.os.linux.configuration
(
get_length() {
ffmpeg -i $1 2>&1 | grep Duration | awk -F " " '{print $2}' |
sed s/,// | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
}





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]}'



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
Publicité
Poster une réponse
Anonyme