[tree_stream] Ajout du titre du média et du débit binaire
This commit is contained in:
parent
d31104a4f0
commit
593df4b028
@ -40,6 +40,58 @@ def couleur(nom_fichier, est_dossier):
|
|||||||
else:
|
else:
|
||||||
return nom_fichier
|
return nom_fichier
|
||||||
|
|
||||||
|
def nettoyer_tags(tags):
|
||||||
|
"""
|
||||||
|
Crée un dictionnaire normalisé à partir des tags,
|
||||||
|
en supprimant les suffixes comme '-eng', '-fre', etc.
|
||||||
|
Si plusieurs clés mènent à la même base, la première rencontrée est conservée.
|
||||||
|
"""
|
||||||
|
tags_sans_suffixes = {}
|
||||||
|
for cle, valeur in tags.items():
|
||||||
|
base = cle.split('-')[0].strip().upper()
|
||||||
|
if base not in tags_sans_suffixes:
|
||||||
|
tags_sans_suffixes[base] = valeur
|
||||||
|
return tags_sans_suffixes
|
||||||
|
|
||||||
|
def estimer_kbps(stream, probe):
|
||||||
|
"""
|
||||||
|
Estime le débit binaire (kb/s) d’un flux multimédia.
|
||||||
|
Priorité :
|
||||||
|
1. stream['bit_rate']
|
||||||
|
2. stream['stream_size'] + probe['format']['duration']
|
||||||
|
3. stream['tags']['BPS']
|
||||||
|
4. stream['tags']['NUMBER_OF_BYTES'] + stream['tags']['DURATION']
|
||||||
|
"""
|
||||||
|
tags = nettoyer_tags(stream.get('tags', {}))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Méthode 1 : bit_rate direct
|
||||||
|
if 'bit_rate' in stream:
|
||||||
|
return int(stream['bit_rate']) // 1000
|
||||||
|
|
||||||
|
# Méthode 2 : stream_size + durée globale
|
||||||
|
if 'stream_size' in stream and 'format' in probe and 'duration' in probe['format']:
|
||||||
|
taille = int(stream['stream_size'])
|
||||||
|
duree = float(probe['format']['duration'])
|
||||||
|
return int((taille * 8) / duree / 1000)
|
||||||
|
|
||||||
|
# Méthode 3 : BPS dans les tags
|
||||||
|
if 'BPS' in tags:
|
||||||
|
return int(tags['BPS']) // 1000
|
||||||
|
|
||||||
|
# Méthode 4 : NUMBER_OF_BYTES + DURATION dans les tags
|
||||||
|
if 'NUMBER_OF_BYTES' in tags and 'DURATION' in tags:
|
||||||
|
total_octets = int(tags['NUMBER_OF_BYTES'])
|
||||||
|
duree_texte = tags['DURATION'] # Format HH:MM:SS.microsec
|
||||||
|
h, m, s = duree_texte.split(':')
|
||||||
|
secondes = int(h) * 3600 + int(m) * 60 + float(s)
|
||||||
|
return int((total_octets * 8) / secondes / 1000)
|
||||||
|
|
||||||
|
except (ValueError, TypeError, ZeroDivisionError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return -1 # Si toutes les méthodes échouent
|
||||||
|
|
||||||
def analyser_fichier_video(chemin):
|
def analyser_fichier_video(chemin):
|
||||||
try:
|
try:
|
||||||
probe = ffmpeg.probe(chemin, show_chapters=None) # Contrairement à ce que l'on pourrait croire, on demande les chapitres, c'est l'option show_chapters qui ne prend pas de paramètre.
|
probe = ffmpeg.probe(chemin, show_chapters=None) # Contrairement à ce que l'on pourrait croire, on demande les chapitres, c'est l'option show_chapters qui ne prend pas de paramètre.
|
||||||
@ -69,7 +121,8 @@ def analyser_fichier_video(chemin):
|
|||||||
f"{ROUGE}{i}{NORMAL}"
|
f"{ROUGE}{i}{NORMAL}"
|
||||||
f"{BLANC}:{NORMAL} "
|
f"{BLANC}:{NORMAL} "
|
||||||
f"{BLEU}{codec_type:<8}{NORMAL} "
|
f"{BLEU}{codec_type:<8}{NORMAL} "
|
||||||
f"{BLANC}({codec_name}, {langue}){NORMAL}"
|
f"{BLANC}({codec_name:<6}, {langue:<3}){NORMAL} "
|
||||||
|
f"{ORANGE}{estimer_kbps(stream, probe):>5.0f} kb/s{NORMAL}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ajouter les flags défaut/forcé s'ils existent
|
# Ajouter les flags défaut/forcé s'ils existent
|
||||||
@ -99,7 +152,32 @@ def analyser_fichier_video(chemin):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return [f"{ROUGE}Erreur : {e}{NORMAL}"]
|
return [f"{ROUGE}Erreur : {e}{NORMAL}"]
|
||||||
|
|
||||||
|
def recuperer_titre_media(chemin):
|
||||||
|
"""
|
||||||
|
@brief Récupère le titre d'un média via ffmpeg.probe.
|
||||||
|
|
||||||
|
@param chemin Chemin vers le fichier média.
|
||||||
|
@return Le titre formaté avec couleurs et guillemets si disponible, sinon chaîne vide.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
probe = ffmpeg.probe(chemin)
|
||||||
|
titre = probe.get('format', {}).get('tags', {}).get('title', None)
|
||||||
|
if titre is not None:
|
||||||
|
return f" {VERT}\"{titre}\"{NORMAL}"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
def afficher_arborescence(dossier, prefixe="", tout_afficher=False, niveau_max=None, niveau_actuel=0):
|
def afficher_arborescence(dossier, prefixe="", tout_afficher=False, niveau_max=None, niveau_actuel=0):
|
||||||
|
"""
|
||||||
|
@brief Affiche l'arborescence d'un dossier avec détails sur les fichiers vidéo.
|
||||||
|
|
||||||
|
@param dossier Dossier à parcourir.
|
||||||
|
@param prefixe Préfixe pour l'affichage en mode arborescence.
|
||||||
|
@param tout_afficher Booléen pour afficher ou non les fichiers cachés.
|
||||||
|
@param niveau_max Profondeur maximale d'affichage (None pour illimité).
|
||||||
|
@param niveau_actuel Niveau courant de récursion (interne).
|
||||||
|
"""
|
||||||
if niveau_max is not None and niveau_actuel > niveau_max:
|
if niveau_max is not None and niveau_actuel > niveau_max:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -120,7 +198,8 @@ def afficher_arborescence(dossier, prefixe="", tout_afficher=False, niveau_max=N
|
|||||||
branche = "└── " if est_dernier else "├── "
|
branche = "└── " if est_dernier else "├── "
|
||||||
sous_prefixe = " " if est_dernier else "│ "
|
sous_prefixe = " " if est_dernier else "│ "
|
||||||
est_dossier = os.path.isdir(chemin_complet)
|
est_dossier = os.path.isdir(chemin_complet)
|
||||||
print(prefixe + branche + couleur(nom, est_dossier))
|
titre = recuperer_titre_media(chemin_complet)
|
||||||
|
print(prefixe + branche + couleur(nom, est_dossier) + titre)
|
||||||
|
|
||||||
if est_dossier:
|
if est_dossier:
|
||||||
afficher_arborescence(
|
afficher_arborescence(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user