{
  "format": "mosael-workflow",
  "version": 1,
  "workflow_revision": 1,
  "name": "稿子 → 数字人口播",
  "description": "一张正脸加一段稿子:逐句配音,按说话照片模型一次能收的长度分段,每段让这张脸说出来,首尾相接铺上时间线,字幕按配音的实际时长铺好,导出成片。成片带「AI 生成」标识。运行前在「让它说话」上确认已取得授权。",
  "graph_hash": "f4b54900a8bdfd282f761f4fc4b7396bb60edf070e3bc0d51b9d924d0f4048fe",
  "graph": {
    "meta": {
      "template_id": "talking_script_video",
      "template_version": 3,
      "source": "official"
    },
    "nodes": [
      {
        "id": "start",
        "type": "start",
        "name": "填稿子",
        "position": {
          "x": 40,
          "y": 260
        },
        "config": {
          "params": {
            "title": "数字人口播",
            "width": 1080,
            "height": 1920,
            "fps": 25
          }
        }
      },
      {
        "id": "face",
        "type": "asset",
        "name": "选一张正脸",
        "position": {
          "x": 330,
          "y": 120
        },
        "config": {
          "asset_id": ""
        }
      },
      {
        "id": "voicing",
        "type": "talking_segments",
        "name": "长稿分段配音",
        "position": {
          "x": 330,
          "y": 400
        },
        "config": {
          "text": "",
          "engine": "builtin:clone",
          "voice": "",
          "model": ""
        }
      },
      {
        "id": "project",
        "type": "project_sequence_create",
        "name": "建立口播时间线",
        "position": {
          "x": 650,
          "y": 400
        },
        "config": {
          "name": "{{start.title}}",
          "width": "{{start.width}}",
          "height": "{{start.height}}",
          "fps": "{{start.fps}}"
        }
      },
      {
        "id": "speak_segments",
        "type": "loop_foreach",
        "name": "逐段让它说话并接上时间线",
        "position": {
          "x": 970,
          "y": 260
        },
        "config": {
          "items": "",
          "inputs": {
            "face_asset_id": "{{face.asset_id}}",
            "sequence_id": "{{project.sequence_id}}",
            "video_track_id": "{{project.video_track_id}}"
          },
          "body": {
            "nodes": [
              {
                "id": "speak",
                "type": "image_speak",
                "name": "这一段说话照片",
                "position": {
                  "x": 80,
                  "y": 140
                },
                "config": {
                  "asset_id": "{{input.face_asset_id}}",
                  "audio_asset_id": "{{loop.item.audio_asset_id}}",
                  "model": "{{loop.item.model}}",
                  "consent": ""
                }
              },
              {
                "id": "place",
                "type": "timeline_append",
                "name": "接到上一段后面",
                "position": {
                  "x": 400,
                  "y": 140
                },
                "config": {
                  "sequence_id": "{{input.sequence_id}}",
                  "asset_id": "",
                  "track_id": "{{input.video_track_id}}"
                },
                "inputs": [
                  "asset_id"
                ]
              }
            ],
            "edges": [
              {
                "id": "speak_place",
                "source": "speak",
                "target": "place"
              },
              {
                "id": "d-speak-asset_id-place-asset_id",
                "source": "speak",
                "target": "place",
                "kind": "data",
                "source_output": "asset_id",
                "target_input": "asset_id"
              }
            ]
          },
          "concurrency": 1,
          "output": "{{place.clip_id}}"
        },
        "inputs": [
          "items"
        ]
      },
      {
        "id": "captions",
        "type": "generate_subtitles",
        "name": "按配音时间铺字幕",
        "position": {
          "x": 1290,
          "y": 260
        },
        "config": {
          "sequence_id": "",
          "segments": "",
          "start_field": "start",
          "end_field": "end",
          "text_field": "text"
        },
        "inputs": [
          "sequence_id",
          "segments"
        ]
      },
      {
        "id": "export_video",
        "type": "export_sequence",
        "name": "导出成片",
        "position": {
          "x": 1610,
          "y": 260
        },
        "config": {
          "sequence_id": ""
        },
        "inputs": [
          "sequence_id"
        ]
      },
      {
        "id": "output",
        "type": "output",
        "name": "交付成片",
        "position": {
          "x": 1930,
          "y": 260
        },
        "config": {
          "values": {
            "final_asset_id": "{{export_video.asset_id}}",
            "segment_clip_ids": "{{speak_segments.results}}",
            "sequence_id": "{{project.sequence_id}}"
          }
        }
      }
    ],
    "edges": [
      {
        "id": "start_face",
        "source": "start",
        "target": "face"
      },
      {
        "id": "start_voicing",
        "source": "start",
        "target": "voicing"
      },
      {
        "id": "start_project",
        "source": "start",
        "target": "project"
      },
      {
        "id": "voicing_speak",
        "source": "voicing",
        "target": "speak_segments"
      },
      {
        "id": "face_speak",
        "source": "face",
        "target": "speak_segments"
      },
      {
        "id": "project_speak",
        "source": "project",
        "target": "speak_segments"
      },
      {
        "id": "speak_captions",
        "source": "speak_segments",
        "target": "captions"
      },
      {
        "id": "captions_export",
        "source": "captions",
        "target": "export_video"
      },
      {
        "id": "export_output",
        "source": "export_video",
        "target": "output"
      },
      {
        "id": "d-voicing-segments-speak_segments-items",
        "source": "voicing",
        "target": "speak_segments",
        "kind": "data",
        "source_output": "segments",
        "target_input": "items"
      },
      {
        "id": "d-project-sequence_id-captions-sequence_id",
        "source": "project",
        "target": "captions",
        "kind": "data",
        "source_output": "sequence_id",
        "target_input": "sequence_id"
      },
      {
        "id": "d-voicing-cues-captions-segments",
        "source": "voicing",
        "target": "captions",
        "kind": "data",
        "source_output": "cues",
        "target_input": "segments"
      },
      {
        "id": "d-project-sequence_id-export_video-sequence_id",
        "source": "project",
        "target": "export_video",
        "kind": "data",
        "source_output": "sequence_id",
        "target_input": "sequence_id"
      }
    ]
  }
}
