import json import os.path import time from concurrent.futures import ThreadPoolExecutor from opentelemetry.trace import Status, StatusCode # 使用新架构组件,保持对旧FfmpegTask的兼容 from entity.ffmpeg import FfmpegTask from entity.render_task import RenderTask, TaskType from services import DefaultRenderService import logging from util import ffmpeg, oss from util.ffmpeg import fade_out_audio from telemetry import get_tracer logger = logging.getLogger('biz/ffmpeg') _render_service = None def _get_render_service(): """获取渲染服务实例""" global _render_service if _render_service is None: _render_service = DefaultRenderService() return _render_service def parse_ffmpeg_task(task_info, template_info): """ 解析FFmpeg任务 - 保留用于向后兼容 实际处理逻辑已迁移到 services.TaskService.create_render_task """ logger.warning("parse_ffmpeg_task is deprecated, use TaskService.create_render_task instead") # 使用新的任务服务创建任务 from services import DefaultTaskService, DefaultRenderService, DefaultTemplateService render_service = DefaultRenderService() template_service = DefaultTemplateService() task_service = DefaultTaskService(render_service, template_service) # 创建新的渲染任务 render_task = task_service.create_render_task(task_info, template_info) # 为了向后兼容,创建一个FfmpegTask包装器 ffmpeg_task = FfmpegTask(render_task.input_files, output_file=render_task.output_file) ffmpeg_task.resolution = render_task.resolution ffmpeg_task.frame_rate = render_task.frame_rate ffmpeg_task.annexb = render_task.annexb ffmpeg_task.center_cut = render_task.center_cut ffmpeg_task.zoom_cut = render_task.zoom_cut ffmpeg_task.ext_data = render_task.ext_data ffmpeg_task.effects = render_task.effects ffmpeg_task.luts = render_task.luts ffmpeg_task.audios = render_task.audios ffmpeg_task.overlays = render_task.overlays return ffmpeg_task # 以下函数已迁移到新架构,保留用于向后兼容 def parse_video(source, task_params, template_info): """已迁移到 TaskService._parse_video_source""" logger.warning("parse_video is deprecated, functionality moved to TaskService") return source, {} def check_placeholder_exist(placeholder_id, task_params): """已迁移到 TaskService._check_placeholder_exist_with_count""" logger.warning("check_placeholder_exist is deprecated, functionality moved to TaskService") return placeholder_id in task_params def check_placeholder_exist_with_count(placeholder_id, task_params, required_count=1): """已迁移到 TaskService._check_placeholder_exist_with_count""" logger.warning("check_placeholder_exist_with_count is deprecated, functionality moved to TaskService") if placeholder_id in task_params: new_sources = task_params.get(placeholder_id, []) if isinstance(new_sources, list): return len(new_sources) >= required_count return required_count <= 1 return False def start_ffmpeg_task(ffmpeg_task): """启动FFmpeg任务 - 使用新的渲染服务""" tracer = get_tracer(__name__) with tracer.start_as_current_span("start_ffmpeg_task") as span: try: # 使用新的渲染服务 render_service = _get_render_service() result = render_service.render(ffmpeg_task) if result: span.set_status(Status(StatusCode.OK)) else: span.set_status(Status(StatusCode.ERROR)) return result except Exception as e: span.set_status(Status(StatusCode.ERROR)) logger.error(f"FFmpeg task failed: {e}", exc_info=True) return False def clear_task_tmp_file(ffmpeg_task): """清理临时文件 - 已迁移到 TaskService._cleanup_temp_files""" logger.warning("clear_task_tmp_file is deprecated, functionality moved to TaskService") try: template_dir = os.getenv("TEMPLATE_DIR", "") output_file = ffmpeg_task.get_output_file() if template_dir and template_dir not in output_file: if os.path.exists(output_file): os.remove(output_file) logger.info("Cleaned up temp file: %s", output_file) else: logger.info("Skipped cleanup of template file: %s", output_file) return True except OSError as e: logger.warning("Failed to cleanup temp file %s: %s", output_file, e) return False def probe_video_info(ffmpeg_task): """获取视频长度宽度和时长 - 使用新的渲染服务""" render_service = _get_render_service() return render_service.get_video_info(ffmpeg_task.get_output_file())