omarbajouk commited on
Commit
a1b5ddd
·
verified ·
1 Parent(s): d72142f

Delete src/video_utils.py

Browse files
Files changed (1) hide show
  1. src/video_utils.py +0 -125
src/video_utils.py DELETED
@@ -1,125 +0,0 @@
1
- import os
2
- import re
3
- import uuid
4
- import traceback
5
- from moviepy.editor import VideoFileClip, concatenate_videoclips
6
- import moviepy.video.fx.all as vfx
7
- from .config import OUT_DIR, W, H
8
-
9
- # ----------------------------------------------------------------------
10
- # 🔤 Fonctions utilitaires
11
- # ----------------------------------------------------------------------
12
-
13
- def safe_name(base):
14
- """Génère un nom de fichier sûr (sans caractères spéciaux)."""
15
- return re.sub(r'[^a-zA-Z0-9_-]+', '_', str(base)).strip('_')
16
-
17
- # ----------------------------------------------------------------------
18
- # 📝 Génération du fichier SRT (corrigée)
19
- # ----------------------------------------------------------------------
20
-
21
- def write_srt(text, duration, base_name=None):
22
- """
23
- Crée un fichier .srt à partir du texte et de la durée audio.
24
- Utilise un nom stable lié à la capsule plutôt qu'un UUID aléatoire.
25
- """
26
- # Nom de fichier SRT stable
27
- if base_name:
28
- srt_path = os.path.join(OUT_DIR, f"{safe_name(base_name)}.srt")
29
- else:
30
- srt_path = os.path.join(OUT_DIR, "subtitles.srt")
31
-
32
- # Contenu basique : 1 seul bloc pour tout le texte
33
- start_time = "00:00:00,000"
34
- total_seconds = int(duration)
35
- end_time = f"00:00:{total_seconds:02d},000"
36
- content = f"1\n{start_time} --> {end_time}\n{text.strip()}\n"
37
-
38
- # Écrire (en remplaçant si existe)
39
- with open(srt_path, "w", encoding="utf-8") as f:
40
- f.write(content)
41
-
42
- print(f"[SRT] ✅ Fichier SRT généré : {srt_path}")
43
- return srt_path
44
-
45
- # ----------------------------------------------------------------------
46
- # 🎬 Préparation de la vidéo présentateur
47
- # ----------------------------------------------------------------------
48
-
49
- def prepare_video_presentateur(video_path, duration, position, plein):
50
- """
51
- Charge la vidéo du présentateur, ajuste la durée et la position.
52
- """
53
- try:
54
- clip = VideoFileClip(video_path)
55
- print(f"[Video] Chargement: {video_path}")
56
- print(f"[Video] Durée vidéo: {clip.duration:.2f}s, Audio: {duration:.2f}s")
57
-
58
- # Bouclage si la vidéo est plus courte que l'audio
59
- if clip.duration < duration:
60
- loop_count = int(duration // clip.duration) + 1
61
- clip = concatenate_videoclips([clip] * loop_count)
62
- clip = clip.subclip(0, duration)
63
- print(f"[Video] Bouclage nécessaire ({clip.duration:.2f}s -> {duration:.2f}s)")
64
- else:
65
- clip = clip.subclip(0, duration)
66
-
67
- # Redimensionner si "plein" est activé
68
- if plein:
69
- clip = clip.resize(height=H)
70
- else:
71
- clip = clip.resize(height=int(H / 2))
72
-
73
- # Position
74
- pos_map = {
75
- "bottom-right": (W - clip.w - 50, H - clip.h - 50),
76
- "bottom-left": (50, H - clip.h - 50),
77
- "top-right": (W - clip.w - 50, 50),
78
- "top-left": (50, 50),
79
- "center": ("center", "center"),
80
- }
81
- clip = clip.set_position(pos_map.get(position, ("center", "center")))
82
-
83
- print(f"[Video] ✅ Vidéo préparée avec succès")
84
- return clip
85
-
86
- except Exception as e:
87
- print(f"[Video] ❌ Erreur préparation vidéo : {e}")
88
- traceback.print_exc()
89
- return None
90
-
91
- # ----------------------------------------------------------------------
92
- # 💾 Écriture vidéo finale avec fallback
93
- # ----------------------------------------------------------------------
94
-
95
- def write_video_with_fallback(final_clip, out_path_base, fps=25):
96
- """
97
- Tente d'écrire la vidéo avec MoviePy puis avec FFMPEG si échec.
98
- """
99
- out_mp4 = f"{out_path_base}.mp4"
100
- try:
101
- print(f"[Export] Rendu vidéo en cours vers : {out_mp4}")
102
- final_clip.write_videofile(
103
- out_mp4,
104
- codec="libx264",
105
- audio_codec="aac",
106
- fps=fps,
107
- threads=4,
108
- verbose=False,
109
- logger=None
110
- )
111
- print(f"[Export] ✅ Vidéo exportée : {out_mp4}")
112
- except Exception as e:
113
- print(f"[Export] ❌ Échec MoviePy ({e}), tentative FFMPEG brute…")
114
- try:
115
- final_clip.write_videofile(
116
- out_mp4,
117
- codec="libx264",
118
- audio_codec="aac",
119
- fps=fps,
120
- ffmpeg_params=["-preset", "ultrafast"]
121
- )
122
- print(f"[Export] ✅ Vidéo exportée avec fallback : {out_mp4}")
123
- except Exception as e2:
124
- print(f"[Export] ❌ FFMPEG a également échoué : {e2}")
125
- return out_mp4