J'ai une liste de .ts
fichiers:
out1.ts ... out749.ts out8159.ts out8818.ts
Comment puis-je obtenir la durée totale (durée d'exécution) de tous ces fichiers?
shell-script
video
k961
la source
la source
Réponses:
Je n'ai pas
.ts
ici mais cela fonctionne pour.mp4
. Utilisezffprobe
(une partie deffmpeg
) pour obtenir le temps en secondes, par exemple:donc pour tous les
.mp4
fichiers du répertoire courant:puis utilisez
paste
pour passer la sortie àbc
et obtenir le temps total en secondes:Donc, pour les
.ts
fichiers, vous pouvez essayer:Un autre outil qui fonctionne pour les fichiers vidéo que j'ai ici est
exiftool
, par exemple:Longueur totale de tous les
.mp4
fichiers du répertoire courant:Vous pouvez également diriger la sortie vers une autre commande pour convertir le total en
DD:HH:MM:SS
, voir les réponses ici .Ou utilisez
exiftool
interneConvertDuration
pour cela (vous avez cependant besoin d'une version relativement récente):la source
ffprobe
avant.paste
etbc
! beaucoup plus propre qu'avecawk
disons.bc
que la précision soit arbitraire, un inconvénient est que...| paste -sd+ - | bc
cela atteindra la limite de taille de ligne dans certainesbc
implémentations (par exemple,seq 429 | paste -sd+ - | bc
échoue avec OpenSolarisbc
) ou a le potentiel d'utiliser toute la mémoire dans d'autres.avprobe
dans Arch repos (prolly car il entre en conflit avecffmpeg
) donc ne peut pas l'essayer ATM mais cela vous donne-t-il la durée du fichier si vous l'exécutez comme ceci:avprobe -show_format_entry duration myfile.mp4
ouavprobe -loglevel quiet -show_format_entry duration myfile.mp4
? Je pense que l'une de ces commandes devrait vous donner une seule ligne de sortie avec la durée du fichier. Pas sûr cependant.Cela utilise
ffmpeg
et imprime le délai d'expiration en secondes totales:Explication:
for f in *.ts; do
itère chacun des fichiers se terminant par ".ts"ffmpeg -i "$f" 2>&1
redirige la sortie vers stderrgrep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
isole le tempsawk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Convertit le temps en secondestimes+=("$_t")
ajoute les secondes à un tableauecho "${times[@]}" | sed 's/ /+/g' | bc
développe chacun des arguments et remplace les espaces et les redirige versbc
une calculatrice linux communela source
En rationalisant la réponse de @ jmunsch et en utilisant la réponse que
paste
je viens d'apprendre de @ slm , vous pourriez vous retrouver avec quelque chose comme ceci:Tout comme jmunsch l'a fait, j'utilise
ffmpeg
pour imprimer la durée, en ignorant l'erreur sur un fichier de sortie manquant et en cherchant plutôt la sortie d'erreur pour la ligne de durée. J'invoqueffmpeg
avec tous les aspects des paramètres régionaux forcés vers les paramètres régionaux C standard, de sorte que je n'ai pas à me soucier des messages de sortie localisés.Ensuite, j'utilise un single
awk
au lieu du siengrep | grep | head | tr | awk
. Cetteawk
invocation recherche la ligne (si tout va bien unique) contenantDuration:
. En utilisant deux points comme séparateur, cette étiquette est le champ 1, les heures sont le champ 2, les minutes déposées 3 et le champ des secondes 4. La virgule de fin après les secondes ne semble pas dérangerawk
, mais si quelqu'un a des problèmes là-bas, il pourrait inclure untr -d ,
dans le pipeline entreffmpeg
etawk
.Vient maintenant la partie de slm: j'utilise
paste
pour remplacer les retours à la ligne par des signes plus, mais sans affecter le retour à la ligne (contrairement à cetr \\n +
que j'avais dans une version précédente de cette réponse). Cela donne l'expression somme qui peut être alimentéebc
.Inspiré par l'idée de slm d'utiliser
date
pour gérer des formats de type temps, voici une version qui l'utilise pour formater les secondes résultantes en jours, heures, minutes et secondes avec partie fractionnaire:La partie à l'intérieur
$(…)
est exactement comme avant. En utilisant le@
caractère comme indication, nous utilisons ceci comme le nombre de secondes depuis le 1er janvier 1970. La «date» résultante est formatée en jour de l'année, heure et nanosecondes. À partir de ce jour de l'année, nous soustrayons un, car une entrée de zéro seconde mène déjà au jour 1 de cette année 1970. Je ne pense pas qu'il existe un moyen d'obtenir des comptes de jours de l'année commençant à zéro.La finale
sed
se débarrasse des zéros de fin supplémentaires. NousTZ
espérons que le paramètre forcera l'utilisation de l'UTC, afin que l'heure d'été n'interfère pas avec les très grandes collections de vidéos. Si vous avez plus d'un an de vidéo, cette approche ne fonctionnera toujours pas.la source
Je ne connais pas l'
.ts
extension, mais en supposant qu'il s'agit d'un type de fichier vidéo que vous pouvez utiliserffmpeg
pour identifier la durée d'un fichier comme ceci:Nous pouvons ensuite diviser cette sortie en sélectionnant uniquement la durée.
Alors maintenant, nous avons juste besoin d'un moyen d'itérer dans nos fichiers et de collecter ces valeurs de durée.
REMARQUE: pour mon exemple , je simplement copié mon exemple de fichier
some.mp4
et l'a nommé1.mp4
,2.mp4
et3.mp4
.Conversion des temps en secondes
L'extrait suivant prendra les durées ci-dessus et les convertira en secondes.
Cela prend nos durées et les place dans une variable
$dur
, pendant que nous parcourons les fichiers. Ladate
commande est ensuite utilisée pour calculer le nombre de secondes sinus de l'époque Unix (1970/01/01). Voici ladate
commande ci-dessus décomposée afin qu'elle soit plus facile à voir:REMARQUE: L' utilisation
Exempledate
de cette manière ne fonctionnera que si tous vos fichiers ont une durée <24 heures (soit 86400 secondes). Si vous avez besoin de quelque chose qui peut gérer de plus longues durées, vous pouvez l'utiliser comme alternative:Totalisation des temps
Nous pouvons ensuite prendre la sortie de notre
for
boucle et l'exécuter dans unepaste
commande qui incorporera des+
signes entre chaque nombre, comme ceci:Enfin, nous l'exécutons dans la calculatrice de ligne de commande,
bc
pour les résumer:Résultat: la durée totale de tous les fichiers, en secondes. Cela peut bien sûr être converti en un autre format si nécessaire.
la source
date
pourrait s'étouffer si elleffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
renvoie quelque chose comme26:33:21.68
(c'est-à-dire une durée ≥ 24 heures / 86400 secondes)paste
mon attention. Je suppose que çajava -classpath $(find -name \*.jar | paste -sd:)
va être très utile pour moi, compte tenu des hacks que j'avais utilisés pour cela dans le passé.paste
est ma commande préférée 8-)En quittant la réponse acceptée et en utilisant l'outil classique de polissage inversé UNIX:
À savoir: Appening
+
etp
puis tuyauterie dansdc
et vous aurez votre somme.la source
bc
obtient beaucoup trop d'amour. Vous mettez tous des+
signes entre chaque ligne (se rejoignant+
), alors qu'avec le polissage inversé, vous pouvez simplement jeter un a+
sur la fin et l'p
imprimer;)Assurez-vous que MPlayer est installé.
la source
Comme Ubuntu expédie libav au lieu de ffmpeg:
Fortement basé sur les idées MvG
la source
Eh bien, toutes ces solutions nécessitent un peu de travail, ce que j'ai fait était très simple, 1)
est allé dans le dossier souhaité et faites un clic droit -> ouvrir avec une autre application
Sélectionnez ensuite VLC media player,
voici un exemple
1.
2.
3.
Vous pouvez voir juste sous la barre d'outils, il y a une liste de lecture [10:35:51] écrite, donc le dossier contient 10 heures 35 minutes et 51 secondes de durée totale des vidéos
la source
J'avais des sous-répertoires sur le dossier actuel, j'ai donc dû calculer de manière récursive la durée:
find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1
la source