限制序列帧去背景仅用于视频转换

后端仅接受 character-animation.convert 结果执行序列帧去背景

前端工具栏与工作流同步收紧视频转换门禁

更新相关测试与Spine序列帧技术方案
This commit is contained in:
2026-08-15 15:35:27 +08:00
parent b5dc99e067
commit f65a813768
7 changed files with 57 additions and 73 deletions
@@ -1124,24 +1124,14 @@ async fn validate_editor_character_animation_source_frames(
Ok(())
}
fn editor_character_animation_sequence_is_green_screen(generation_inputs: Option<&Value>) -> bool {
fn editor_character_animation_sequence_is_video_conversion(
generation_inputs: Option<&Value>,
) -> bool {
let Some(inputs) = generation_inputs.and_then(Value::as_object) else {
return false;
};
if inputs.get("version").and_then(Value::as_u64) != Some(2)
|| inputs.get("action").and_then(Value::as_str) != Some("character-animation.generate")
{
return false;
}
inputs
.get("fields")
.and_then(Value::as_array)
.into_iter()
.flatten()
.any(|field| {
field.get("id").and_then(Value::as_str) == Some("backgroundColor")
&& field.get("value").and_then(Value::as_str) == Some("green")
})
inputs.get("version").and_then(Value::as_u64) == Some(2)
&& inputs.get("action").and_then(Value::as_str) == Some("character-animation.convert")
}
pub async fn remove_editor_character_animation_background(
@@ -1291,13 +1281,13 @@ pub(crate) async fn remove_editor_character_animation_background_for_owner(
})),
));
}
if !editor_character_animation_sequence_is_green_screen(
if !editor_character_animation_sequence_is_video_conversion(
source_resource.generation_inputs.as_ref(),
) {
return Err(character_animation_error_response(
&request_context,
editor_character_animation_bad_request(
"当前仅支持由编辑器生成且背景为纯绿幕的角色动作序列帧去背景。",
"AI生成的角色动作序列帧已自动去背景,只有视频直接转换结果可以再次去背景。",
),
));
}
@@ -9342,41 +9332,40 @@ mod tests {
}
#[test]
fn editor_character_animation_background_removal_requires_green_generated_inputs() {
let green_inputs = json!({
fn editor_character_animation_background_removal_requires_video_conversion_inputs() {
let converted_inputs = json!({
"version": 2,
"action": "character-animation.generate",
"fields": [{
"id": "backgroundColor",
"value": "green"
}]
"action": "character-animation.convert",
"fields": []
});
assert!(editor_character_animation_sequence_is_green_screen(Some(
&green_inputs
)));
assert!(editor_character_animation_sequence_is_video_conversion(
Some(&converted_inputs)
));
for inputs in [
json!({
"version": 2,
"action": "character-animation.generate",
"fields": [{ "id": "backgroundColor", "value": "white" }]
}),
json!({
"version": 2,
"action": "character-animation.generate",
"fields": [{ "id": "backgroundColor", "value": "blue" }]
}),
json!({
"version": 2,
"action": "character-animation.convert",
"fields": [{ "id": "backgroundColor", "value": "green" }]
}),
json!({
"version": 2,
"action": "character-animation.remove-background",
"fields": []
}),
json!({
"version": 1,
"action": "character-animation.convert",
"fields": []
}),
] {
assert!(!editor_character_animation_sequence_is_green_screen(Some(
&inputs
)));
assert!(!editor_character_animation_sequence_is_video_conversion(
Some(&inputs)
));
}
assert!(!editor_character_animation_sequence_is_green_screen(None));
assert!(!editor_character_animation_sequence_is_video_conversion(
None
));
}
#[test]