Spaces:
Sleeping
Sleeping
File size: 3,397 Bytes
343eed9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | """
Analyseur de Structure Intelligent pour DarkMedia-X Studio.
Sépare visuels et narrations par analyse de contenu plutôt que par Regex complexes.
"""
import re
from pathlib import Path
def is_visual(line):
"""Détermine si une ligne décrit une image."""
l = line.lower()
keywords = [
'plan ', 'vue ', 'image', 'camera', 'visual', 'prompt', 'visuel',
'--ar', 'style', 'cinématique', 'gros plan', 'trajectoire',
'fond noir', 'ambiance', 'texture', 'éclairage'
]
# Si la ligne commence par un label de prompt ou contient un mot technique
return any(x in l for x in keywords) or l.startswith('- visual')
def is_narration(line):
"""Détermine si une ligne est destinée à être lue."""
l = line.lower()
# Si la ligne est entre guillemets ou commence par un label de parole
if re.match(r'^[«"„“].*[»"”]$', line.strip()): return True
labels = ['narration', "l'histoire", 'paroles', 'audio', 'texte']
return any(l.startswith(x) for x in labels)
def clean_content(text):
"""Nettoie le bruit Markdown et les labels."""
if not text: return ""
# Supprimer les labels au début (ex: "Narration :")
text = re.sub(r'^(.*?)\s*[:\-]\s*', '', text).strip()
# Supprimer les astérisques et guillemets
text = text.replace('**', '').replace('"', '').replace('«', '').replace('»', '')
return text.strip()
def normalize_content(content):
# Nettoyage global préliminaire
content = re.sub(r"Gemini said.*?\n", "", content, flags=re.DOTALL)
content = re.sub(r"\(\d+-\d+s\)", "", content)
# Découpage par scènes (##)
parts = re.split(r"(?:\n|^)##\s*", content)
intro = parts[0].strip()
new_content = intro + "\n\n" if intro else ""
for p in parts[1:]:
if not p.strip(): continue
lines = p.split('\n')
header = lines[0].strip()
body_lines = lines[1:]
visual_pool = []
narration_pool = []
for line in body_lines:
line = line.strip()
if not line or line.startswith('##'): continue
if is_visual(line):
visual_pool.append(clean_content(line))
elif is_narration(line):
narration_pool.append(clean_content(line))
else:
# Heuristique finale : si c'est court et sans ponctuation finale,
# c'est probablement du visuel, sinon de la narration.
if len(line) < 50 and not any(line.endswith(x) for x in ['.', '!', '?', '"']):
visual_pool.append(clean_content(line))
else:
narration_pool.append(clean_content(line))
# Re-synthèse propre
visual_text = " ".join(visual_pool)
narration_text = " ".join(narration_pool)
new_content += f"## {header}\n"
new_content += f"**Visual Prompt :** {visual_text}\n"
new_content += f"**Narration :** \"{narration_text}\"\n\n"
return new_content.strip()
def normalize_file(file_path):
path = Path(file_path)
if not path.exists(): return False
content = path.read_text(encoding="utf-8")
normalized = normalize_content(content)
if normalized.strip() != content.strip():
path.write_text(normalized, encoding="utf-8")
return True
return False
|