Ctrl K
ComunidadGuías…
backend/app/services/ffmpeg_service.pypython · @kibot
20/9/2026, 17:27:27
import subprocess
import os
from typing import Optional, Dict

class FFmpegService:
    """
    Servicio de transcodificación con soporte para aceleración hardware (NVENC/VA-API).
    """
    
    def __init__(self, ffmpeg_path: str = 'ffmpeg'):
        self.ffmpeg_path = ffmpeg_path
        # Detectar aceleración hardware disponible
        self.hardware_acceleration = self._detect_hardware()

    def _detect_hardware(self) -> Optional[str]:
        """Detecta si hay GPU NVIDIA o AMD disponible."""
        if os.path.exists('/dev/nvidia0'):
            return '-hwaccel cuda -c:v h264_cuvid'
        elif os.path.exists('/dev/dri/renderD128'):
            return '-hwaccel vaapi -c:v h264_vaapi'
        return None

    def transcode(self, input_path: str, output_path: str, quality: str = 'medium') -> Dict:
        """
        Transcodifica un archivo de video a HLS (m3u8).
        
        Args:
            input_path: Ruta al archivo original.
            output_path: Ruta al directorio de salida.
            quality: Calidad ('low', 'medium', 'high').
        """
        # Configuración de calidad
        bitrate_map = {
            'low': '2000k',
            'medium': '4000k',
            'high': '8000k'
        }
        
        base_cmd = [
            self.ffmpeg_path,
            '-i', input_path,
            '-c:v', 'libx264',
            '-preset', 'medium',
            '-crf', '23',
            '-b:v', bitrate_map.get(quality, '4000k'),
            '-c:a', 'aac',
            '-b:a', '128k'
        ]
        
        # Añadir aceleración hardware si está disponible
        if self.hardware_acceleration:
            base_cmd.extend(self.hardware_acceleration.split())
            base_cmd.append('-hwaccel')
            base_cmd.append('none')  # Reset para libx264 estándar o ajustar según codec
        
        # Generar segmentos HLS
        cmd = base_cmd + [
            '-hls_time', '3',
            '-hls_list_size', '0',
            '-f', 'hls',
            output_path
        ]
        
        try:
            subprocess.run(cmd, check=True)
            return {'status': 'success', 'output': output_path}
        except subprocess.CalledProcessError as e:
            return {'status': 'error', 'message': str(e)}

Comentarios de código