Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Totaliser durée MP3 d'un dossier en bash ou équivalent

13 réponses
Avatar
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#t=48

10 réponses

1 2
Avatar
Doug713705
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
Avatar
Nicolas George
Doug713705 , dans le message , a
é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
Avatar
Doug713705
Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(<5526fdf9$0$3319$) :

Doug713705 , dans le message , a
é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
Avatar
Lucas Levrel
Le 10 avril 2015, Doug713705 a écrit :

Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(<5526fdf9$0$3319$) :

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

Le 10 avril 2015, Doug713705 a écrit :

Le 09-04-2015, Nicolas George nous expliquait dans
fr.comp.os.linux.configuration
(<5526fdf9$0$3319$) :

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
Avatar
Nicolas George
Baton .rouge , dans le message
, a écrit :
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.
Avatar
mireero
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
Avatar
Benoit Izac
Bonjour,

le 11/04/2015 à 10:11, mireero a écrit dans le message
<5528c936$0$3172$ :

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
Avatar
Benoit Izac
Bonjour,

le 10/04/2015 à 22:58, Nicolas George a écrit dans le message
<5528397b$0$2983$ :

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
Avatar
Doug713705
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
1 2