You've already forked FrameTour-RenderWorker
feat(重构): 实现新的渲染服务架构
- 新增 RenderTask
This commit is contained in:
@@ -5,7 +5,10 @@ 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
|
||||
@@ -13,6 +16,14 @@ 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):
|
||||
@@ -130,24 +141,25 @@ def check_placeholder_exist_with_count(placeholder_id, task_params, required_cou
|
||||
|
||||
|
||||
def start_ffmpeg_task(ffmpeg_task):
|
||||
"""启动FFmpeg任务 - 使用新的渲染服务"""
|
||||
tracer = get_tracer(__name__)
|
||||
with tracer.start_as_current_span("start_ffmpeg_task") as span:
|
||||
for task in ffmpeg_task.analyze_input_render_tasks():
|
||||
result = start_ffmpeg_task(task)
|
||||
if not result:
|
||||
return False
|
||||
ffmpeg_task.correct_task_type()
|
||||
span.set_attribute("task.type", ffmpeg_task.task_type)
|
||||
span.set_attribute("task.center_cut", str(ffmpeg_task.center_cut))
|
||||
span.set_attribute("task.frame_rate", ffmpeg_task.frame_rate)
|
||||
span.set_attribute("task.resolution", str(ffmpeg_task.resolution))
|
||||
span.set_attribute("task.ext_data", json.dumps(ffmpeg_task.ext_data))
|
||||
result = ffmpeg.start_render(ffmpeg_task)
|
||||
if not result:
|
||||
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
|
||||
span.set_status(Status(StatusCode.OK))
|
||||
return True
|
||||
|
||||
|
||||
def clear_task_tmp_file(ffmpeg_task):
|
||||
@@ -166,7 +178,8 @@ def clear_task_tmp_file(ffmpeg_task):
|
||||
|
||||
|
||||
def probe_video_info(ffmpeg_task):
|
||||
# 获取视频长度宽度和时长
|
||||
return ffmpeg.probe_video_info(ffmpeg_task.get_output_file())
|
||||
"""获取视频长度宽度和时长 - 使用新的渲染服务"""
|
||||
render_service = _get_render_service()
|
||||
return render_service.get_video_info(ffmpeg_task.get_output_file())
|
||||
|
||||
|
||||
|
79
biz/task.py
79
biz/task.py
@@ -1,44 +1,55 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from opentelemetry.trace import Status, StatusCode
|
||||
|
||||
from biz.ffmpeg import parse_ffmpeg_task, start_ffmpeg_task, clear_task_tmp_file, probe_video_info, fade_out_audio
|
||||
# 使用新的服务架构
|
||||
from services import DefaultTaskService, DefaultRenderService, DefaultTemplateService
|
||||
from telemetry import get_tracer
|
||||
from template import get_template_def
|
||||
from util import api
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 创建服务实例(单例模式)
|
||||
_render_service = None
|
||||
_template_service = None
|
||||
_task_service = None
|
||||
|
||||
def _get_services():
|
||||
"""获取服务实例(懒加载)"""
|
||||
global _render_service, _template_service, _task_service
|
||||
|
||||
if _render_service is None:
|
||||
_render_service = DefaultRenderService()
|
||||
|
||||
if _template_service is None:
|
||||
_template_service = DefaultTemplateService()
|
||||
_template_service.load_local_templates() # 加载本地模板
|
||||
|
||||
if _task_service is None:
|
||||
_task_service = DefaultTaskService(_render_service, _template_service)
|
||||
|
||||
return _task_service, _render_service, _template_service
|
||||
|
||||
def start_task(task_info):
|
||||
"""启动任务处理(保持向后兼容的接口)"""
|
||||
tracer = get_tracer(__name__)
|
||||
with tracer.start_as_current_span("start_task") as span:
|
||||
task_info = api.normalize_task(task_info)
|
||||
span.set_attribute("task", json.dumps(task_info))
|
||||
span.set_attribute("scenicId", task_info.get("scenicId", "?"))
|
||||
span.set_attribute("templateId", task_info.get("templateId"))
|
||||
template_info = get_template_def(task_info.get("templateId"))
|
||||
api.report_task_start(task_info)
|
||||
ffmpeg_task = parse_ffmpeg_task(task_info, template_info)
|
||||
result = start_ffmpeg_task(ffmpeg_task)
|
||||
if not result:
|
||||
with tracer.start_as_current_span("start_task_legacy") as span:
|
||||
try:
|
||||
task_service, _, _ = _get_services()
|
||||
|
||||
# 使用新的任务服务处理
|
||||
result = task_service.process_task(task_info)
|
||||
|
||||
if result:
|
||||
span.set_status(Status(StatusCode.OK))
|
||||
logger.info("Task completed successfully: %s", task_info.get("id"))
|
||||
else:
|
||||
span.set_status(Status(StatusCode.ERROR))
|
||||
logger.error("Task failed: %s", task_info.get("id"))
|
||||
|
||||
return None # 保持原有返回值格式
|
||||
|
||||
except Exception as e:
|
||||
span.set_status(Status(StatusCode.ERROR))
|
||||
return api.report_task_failed(task_info)
|
||||
width, height, duration = probe_video_info(ffmpeg_task)
|
||||
span.set_attribute("probe.width", width)
|
||||
span.set_attribute("probe.height", height)
|
||||
span.set_attribute("probe.duration", duration)
|
||||
# 音频淡出
|
||||
new_fn = fade_out_audio(ffmpeg_task.get_output_file(), duration)
|
||||
ffmpeg_task.set_output_file(new_fn)
|
||||
oss_result = api.upload_task_file(task_info, ffmpeg_task)
|
||||
if not oss_result:
|
||||
span.set_status(Status(StatusCode.ERROR))
|
||||
return api.report_task_failed(task_info)
|
||||
# 获取视频长度宽度和时长
|
||||
clear_task_tmp_file(ffmpeg_task)
|
||||
api.report_task_success(task_info, videoInfo={
|
||||
"width": width,
|
||||
"height": height,
|
||||
"duration": duration
|
||||
})
|
||||
span.set_status(Status(StatusCode.OK))
|
||||
return None
|
||||
logger.error("Task processing failed: %s", e, exc_info=True)
|
||||
return None
|
||||
|
Reference in New Issue
Block a user