malvin noel
corrected app
0940c19
# ============================
# get_footage.py (unchanged)
# ============================
# (contenu identique à la précédente version – pas de modification)
# ============================
# edit_video.py (révision => musique optionnelle et volume paramétrable)
# ============================
"""Assemble la voix IA et, si fourni, la musique de fond.
Appel :
edit_video(
video_path="./assets/video_music/video_silent.mp4",
audio_path="./assets/audio/voice.mp3",
music_path=None, # ou chemin .mp3 / .wav
output_path="./assets/output/final_video.mp4",
music_volume=0.10, # volume musique (0‑1)
)
"""
from moviepy import VideoFileClip, AudioFileClip, CompositeAudioClip
import os
def edit_video(
video_path: str,
audio_path: str,
music_path: str | None,
output_path: str,
*,
music_volume: float = 0.10,
):
video_clip = VideoFileClip(video_path)
voice_clip = AudioFileClip(audio_path)
tracks = [voice_clip]
if music_path and os.path.isfile(music_path):
try:
music_clip = (
AudioFileClip(music_path)
.with_volume_scaled(music_volume)
.with_duration(video_clip.duration)
)
tracks.insert(0, music_clip)
except Exception as err:
print(f"⚠️ Musique ignorée : {err}")
final_audio = CompositeAudioClip(tracks).with_duration(video_clip.duration)
final_clip = video_clip.with_audio(final_audio)
final_clip.write_videofile(
output_path,
codec="libx264",
audio_codec="aac",
fps=30,
threads=4,
preset="medium",
ffmpeg_params=["-pix_fmt", "yuv420p"],
)
print(f"✅ Vidéo générée : {output_path}")
video_clip.close()
voice_clip.close()
if "music_clip" in locals():
music_clip.close()
final_audio.close()
final_clip.close()