{
  "format": "mosael-workflow",
  "version": 1,
  "workflow_revision": 1,
  "name": "Transcript-based video cleanup",
  "description": "Remove background hiss, transcribe the video with timestamps, identify pauses, fillers and repetition, then create a cut plan and a cleaned video while preserving the original. Suited to talks and interviews up to about 30 minutes; split longer footage first.",
  "graph_hash": "b6d6e5ab29ac9b4186e2d6f8f0c1972d74e845283b390ee9cbb4c7306fd0e086",
  "graph": {
    "meta": {
      "template_id": "transcript_video_cleanup",
      "template_version": 6,
      "source": "official"
    },
    "nodes": [
      {
        "id": "start",
        "type": "start",
        "name": "Set the cleanup thresholds",
        "position": {
          "x": 40,
          "y": 260
        },
        "config": {
          "params": {
            "cleanup_style": "Natural and tight; keep the real tone and the breaths that matter",
            "silence_threshold_seconds": 1.0,
            "filler_policy": "Conservative: only remove standalone fillers that carry no meaning",
            "max_removal_ratio": 0.35
          }
        }
      },
      {
        "id": "source_video",
        "type": "asset",
        "name": "Pick the video to clean up",
        "position": {
          "x": 330,
          "y": 260
        },
        "config": {
          "asset_id": ""
        }
      },
      {
        "id": "clean_audio",
        "type": "denoise_audio",
        "name": "Remove background noise (a new asset; the source is untouched)",
        "position": {
          "x": 650,
          "y": 260
        },
        "config": {
          "asset_id": "",
          "strength": "medium"
        },
        "inputs": [
          "asset_id"
        ]
      },
      {
        "id": "verbatim_transcript",
        "type": "transcribe_asset",
        "name": "Transcribe with timecodes",
        "position": {
          "x": 970,
          "y": 100
        },
        "config": {
          "asset_id": ""
        },
        "inputs": [
          "asset_id"
        ]
      },
      {
        "id": "cleanup_project",
        "type": "project_sequence_create",
        "name": "Create a non-destructive working copy",
        "position": {
          "x": 970,
          "y": 420
        },
        "config": {
          "name": "{{source_video.name}} · Cleaned up",
          "width": "",
          "height": "",
          "fps": ""
        },
        "inputs": [
          "width",
          "height",
          "fps"
        ]
      },
      {
        "id": "source_on_timeline",
        "type": "timeline_append",
        "name": "Put the cleaned video on the new timeline",
        "position": {
          "x": 1290,
          "y": 420
        },
        "config": {
          "sequence_id": "",
          "asset_id": "",
          "track_id": "",
          "start": 0
        },
        "inputs": [
          "sequence_id",
          "asset_id",
          "track_id"
        ]
      },
      {
        "id": "cleanup_plan",
        "type": "llm",
        "name": "Diagnose the mess and draft a cleanup plan",
        "position": {
          "x": 1610,
          "y": 260
        },
        "config": {
          "profile_id": "",
          "model": "",
          "preset": "precise",
          "system": "你是一名资深口播、访谈与课程剪辑师。你会收到段落级时间码逐字稿：每段有起止和正文（带标点）；\n段内的长停顿在 pauses 里给出起止，停顿两边几个词的时间在 tokens 里；口头禅候选（呃、嗯、就是说、um、uh、那个、like\n……）不管在哪都在 fillers 里给出起止和原文。任务是在不改写观点、不改变事实、\n不打乱时间顺序的前提下，让视频更紧凑、清楚、自然。识别长停顿、无语义口头禅、重复表达、错误起句后重录、\n明显跑题和噪声词。只把高置信度且能从时间码精确定位的问题放入 remove_ranges：段与段之间的停顿按相邻两段\n的起止定位，段内停顿按 pauses 定位，独立、无语义的口头禅按 fillers 给出的起止切（「那个」「like」这类歧义词\n要看上下文，作实词用的不删）；整句的重复、错误起句、跑题按整段的起止切。结构跳跃、可能有意的停顿、语气表达\n或任何含义不确定的内容只写进 issues 和 review_notes，不自动删除。范围必须按 src_start 升序、互不重叠、src_end 大于 src_start，并在\n素材时长内。删除停顿时在相邻有效语音两侧各保留约 0.12–0.20 秒自然呼吸。若重复录制同一句，保留表达最完整\n自然的一遍。只输出符合 JSON Schema 的对象。",
          "prompt": "素材名称：{{source_video.name}}\n素材时长：{{source_video.duration}} 秒\n逐字稿语言：{{verbatim_transcript.language}}\n整理风格：{{start.cleanup_style}}\n长停顿阈值：{{start.silence_threshold_seconds}} 秒\n口头禅策略：{{start.filler_policy}}\n最多删除原时长比例：{{start.max_removal_ratio}}\n\n下面是按原视频源时间记录的紧凑逐字稿 JSON。每段含 start/end/text（text 带标点）；有段内长停顿的段另有 pauses\n（每项是停顿的起止）和 tokens（停顿两边几个词的时间）；有口头禅候选的段另有 fillers（每个候选的起止和原文）。\ntokens、fillers 都是短数组，列顺序由顶层 token_columns 声明：\n{{verbatim_transcript.timed_text}}\n\n请逐项诊断并生成安全的 remove_ranges。所有自动删除范围的总时长不得超过规定比例；无法从逐字稿\n确定的画面杂乱、跳剪需求或语义取舍写入 review_notes，不得猜测时间范围。",
          "response_format": "json_schema",
          "json_schema_name": "transcript_video_cleanup_plan",
          "json_schema": {
            "type": "object",
            "properties": {
              "editorial_summary": {
                "type": "string",
                "description": "素材问题、整理策略和预期改善"
              },
              "revised_outline": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "issue_type": {
                      "type": "string",
                      "enum": [
                        "silence",
                        "filler",
                        "repetition",
                        "false_start",
                        "off_topic",
                        "verbal_noise",
                        "structure"
                      ]
                    },
                    "start_seconds": {
                      "type": "number",
                      "minimum": 0
                    },
                    "end_seconds": {
                      "type": "number",
                      "minimum": 0
                    },
                    "excerpt": {
                      "type": "string"
                    },
                    "diagnosis": {
                      "type": "string"
                    },
                    "recommendation": {
                      "type": "string"
                    },
                    "auto_cut": {
                      "type": "boolean"
                    },
                    "confidence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  },
                  "required": [
                    "issue_type",
                    "start_seconds",
                    "end_seconds",
                    "excerpt",
                    "diagnosis",
                    "recommendation",
                    "auto_cut",
                    "confidence"
                  ],
                  "additionalProperties": false
                }
              },
              "remove_ranges": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "src_start": {
                      "type": "number",
                      "minimum": 0
                    },
                    "src_end": {
                      "type": "number",
                      "exclusiveMinimum": 0
                    },
                    "issue_type": {
                      "type": "string",
                      "enum": [
                        "silence",
                        "filler",
                        "repetition",
                        "false_start",
                        "off_topic",
                        "verbal_noise"
                      ]
                    },
                    "reason": {
                      "type": "string"
                    },
                    "transcript_excerpt": {
                      "type": "string"
                    },
                    "confidence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  },
                  "required": [
                    "src_start",
                    "src_end",
                    "issue_type",
                    "reason",
                    "transcript_excerpt",
                    "confidence"
                  ],
                  "additionalProperties": false
                }
              },
              "review_notes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "estimated_removed_seconds": {
                "type": "number",
                "minimum": 0
              }
            },
            "required": [
              "editorial_summary",
              "revised_outline",
              "issues",
              "remove_ranges",
              "review_notes",
              "estimated_removed_seconds"
            ],
            "additionalProperties": false
          },
          "json_schema_strict": "true",
          "temperature": 0.15,
          "max_tokens": 16000
        }
      },
      {
        "id": "apply_cleanup",
        "type": "timeline_cut_ranges",
        "name": "Ripple-cut the timeline from the transcript",
        "position": {
          "x": 1930,
          "y": 260
        },
        "config": {
          "sequence_id": "",
          "clip_id": "",
          "ranges": "{{cleanup_plan.json.remove_ranges}}",
          "min_confidence": 0.8,
          "max_removal_ratio": "{{start.max_removal_ratio}}",
          "segments": ""
        },
        "inputs": [
          "sequence_id",
          "clip_id",
          "segments"
        ]
      },
      {
        "id": "export_clean_video",
        "type": "export_sequence",
        "name": "Export the cleaned-up video",
        "position": {
          "x": 2250,
          "y": 260
        },
        "config": {
          "sequence_id": ""
        },
        "inputs": [
          "sequence_id"
        ]
      },
      {
        "id": "done_notice",
        "type": "notify",
        "name": "Cleanup finished notice",
        "position": {
          "x": 2570,
          "y": 260
        },
        "config": {
          "title": "Transcript and cleanup are ready",
          "body": "{{source_video.name}} has been denoised; the transcript, the diagnosis and a non-destructive cleaned-up cut are ready. {{apply_cleanup.skipped_note}}"
        }
      },
      {
        "id": "output",
        "type": "output",
        "name": "Hand over the transcript, the plan and the export",
        "position": {
          "x": 2890,
          "y": 260
        },
        "config": {
          "values": {
            "source_asset_id": "{{source_video.asset_id}}",
            "denoised_asset_id": "{{clean_audio.asset_id}}",
            "verbatim_transcript": "{{verbatim_transcript.text}}",
            "timed_transcript": "{{verbatim_transcript.segments}}",
            "cleanup_plan": "{{cleanup_plan.json}}",
            "cleaned_verbatim": "{{apply_cleanup.kept_text}}",
            "applied_ranges": "{{apply_cleanup.ranges}}",
            "skipped_ranges": "{{apply_cleanup.skipped_ranges}}",
            "removed_seconds": "{{apply_cleanup.removed_seconds}}",
            "project_id": "{{cleanup_project.project_id}}",
            "sequence_id": "{{cleanup_project.sequence_id}}",
            "final_asset_id": "{{export_clean_video.asset_id}}"
          }
        }
      }
    ],
    "edges": [
      {
        "id": "start_source",
        "source": "start",
        "target": "source_video"
      },
      {
        "id": "source_denoise",
        "source": "source_video",
        "target": "clean_audio"
      },
      {
        "id": "denoise_transcript",
        "source": "clean_audio",
        "target": "verbatim_transcript"
      },
      {
        "id": "transcript_project",
        "source": "verbatim_transcript",
        "target": "cleanup_project"
      },
      {
        "id": "denoise_append",
        "source": "clean_audio",
        "target": "source_on_timeline"
      },
      {
        "id": "project_append",
        "source": "cleanup_project",
        "target": "source_on_timeline"
      },
      {
        "id": "transcript_plan",
        "source": "verbatim_transcript",
        "target": "cleanup_plan"
      },
      {
        "id": "append_plan",
        "source": "source_on_timeline",
        "target": "cleanup_plan"
      },
      {
        "id": "plan_apply",
        "source": "cleanup_plan",
        "target": "apply_cleanup"
      },
      {
        "id": "apply_export",
        "source": "apply_cleanup",
        "target": "export_clean_video"
      },
      {
        "id": "export_notice",
        "source": "export_clean_video",
        "target": "done_notice"
      },
      {
        "id": "notice_output",
        "source": "done_notice",
        "target": "output"
      },
      {
        "id": "d-source_video-asset_id-clean_audio-asset_id",
        "source": "source_video",
        "target": "clean_audio",
        "kind": "data",
        "source_output": "asset_id",
        "target_input": "asset_id"
      },
      {
        "id": "d-clean_audio-asset_id-verbatim_transcript-asset_id",
        "source": "clean_audio",
        "target": "verbatim_transcript",
        "kind": "data",
        "source_output": "asset_id",
        "target_input": "asset_id"
      },
      {
        "id": "d-source_video-width-cleanup_project-width",
        "source": "source_video",
        "target": "cleanup_project",
        "kind": "data",
        "source_output": "width",
        "target_input": "width"
      },
      {
        "id": "d-source_video-height-cleanup_project-height",
        "source": "source_video",
        "target": "cleanup_project",
        "kind": "data",
        "source_output": "height",
        "target_input": "height"
      },
      {
        "id": "d-source_video-fps-cleanup_project-fps",
        "source": "source_video",
        "target": "cleanup_project",
        "kind": "data",
        "source_output": "fps",
        "target_input": "fps"
      },
      {
        "id": "d-cleanup_project-sequence_id-source_on_timeline-sequence_id",
        "source": "cleanup_project",
        "target": "source_on_timeline",
        "kind": "data",
        "source_output": "sequence_id",
        "target_input": "sequence_id"
      },
      {
        "id": "d-clean_audio-asset_id-source_on_timeline-asset_id",
        "source": "clean_audio",
        "target": "source_on_timeline",
        "kind": "data",
        "source_output": "asset_id",
        "target_input": "asset_id"
      },
      {
        "id": "d-cleanup_project-video_track_id-source_on_timeline-track_id",
        "source": "cleanup_project",
        "target": "source_on_timeline",
        "kind": "data",
        "source_output": "video_track_id",
        "target_input": "track_id"
      },
      {
        "id": "d-cleanup_project-sequence_id-apply_cleanup-sequence_id",
        "source": "cleanup_project",
        "target": "apply_cleanup",
        "kind": "data",
        "source_output": "sequence_id",
        "target_input": "sequence_id"
      },
      {
        "id": "d-source_on_timeline-clip_id-apply_cleanup-clip_id",
        "source": "source_on_timeline",
        "target": "apply_cleanup",
        "kind": "data",
        "source_output": "clip_id",
        "target_input": "clip_id"
      },
      {
        "id": "d-verbatim_transcript-segments-apply_cleanup-segments",
        "source": "verbatim_transcript",
        "target": "apply_cleanup",
        "kind": "data",
        "source_output": "segments",
        "target_input": "segments"
      },
      {
        "id": "d-cleanup_project-sequence_id-export_clean_video-sequence_id",
        "source": "cleanup_project",
        "target": "export_clean_video",
        "kind": "data",
        "source_output": "sequence_id",
        "target_input": "sequence_id"
      }
    ]
  }
}
