88 lines
3.4 KiB
Python
88 lines
3.4 KiB
Python
import os
|
|
import subprocess
|
|
import re
|
|
from PyQt6.QtCore import QThread, pyqtSignal
|
|
|
|
class MediaConverter(QThread):
|
|
progress_signal = pyqtSignal(str) # Mensaje de estado
|
|
finished_signal = pyqtSignal(bool, str) # (Éxito?, Mensaje final)
|
|
|
|
def __init__(self, input_file, output_file, preset_key, bin_dir="bin"):
|
|
super().__init__()
|
|
self.input_file = input_file
|
|
self.output_file = output_file
|
|
self.preset_key = preset_key
|
|
self.bin_dir = os.path.abspath(bin_dir)
|
|
|
|
def run(self):
|
|
ffmpeg_exe = os.path.join(self.bin_dir, "ffmpeg.exe")
|
|
|
|
if not os.path.exists(ffmpeg_exe):
|
|
self.finished_signal.emit(False, "No se encontró ffmpeg.exe en la carpeta bin.")
|
|
return
|
|
|
|
if not os.path.exists(self.input_file):
|
|
self.finished_signal.emit(False, "El archivo de entrada no existe.")
|
|
return
|
|
|
|
# Configuración de argumentos según el preset
|
|
if self.preset_key == "mp4_std":
|
|
# MP4 Estándar sin reescalado
|
|
codec_args = ["-c:v", "libx264", "-c:a", "aac"]
|
|
|
|
elif self.preset_key == "mp4_1080p":
|
|
# MP4 Max 1080p Verticales (mantiene aspecto, no escala si es <= 1080)
|
|
codec_args = ["-vf", "scale=-2:'min(1080,ih)'", "-c:v", "libx264", "-c:a", "aac"]
|
|
|
|
elif self.preset_key == "mp3_192k":
|
|
# Estéreo completo a MP3 192 kbps
|
|
codec_args = ["-vn", "-c:a", "libmp3lame", "-b:a", "192k"]
|
|
|
|
elif self.preset_key == "mp3_ch1":
|
|
# Solo Canal 1 (Izquierdo / Left) -> Mono MP3 192 kbps
|
|
codec_args = ["-vn", "-af", "pan=mono|c0=c0", "-c:a", "libmp3lame", "-b:a", "192k"]
|
|
|
|
elif self.preset_key == "mp3_ch2":
|
|
# Solo Canal 2 (Derecho / Right) -> Mono MP3 192 kbps
|
|
codec_args = ["-vn", "-af", "pan=mono|c0=c1", "-c:a", "libmp3lame", "-b:a", "192k"]
|
|
|
|
else:
|
|
self.finished_signal.emit(False, "Preset no reconocido.")
|
|
return
|
|
|
|
# Sobrescribir archivo de salida si ya existe (-y)
|
|
command = [ffmpeg_exe, "-y", "-i", self.input_file] + codec_args + [self.output_file]
|
|
|
|
try:
|
|
startupinfo = None
|
|
if os.name == 'nt':
|
|
startupinfo = subprocess.STARTUPINFO()
|
|
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
|
|
|
process = subprocess.Popen(
|
|
command,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
text=True,
|
|
startupinfo=startupinfo,
|
|
encoding='utf-8',
|
|
errors='replace'
|
|
)
|
|
|
|
for line in process.stdout:
|
|
line_str = line.strip()
|
|
if line_str:
|
|
if "time=" in line_str:
|
|
match = re.search(r'time=(\d{2}:\d{2}:\d{2}\.\d{2})', line_str)
|
|
if match:
|
|
self.progress_signal.emit(f"Procesando... Tiempo: {match.group(1)}")
|
|
|
|
process.wait()
|
|
|
|
if process.returncode == 0:
|
|
self.finished_signal.emit(True, "¡Conversión completada con éxito!")
|
|
else:
|
|
self.finished_signal.emit(False, "Ocurrió un error durante la conversión con FFmpeg.")
|
|
|
|
except Exception as e:
|
|
self.finished_signal.emit(False, f"Error de ejecución: {str(e)}") |