|
|
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 |
|
|
|
|
|
|
|
|
output_path = tempfile.mktemp(suffix='.mp3') |
|
|
|
|
|
|
|
|
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') |
|
|
|
|
|
|
|
|
cap1 = cv2.VideoCapture(video1_path) |
|
|
cap2 = cv2.VideoCapture(video2_path) |
|
|
|
|
|
|
|
|
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)) |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
if frame1.shape[0] != frame2.shape[0]: |
|
|
frame2 = cv2.resize(frame2, (width2, height)) |
|
|
|
|
|
|
|
|
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)) |
|
|
|
|
|
|
|
|
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 |
|
|
|