import os import tempfile from pathlib import Path import requests def text_to_speech_gtts(text, language="fr"): """ Convertit du texte en audio en utilisant gTTS (Google Text-to-Speech) Args: text (str): Le texte à convertir language (str): Code de langue (fr, en, es, etc.) Returns: str: Chemin vers le fichier audio généré """ try: from gtts import gTTS # Créer un fichier temporaire output_path = tempfile.mktemp(suffix='.mp3') # Générer l'audio tts = gTTS(text=text, lang=language, slow=False) tts.save(output_path) return output_path except ImportError: raise ImportError("gTTS n'est pas installé. Installez-le avec: pip install gTTS") except Exception as e: raise Exception(f"Erreur lors de la génération TTS: {str(e)}") def text_to_speech_elevenlabs(text, api_key, voice_id="EXAVITQu4vr4xnSDxMaL"): """ Convertit du texte en audio en utilisant ElevenLabs API Args: text (str): Le texte à convertir api_key (str): Clé API ElevenLabs voice_id (str): ID de la voix à utiliser Returns: str: Chemin vers le fichier audio généré """ try: url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}" headers = { "Accept": "audio/mpeg", "Content-Type": "application/json", "xi-api-key": api_key } data = { "text": text, "model_id": "eleven_monolingual_v1", "voice_settings": { "stability": 0.5, "similarity_boost": 0.5 } } response = requests.post(url, json=data, headers=headers) if response.status_code == 200: output_path = tempfile.mktemp(suffix='.mp3') with open(output_path, 'wb') as f: f.write(response.content) return output_path else: raise Exception(f"Erreur API ElevenLabs: {response.status_code} - {response.text}") except Exception as e: raise Exception(f"Erreur lors de la génération TTS ElevenLabs: {str(e)}") def merge_videos_side_by_side(video1_path, video2_path, output_path=None): """ Fusionne deux vidéos côte à côte Args: video1_path (str): Chemin vers la première vidéo video2_path (str): Chemin vers la deuxième vidéo output_path (str): Chemin de sortie (optionnel) Returns: str: Chemin vers la vidéo fusionnée """ import cv2 if output_path is None: output_path = tempfile.mktemp(suffix='.mp4') # Ouvrir les vidéos cap1 = cv2.VideoCapture(video1_path) cap2 = cv2.VideoCapture(video2_path) # Obtenir les propriétés fps = int(cap1.get(cv2.CAP_PROP_FPS)) height = int(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT)) width1 = int(cap1.get(cv2.CAP_PROP_FRAME_WIDTH)) width2 = int(cap2.get(cv2.CAP_PROP_FRAME_WIDTH)) # Créer le writer pour la vidéo de sortie fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width1 + width2, height)) while True: ret1, frame1 = cap1.read() ret2, frame2 = cap2.read() if not ret1 or not ret2: break # Redimensionner si nécessaire pour avoir la même hauteur if frame1.shape[0] != frame2.shape[0]: frame2 = cv2.resize(frame2, (width2, height)) # Fusionner horizontalement merged = cv2.hconcat([frame1, frame2]) out.write(merged) cap1.release() cap2.release() out.release() return output_path def get_video_duration(video_path): """ Obtient la durée d'une vidéo en secondes Args: video_path (str): Chemin vers la vidéo Returns: float: Durée en secondes """ import cv2 cap = cv2.VideoCapture(video_path) fps = cap.get(cv2.CAP_PROP_FPS) frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT) duration = frame_count / fps if fps > 0 else 0 cap.release() return duration def resize_video(input_path, output_path=None, width=None, height=None, scale=None): """ Redimensionne une vidéo Args: input_path (str): Chemin vers la vidéo source output_path (str): Chemin de sortie (optionnel) width (int): Nouvelle largeur (optionnel) height (int): Nouvelle hauteur (optionnel) scale (float): Facteur d'échelle (optionnel) Returns: str: Chemin vers la vidéo redimensionnée """ import cv2 if output_path is None: output_path = tempfile.mktemp(suffix='.mp4') cap = cv2.VideoCapture(input_path) fps = int(cap.get(cv2.CAP_PROP_FPS)) orig_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) orig_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Calculer les nouvelles dimensions if scale: width = int(orig_width * scale) height = int(orig_height * scale) elif width and not height: height = int(orig_height * (width / orig_width)) elif height and not width: width = int(orig_width * (height / orig_height)) elif not width and not height: width, height = orig_width, orig_height fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) while True: ret, frame = cap.read() if not ret: break resized = cv2.resize(frame, (width, height)) out.write(resized) cap.release() out.release() return output_path def create_solid_color_video(width, height, duration, fps, color=(0, 0, 0), output_path=None): """ Crée une vidéo d'une couleur unie Args: width (int): Largeur height (int): Hauteur duration (float): Durée en secondes fps (int): Images par seconde color (tuple): Couleur BGR (default: noir) output_path (str): Chemin de sortie (optionnel) Returns: str: Chemin vers la vidéo créée """ import cv2 import numpy as np if output_path is None: output_path = tempfile.mktemp(suffix='.mp4') fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) frame = np.full((height, width, 3), color, dtype=np.uint8) total_frames = int(duration * fps) for _ in range(total_frames): out.write(frame) out.release() return output_path