diff --git a/domain/task.py b/domain/task.py index b23134c..7cac821 100644 --- a/domain/task.py +++ b/domain/task.py @@ -350,9 +350,25 @@ class Task: return int(self.payload.get('durationMs', 5000)) def get_material_url(self) -> Optional[str]: - """获取素材 URL""" + """ + 获取素材 URL + + 优先使用 boundMaterialUrl(实际可下载的 HTTP URL), + 如果不存在则回退到 sourceRef(可能是 slot 引用)。 + + Returns: + 素材 URL,如果都不存在返回 None + """ return self.payload.get('boundMaterialUrl') or self.payload.get('sourceRef') + def get_source_ref(self) -> Optional[str]: + """获取素材源引用(slot 标识符,如 device:xxx)""" + return self.payload.get('sourceRef') + + def get_bound_material_url(self) -> Optional[str]: + """获取绑定的素材 URL(实际可下载的 HTTP URL)""" + return self.payload.get('boundMaterialUrl') + def get_render_spec(self) -> RenderSpec: """获取渲染规格""" return RenderSpec.from_dict(self.payload.get('renderSpec')) diff --git a/handlers/render_video.py b/handlers/render_video.py index acc4e98..de3dd98 100644 --- a/handlers/render_video.py +++ b/handlers/render_video.py @@ -46,6 +46,21 @@ class RenderSegmentVideoHandler(BaseHandler): "Missing material URL (boundMaterialUrl or sourceRef)" ) + # 检查 URL 格式:必须是 HTTP/HTTPS 协议 + if not material_url.startswith(('http://', 'https://')): + source_ref = task.get_source_ref() + bound_url = task.get_bound_material_url() + logger.error( + f"[task:{task.task_id}] Invalid material URL format: '{material_url}'. " + f"boundMaterialUrl={bound_url}, sourceRef={source_ref}. " + f"Server should provide boundMaterialUrl with HTTP URL." + ) + return TaskResult.fail( + ErrorCode.E_SPEC_INVALID, + f"Invalid material URL: '{material_url}' is not a valid HTTP URL. " + f"Server must provide boundMaterialUrl." + ) + render_spec = task.get_render_spec() output_spec = task.get_output_spec() duration_ms = task.get_duration_ms()