You've already forked FrameTour-RenderWorker
feat(重构): 实现新的渲染服务架构
- 新增 RenderTask
This commit is contained in:
@@ -4,125 +4,66 @@ import logging
|
||||
|
||||
from telemetry import get_tracer
|
||||
from util import api, oss
|
||||
from services.template_service import DefaultTemplateService
|
||||
|
||||
TEMPLATES = {}
|
||||
logger = logging.getLogger("template")
|
||||
|
||||
def check_local_template(local_name):
|
||||
template_def = TEMPLATES[local_name]
|
||||
base_dir = template_def.get("local_path")
|
||||
for video_part in template_def.get("video_parts", []):
|
||||
source_file = video_part.get("source", "")
|
||||
if str(source_file).startswith("http"):
|
||||
# download file
|
||||
...
|
||||
elif str(source_file).startswith("PLACEHOLDER_"):
|
||||
continue
|
||||
else:
|
||||
if not os.path.isabs(source_file):
|
||||
source_file = os.path.join(base_dir, source_file)
|
||||
if not os.path.exists(source_file):
|
||||
logger.error(f"{source_file} not found, please check the template definition")
|
||||
raise Exception(f"{source_file} not found, please check the template definition")
|
||||
for audio in video_part.get("audios", []):
|
||||
if not os.path.isabs(audio):
|
||||
audio = os.path.join(base_dir, audio)
|
||||
if not os.path.exists(audio):
|
||||
logger.error(f"{audio} not found, please check the template definition")
|
||||
raise Exception(f"{audio} not found, please check the template definition")
|
||||
for lut in video_part.get("luts", []):
|
||||
if not os.path.isabs(lut):
|
||||
lut = os.path.join(base_dir, lut)
|
||||
if not os.path.exists(lut):
|
||||
logger.error(f"{lut} not found, please check the template definition")
|
||||
raise Exception(f"{lut} not found, please check the template definition")
|
||||
for mask in video_part.get("overlays", []):
|
||||
if not os.path.isabs(mask):
|
||||
mask = os.path.join(base_dir, mask)
|
||||
if not os.path.exists(mask):
|
||||
logger.error(f"{mask} not found, please check the template definition")
|
||||
raise Exception(f"{mask} not found, please check the template definition")
|
||||
# 全局模板服务实例
|
||||
_template_service = None
|
||||
|
||||
def _get_template_service():
|
||||
"""获取模板服务实例"""
|
||||
global _template_service
|
||||
if _template_service is None:
|
||||
_template_service = DefaultTemplateService()
|
||||
return _template_service
|
||||
|
||||
# 向后兼容的全局变量和函数
|
||||
TEMPLATES = {}
|
||||
|
||||
def _update_templates_dict():
|
||||
"""更新全局TEMPLATES字典以保持向后兼容"""
|
||||
service = _get_template_service()
|
||||
TEMPLATES.clear()
|
||||
TEMPLATES.update(service.templates)
|
||||
|
||||
def check_local_template(local_name):
|
||||
"""向后兼容函数"""
|
||||
service = _get_template_service()
|
||||
template_def = service.templates.get(local_name)
|
||||
if template_def:
|
||||
try:
|
||||
service.validate_template(template_def)
|
||||
except Exception as e:
|
||||
logger.error(f"Template validation failed: {e}")
|
||||
raise
|
||||
|
||||
def load_template(template_name, local_path):
|
||||
global TEMPLATES
|
||||
logger.info(f"加载视频模板定义:【{template_name}({local_path})】")
|
||||
template_def_file = os.path.join(local_path, "template.json")
|
||||
if os.path.exists(template_def_file):
|
||||
TEMPLATES[template_name] = json.load(open(template_def_file, 'rb'))
|
||||
TEMPLATES[template_name]["local_path"] = local_path
|
||||
try:
|
||||
check_local_template(template_name)
|
||||
logger.info(f"完成加载【{template_name}】模板")
|
||||
except Exception as e:
|
||||
logger.error(f"模板定义文件【{template_def_file}】有误,正在尝试重新下载模板", exc_info=e)
|
||||
download_template(template_name)
|
||||
|
||||
"""向后兼容函数"""
|
||||
service = _get_template_service()
|
||||
service._load_template(template_name, local_path)
|
||||
_update_templates_dict()
|
||||
|
||||
def load_local_template():
|
||||
for template_name in os.listdir(os.getenv("TEMPLATE_DIR")):
|
||||
if template_name.startswith("_"):
|
||||
continue
|
||||
if template_name.startswith("."):
|
||||
continue
|
||||
target_path = os.path.join(os.getenv("TEMPLATE_DIR"), template_name)
|
||||
if os.path.isdir(target_path):
|
||||
load_template(template_name, target_path)
|
||||
|
||||
"""加载本地模板(向后兼容函数)"""
|
||||
service = _get_template_service()
|
||||
service.load_local_templates()
|
||||
_update_templates_dict()
|
||||
|
||||
def get_template_def(template_id):
|
||||
if template_id not in TEMPLATES:
|
||||
download_template(template_id)
|
||||
return TEMPLATES.get(template_id)
|
||||
"""获取模板定义(向后兼容函数)"""
|
||||
service = _get_template_service()
|
||||
template = service.get_template(template_id)
|
||||
_update_templates_dict()
|
||||
return template
|
||||
|
||||
def download_template(template_id):
|
||||
tracer = get_tracer(__name__)
|
||||
with tracer.start_as_current_span("download_template"):
|
||||
template_info = api.get_template_info(template_id)
|
||||
if template_info is None:
|
||||
return
|
||||
if not os.path.isdir(template_info['local_path']):
|
||||
os.makedirs(template_info['local_path'])
|
||||
# download template assets
|
||||
overall_template = template_info['overall_template']
|
||||
video_parts = template_info['video_parts']
|
||||
def _download_assets(_template):
|
||||
if 'source' in _template:
|
||||
if str(_template['source']).startswith("http"):
|
||||
_, _fn = os.path.split(_template['source'])
|
||||
new_fp = os.path.join(template_info['local_path'], _fn)
|
||||
oss.download_from_oss(_template['source'], new_fp)
|
||||
if _fn.endswith(".mp4"):
|
||||
from util.ffmpeg import re_encode_and_annexb
|
||||
new_fp = re_encode_and_annexb(new_fp)
|
||||
_template['source'] = os.path.relpath(new_fp, template_info['local_path'])
|
||||
if 'overlays' in _template:
|
||||
for i in range(len(_template['overlays'])):
|
||||
overlay = _template['overlays'][i]
|
||||
if str(overlay).startswith("http"):
|
||||
_, _fn = os.path.split(overlay)
|
||||
oss.download_from_oss(overlay, os.path.join(template_info['local_path'], _fn))
|
||||
_template['overlays'][i] = _fn
|
||||
if 'luts' in _template:
|
||||
for i in range(len(_template['luts'])):
|
||||
lut = _template['luts'][i]
|
||||
if str(lut).startswith("http"):
|
||||
_, _fn = os.path.split(lut)
|
||||
oss.download_from_oss(lut, os.path.join(template_info['local_path'], _fn))
|
||||
_template['luts'][i] = _fn
|
||||
if 'audios' in _template:
|
||||
for i in range(len(_template['audios'])):
|
||||
if str(_template['audios'][i]).startswith("http"):
|
||||
_, _fn = os.path.split(_template['audios'][i])
|
||||
oss.download_from_oss(_template['audios'][i], os.path.join(template_info['local_path'], _fn))
|
||||
_template['audios'][i] = _fn
|
||||
_download_assets(overall_template)
|
||||
for video_part in video_parts:
|
||||
_download_assets(video_part)
|
||||
with open(os.path.join(template_info['local_path'], 'template.json'), 'w', encoding='utf-8') as f:
|
||||
json.dump(template_info, f)
|
||||
load_template(template_id, template_info['local_path'])
|
||||
|
||||
"""下载模板(向后兼容函数)"""
|
||||
service = _get_template_service()
|
||||
success = service.download_template(template_id)
|
||||
_update_templates_dict()
|
||||
return success
|
||||
|
||||
def analyze_template(template_id):
|
||||
...
|
||||
"""分析模板(占位符函数)"""
|
||||
pass
|
||||
|
Reference in New Issue
Block a user