From fef03abb47f606168f667a1f617ee8965223190b Mon Sep 17 00:00:00 2001 From: KoDelioDa Date: Mon, 11 Aug 2025 23:39:55 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20pattern/tmp.py,?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=8F=A3=E6=92=AD=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E5=B9=95=E4=BB=A3=E7=A0=81=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pattern/tmp.py | 625 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 625 insertions(+) diff --git a/pattern/tmp.py b/pattern/tmp.py index e69de29..d1a0f9a 100644 --- a/pattern/tmp.py +++ b/pattern/tmp.py @@ -0,0 +1,625 @@ +import requests +import json +from flask import Flask, request, jsonify, Response +import sys +import time +from capcut_server import add_text, save_draft, add_audio +#from settings.local import PORT +#from util import timing_decorator +#from pyJianYingDraft.text_segment import TextStyleRange, Text_style, Text_border +#from util import hex_to_rgb +import pandas as pd +import json, os, ast, csv + +PORT=9000 #端口 +BASE_URL = f"http://localhost:{PORT}" +LICENSE_KEY = "trial" # Trial license key +draft_folder = r"z:\PAWA\项目\CapCutAPI\草稿" + + + +def make_request(endpoint, data, method='POST'): + """Send HTTP request to the server and handle the response""" + url = f"{BASE_URL}/{endpoint}" + headers = {'Content-Type': 'application/json'} + + try: + if method == 'POST': + response = requests.post(url, data=json.dumps(data), headers=headers) + elif method == 'GET': + response = requests.get(url, params=data, headers=headers) + else: + raise ValueError(f"Unsupported HTTP method: {method}") + + response.raise_for_status() # Raise an exception if the request fails + return response.json() + except requests.exceptions.RequestException as e: + print(f"Request error: {e}") + sys.exit(1) + except json.JSONDecodeError: + print("Unable to parse server response") + sys.exit(1) + +def save_draft_impl(draft_id, draft_folder): + """API wrapper for save_draft service""" + data = { + "license_key": LICENSE_KEY, # Using trial version license key + "draft_id": draft_id, + "draft_folder": draft_folder + } + return make_request("save_draft", data) + +def query_script_impl(draft_id): + """API wrapper for query_script service""" + data = { + "draft_id": draft_id + } + return make_request("query_script", data) + +def add_text_impl(text, start, end, font, font_color, font_size, track_name, draft_folder="123", draft_id=None, + vertical=False, transform_x=0, transform_y=0, font_alpha=1.0, + border_color=None, border_width=0.0, border_alpha=1.0, + background_color=None, background_alpha=1.0, background_style=None, + background_round_radius=0.0, background_height=0.14, background_width=0.14, + background_horizontal_offset=0.5, background_vertical_offset=0.5, + shadow_enabled=False, shadow_alpha=0.9, shadow_angle=-45.0, + shadow_color="#000000", shadow_distance=5.0, shadow_smoothing=0.15, + bubble_effect_id=None, bubble_resource_id=None, + effect_effect_id=None, + intro_animation=None, intro_duration=0.5, + outro_animation=None, outro_duration=0.5, + width=1080, height=1920, + fixed_width=-1, fixed_height=-1, + text_styles=None): + """Add text with support for multiple styles, shadows, and backgrounds""" + data = { + "draft_folder": draft_folder, + "text": text, + "start": start, + "end": end, + "font": font, + "font_color": font_color, + "font_size": font_size, + "alpha": font_alpha, + "track_name": track_name, + "vertical": vertical, + "transform_x": transform_x, + "transform_y": transform_y + } + + # Add border parameters + if border_color: + data["border_color"] = border_color + data["border_width"] = border_width + data["border_alpha"] = border_alpha + + # Add background parameters + if background_color: + data["background_color"] = background_color + data["background_alpha"] = background_alpha + if background_style: + data["background_style"] = background_style + data["background_round_radius"] = background_round_radius + data["background_height"] = background_height + data["background_width"] = background_width + data["background_horizontal_offset"] = background_horizontal_offset + data["background_vertical_offset"] = background_vertical_offset + + # Add shadow parameters + if shadow_enabled: + data["shadow_enabled"] = shadow_enabled + data["shadow_alpha"] = shadow_alpha + data["shadow_angle"] = shadow_angle + data["shadow_color"] = shadow_color + data["shadow_distance"] = shadow_distance + data["shadow_smoothing"] = shadow_smoothing + + + # Add bubble effect parameters + if bubble_effect_id: + data["bubble_effect_id"] = bubble_effect_id + if bubble_resource_id: + data["bubble_resource_id"] = bubble_resource_id + + # Add text effect parameters + if effect_effect_id: + data["effect_effect_id"] = effect_effect_id + + # Add intro animation parameters + if intro_animation: + data["intro_animation"] = intro_animation + data["intro_duration"] = intro_duration + + # Add outro animation parameters + if outro_animation: + data["outro_animation"] = outro_animation + data["outro_duration"] = outro_duration + + # Add size parameters + data["width"] = width + data["height"] = height + + # Add fixed size parameters + if fixed_width > 0: + data["fixed_width"] = fixed_width + if fixed_height > 0: + data["fixed_height"] = fixed_height + + if draft_id: + data["draft_id"] = draft_id + + # Add text styles parameters + if text_styles: + data["text_styles"] = text_styles + + if draft_id: + data["draft_id"] = draft_id + + return make_request("add_text", data) + + +def group_sentences(corrected_srt, threshold=1.0): + """按时间间隔分句""" + if not corrected_srt: + return [] + sentences = [] + current_sentence = [corrected_srt[0]] + for i in range(1, len(corrected_srt)): + prev_end = corrected_srt[i-1]["end"] + curr_start = corrected_srt[i]["start"] + if curr_start - prev_end > threshold: + sentences.append(current_sentence) + current_sentence = [corrected_srt[i]] + else: + current_sentence.append(corrected_srt[i]) + sentences.append(current_sentence) + return sentences + + +def adjust_sentence_timing(sentences, gap_adjust=1, time_precision=3): + """调整句子间的时间间隔,并保留原始时间""" + def round_time(t): + return round(t, time_precision) if time_precision is not None else t + + adjusted_sentences = [] + total_offset = 0.0 + prev_end = sentences[0][-1]["end"] + + # 第一句保持原时间 + first_sentence = [ + { + "word": w["word"], + "start": w["start"], + "end": w["end"], + "original_start": w["start"], + "original_end": w["end"] + } + for w in sentences[0] + ] + adjusted_sentences.append(first_sentence) + + for i in range(1, len(sentences)): + sentence = sentences[i] + curr_start = sentence[0]["start"] + natural_gap = curr_start - prev_end + adjusted_gap = natural_gap if gap_adjust == 0 else (1.0 if natural_gap > 1.0 else natural_gap) + move_amount = natural_gap - adjusted_gap + total_offset += move_amount + + adjusted_sentence = [] + for w in sentence: + adjusted_sentence.append({ + "word": w["word"], + "start": round_time(w["start"] - total_offset), + "end": round_time(w["end"] - total_offset), + "original_start": w["start"], + "original_end": w["end"] + }) + adjusted_sentences.append(adjusted_sentence) + prev_end = sentence[-1]["end"] + return adjusted_sentences + + +def split_into_paragraphs(sentence, max_words=5, max_chunk_duration=1.5): + """把句子按词数和时长分段""" + paragraphs = [] + i = 0 + n = len(sentence) + while i < n: + paragraph = [sentence[i]] + current_start = sentence[i]["start"] + current_end = sentence[i]["end"] + i += 1 + while i < n: + current_word = sentence[i] + is_continuous = abs(current_word["start"] - current_end) < 0.001 + if (len(paragraph) >= max_words or + (current_word["end"] - current_start) >= max_chunk_duration or + not is_continuous): + break + paragraph.append(current_word) + current_end = current_word["end"] + i += 1 + paragraphs.append(paragraph) + + return paragraphs + + +def build_segments_by_mode( + mode, + paragraph, + track_name, + font, + font_size, + highlight_color, + normal_color, + transform_x, + transform_y, + fixed_width, + shadow_enabled, + shadow_color, + border_color, + border_width, + border_alpha, + background_color, + ): + + """根据模式生成字幕片段""" + segments = [] + #print("二级代码返回调试fx", fixed_width) + + if mode == "word_pop": + # 单词跳出 + for w in paragraph: + text_styles = [] + word_count = len(w["word"].replace(" ", "")) #统计有多少个字 + text_styles.append({ + "start": 0, + "end": word_count, + "border": { + "alpha": border_alpha, + "color": border_color, + "width": border_width + } + }) + segments.append({ + "text": w["word"], + "start": w["start"], + "end": w["end"], + "font": font, + "track_name": track_name, + "font_color": normal_color, + "font_size": font_size, + "transform_x": transform_x, + "transform_y": transform_y, + "shadow_enabled": shadow_enabled, + "fixed_width": fixed_width, + "text_styles": text_styles, + + "shadow_color": shadow_color, + "border_color": border_color, + "border_width": border_width, + "border_alpha": border_alpha, + + "background_color": background_color, + }) + + elif mode == "word_highlight": + # 单词高亮:当前词亮,其他灰 + paragraph_text = " ".join(w["word"] for w in paragraph) + offsets = [] + ci = 0 + for w in paragraph: + offsets.append((ci, ci + len(w["word"]))) + ci += len(w["word"]) + 1 + for idx, w in enumerate(paragraph): + text_styles = [] + for k, (s, e) in enumerate(offsets): + color = highlight_color if k == idx else normal_color + text_styles.append({ + "start": s, + "end": e, + "style": { + "color": color, + "size": font_size, + }, + "border": { + "alpha": border_alpha, + "color": border_color, + "width": border_width + } + }) + print("text_styles", text_styles) + + segments.append({ + "text": paragraph_text, + "start": w["start"], + "end": w["end"], + "font": font, + "track_name": track_name, + "font_color": normal_color, + "font_size": font_size, + "text_styles": text_styles, + "transform_x": transform_x, + "transform_y": transform_y, + "shadow_enabled": shadow_enabled, + "fixed_width": fixed_width, + + + "shadow_color": shadow_color, + "border_color": border_color, + "border_width": border_width, + "border_alpha": border_alpha, + + "background_color": background_color, + }) + + elif mode == "sentence_fade": + # 句子渐显:已亮过的词继续保持亮 + paragraph_text = " ".join(w["word"] for w in paragraph) + offsets = [] + ci = 0 + for w in paragraph: + offsets.append((ci, ci + len(w["word"]))) + ci += len(w["word"]) + 1 + for idx, w in enumerate(paragraph): + text_styles = [] + for k, (s, e) in enumerate(offsets): + color = highlight_color if k <= idx else normal_color + text_styles.append({ + "start": s, + "end": e, + "style": {"color": color, "size": font_size}, + "border": { + "alpha": border_alpha, + "color": border_color, + "width": border_width + } + }) + segments.append({ + "text": paragraph_text, + "start": w["start"], + "end": w["end"], + "font": font, + "track_name": track_name, + "font_color": normal_color, + "font_size": font_size, + "text_styles": text_styles, + "transform_x": transform_x, + "transform_y": transform_y, + "shadow_enabled": shadow_enabled, + "fixed_width": fixed_width, + + + "shadow_color": shadow_color, + "border_color": border_color, + "border_width": border_width, + "border_alpha": border_alpha, + + "background_color": background_color, + }) + + elif mode == "sentence_pop": + # 句子跳出 + text = " ".join(w["word"] for w in paragraph) + start_time = paragraph[0]["start"] + end_time = paragraph[-1]["end"] + text_styles = [] + word_count = len(text.replace(" ", "")) #统计有多少个字 + text_styles.append({ + "start": 0, + "end": word_count, + "border": { + "alpha": border_alpha, + "color": border_color, + "width": border_width + } + }) + segments.append({ + "text": text, + "start": start_time, + "end": end_time, + "font": font, + "track_name": track_name, + "font_color": normal_color, + "font_size": font_size, + "transform_x": transform_x, + "transform_y": transform_y, + "shadow_enabled": shadow_enabled, + "fixed_width": fixed_width, + "text_styles": text_styles, + + + "shadow_color": shadow_color, + "border_color": border_color, + "border_width": border_width, + "border_alpha": border_alpha, + + "background_color": background_color, + }) + + else: + raise ValueError(f"未知模式: {mode}") + """segments.append({ + "file_name": file_name, + })""" + + return segments + +corrected_srt = [{ + "word": "你", + "start": 0.0, + "end": 0.64, + "confidence": 0.93917525 + }, + { + "word": "好", + "start": 0.64, + "end": 0.79999995, + "confidence": 0.9976464 + }, + { + "word": "我", + "start": 0.79999995, + "end": 1.36, + "confidence": 0.6848311 + }, + { + "word": "是", + "start": 1.36, + "end": 1.52, + "confidence": 0.9850389 + }, + { + "word": "PAWA", + "start": 1.52, + "end": 1.68, + "confidence": 0.9926886 + }, + { + "word": "很", + "start": 1.68, + "end": 2.08, + "confidence": 0.9972697 + }, + { + "word": "高", + "start": 2.08, + "end": 2.72, + "confidence": 0.9845563 + }, + { + "word": "兴", + "start": 2.72, + "end": 3.04, + "confidence": 0.99794894 + }, + { + "word": "认", + "start": 3.04, + "end": 3.1999998, + "confidence": 0.9970203 + }, + { + "word": "识", + "start": 3.1999998, + "end": 3.36, + "confidence": 0.9970235 + }, + { + "word": "大", + "start": 3.36, + "end": 3.6799998, + "confidence": 0.98627764 + }, + { + "word": "家", + "start": 3.6799998, + "end": 4.0, + "confidence": 0.9939551 + }, + ] + + +def add_koubo_from_srt( + corrected_srt, + track_name, + mode="word_pop", + font="ZY_Modern", + font_size=32, + highlight_color="#FFD700", + normal_color="#AAAAAA", max_chunk_duration=1.5, max_words=5, + gap_adjust=1, + time_precision=3, + transform_x=0.5, + transform_y=0.3, + fixed_width=-1, + shadow_enabled=True, + shadow_color="#000000", + border_color="#000000", + border_width=0.5, + border_alpha=1.0, + background_color="#000000", + + ): + """统一入口:根据 mode 选择字幕效果""" + sentences = group_sentences(corrected_srt) + adjusted_sentences = adjust_sentence_timing(sentences, gap_adjust, time_precision) + all_paragraphs = [split_into_paragraphs(s, max_words, max_chunk_duration) for s in adjusted_sentences] + + draft_id_ret = None + for sentence_paragraphs in all_paragraphs: + for paragraph in sentence_paragraphs: + segments = build_segments_by_mode( + mode, + paragraph, + track_name, + font, + font_size, + highlight_color, + normal_color, + transform_x, + transform_y, + fixed_width, + shadow_enabled, + shadow_color, + border_color, + border_width, + border_alpha, + background_color, + + ) + #print("segments", segments) + + for seg in segments: + #print("二级代码返回调试fx", seg) + if draft_id_ret: + seg["draft_id"] = draft_id_ret + print("seg", seg) + + res = add_text_impl(**seg) + if draft_id_ret is None and isinstance(res, dict): + try: + draft_id_ret = res["output"]["draft_id"] + except: + pass + return draft_id_ret + +colors = { + "shadow_color": "#000000", + "border_color": "#FFD700", + "background_color": "#000000", + "normal_color": "#FFFFFF", + "highlight_color": "#DA70D6" # 紫色 + } + +draft_id = add_koubo_from_srt( + corrected_srt, + track_name="main_text", + font_size=15, + gap_adjust=0, + transform_x=0, + transform_y=-0.45,# 0=保持原间隔,1=调整>1s的间隔 + fixed_width = 0.6, + mode="word_highlight", + shadow_enabled=True, + border_width=10, + border_alpha=1.0, + + **colors, + + font="ZY_Modern", #设置自己的字体,需要在字体库中添加 + + +) +save_result = save_draft_impl(draft_id, draft_folder) +""" +# 单词高亮 +mode="word_highlight" +# 单词跳出 +mode="word_pop" +# 句子渐显 +mode="sentence_fade" +# 句子跳出 +mode="sentence_pop" +""" From 4a77eea9497f7def036c027b1af6e54f7f2c428d Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 15:29:35 +0800 Subject: [PATCH 02/10] default font is system --- add_text_impl.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/add_text_impl.py b/add_text_impl.py index 23c306e..0643c1a 100644 --- a/add_text_impl.py +++ b/add_text_impl.py @@ -14,7 +14,7 @@ def add_text_impl( draft_id: str | None = None, # Python 3.10+ 新语法 transform_y: float = -0.8, transform_x: float = 0, - font: str = "文轩体", + font: Optional[str] = None, font_color: str = "#ffffff", font_size: float = 8.0, track_name: str = "text_main", @@ -102,11 +102,14 @@ def add_text_impl( :return: Updated draft information """ # Validate if font is in Font_type - try: - font_type = getattr(Font_type, font) - except: - available_fonts = [attr for attr in dir(Font_type) if not attr.startswith('_')] - raise ValueError(f"Unsupported font: {font}, please use one of the fonts in Font_type: {available_fonts}") + if font is None: + font_type = None + else: + try: + font_type = getattr(Font_type, font) + except: + available_fonts = [attr for attr in dir(Font_type) if not attr.startswith('_')] + raise ValueError(f"Unsupported font: {font}, please use one of the fonts in Font_type: {available_fonts}") # Validate alpha value range if not 0.0 <= font_alpha <= 1.0: From 8134ed9489364213356cbf4245f11485b078ab73 Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 16:39:46 +0800 Subject: [PATCH 03/10] add 001-words.py --- pattern/{tmp.py => 001-words.py} | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) rename pattern/{tmp.py => 001-words.py} (97%) diff --git a/pattern/tmp.py b/pattern/001-words.py similarity index 97% rename from pattern/tmp.py rename to pattern/001-words.py index d1a0f9a..d8232f7 100644 --- a/pattern/tmp.py +++ b/pattern/001-words.py @@ -3,18 +3,12 @@ import json from flask import Flask, request, jsonify, Response import sys import time -from capcut_server import add_text, save_draft, add_audio -#from settings.local import PORT -#from util import timing_decorator -#from pyJianYingDraft.text_segment import TextStyleRange, Text_style, Text_border -#from util import hex_to_rgb -import pandas as pd -import json, os, ast, csv +import json -PORT=9000 #端口 +PORT=9001 #端口 BASE_URL = f"http://localhost:{PORT}" -LICENSE_KEY = "trial" # Trial license key -draft_folder = r"z:\PAWA\项目\CapCutAPI\草稿" +draft_folder = "/Users/sunguannan/Movies/JianyingPro/User Data/Projects/com.lveditor.draft" + @@ -43,7 +37,6 @@ def make_request(endpoint, data, method='POST'): def save_draft_impl(draft_id, draft_folder): """API wrapper for save_draft service""" data = { - "license_key": LICENSE_KEY, # Using trial version license key "draft_id": draft_id, "draft_folder": draft_folder } @@ -612,7 +605,10 @@ draft_id = add_koubo_from_srt( ) + save_result = save_draft_impl(draft_id, draft_folder) + +print(save_result) """ # 单词高亮 mode="word_highlight" From c94b11a1f53bae9ed04376cd49d6f9608948d88c Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 16:56:15 +0800 Subject: [PATCH 04/10] add 001-words --- README-zh.md | 3 +++ README.md | 6 +++++- example.py | 2 +- pattern/001-words.py | 29 +++++++++++++++++------------ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/README-zh.md b/README-zh.md index f573ab4..7215550 100644 --- a/README-zh.md +++ b/README-zh.md @@ -246,6 +246,9 @@ mcp_client.call_tool("add_text", { 调用 `save_draft` 会在`capcut_server.py`当前目录下生成一个 `dfd_` 开头的文件夹,将其复制到剪映/CapCut 草稿目录,即可在应用中看到生成的草稿。 +## 模版 +我们汇总了一些模版,放在`pattern`文件夹下。 + ## 社区与支持 我们欢迎各种形式的贡献!我们的迭代规则: diff --git a/README.md b/README.md index 0280f24..b6a71ea 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ response = requests.post("http://localhost:9001/add_text", json={ "text": "Welcome to CapCutAPI", "start": 0, "end": 5, - "font": "Source Han Sans", + "font": "Source Han Sans",read "font_color": "#FFD700", "font_size": 48, "shadow_enabled": True, @@ -243,6 +243,10 @@ mcp_client.call_tool("add_text", { Calling `save_draft` will generate a folder starting with `dfd_` in the current directory of `capcut_server.py`. Copy this to the CapCut/Jianying drafts directory to see the generated draft in the application. +## Pattern + +You can find a lot of pattern in the `pattern` directory. + ## Community & Support We welcome contributions of all forms\! Our iteration rules are: diff --git a/example.py b/example.py index cff418f..c2d8f30 100644 --- a/example.py +++ b/example.py @@ -162,7 +162,7 @@ def add_text_impl(text, start, end, font, font_color, font_size, track_name, dra return make_request("add_text", data) -def add_image_impl(image_url, width, height, start, end, track_name, draft_id=None, +def add_image_impl(image_url, start, end, width=None, height=None, track_name="image_main", draft_id=None, transform_x=0, transform_y=0, scale_x=1.0, scale_y=1.0, transition=None, transition_duration=None, mask_type=None, mask_center_x=0.0, mask_center_y=0.0, mask_size=0.5, mask_rotation=0.0, mask_feather=0.0, mask_invert=False, diff --git a/pattern/001-words.py b/pattern/001-words.py index d8232f7..4da9f4c 100644 --- a/pattern/001-words.py +++ b/pattern/001-words.py @@ -5,6 +5,9 @@ import sys import time import json +sys.path.append('/Users/sunguannan/capcutapi') +from example import add_image_impl + PORT=9001 #端口 BASE_URL = f"http://localhost:{PORT}" draft_folder = "/Users/sunguannan/Movies/JianyingPro/User Data/Projects/com.lveditor.draft" @@ -440,73 +443,73 @@ def build_segments_by_mode( return segments corrected_srt = [{ - "word": "你", + "word": "Hello", "start": 0.0, "end": 0.64, "confidence": 0.93917525 }, { - "word": "好", + "word": "I'm", "start": 0.64, "end": 0.79999995, "confidence": 0.9976464 }, { - "word": "我", + "word": "PAWA", "start": 0.79999995, "end": 1.36, "confidence": 0.6848311 }, { - "word": "是", + "word": "Nice", "start": 1.36, "end": 1.52, "confidence": 0.9850389 }, { - "word": "PAWA", + "word": "To", "start": 1.52, "end": 1.68, "confidence": 0.9926886 }, { - "word": "很", + "word": "Meet", "start": 1.68, "end": 2.08, "confidence": 0.9972697 }, { - "word": "高", + "word": "You", "start": 2.08, "end": 2.72, "confidence": 0.9845563 }, { - "word": "兴", + "word": "Enjoy", "start": 2.72, "end": 3.04, "confidence": 0.99794894 }, { - "word": "认", + "word": "My", "start": 3.04, "end": 3.1999998, "confidence": 0.9970203 }, { - "word": "识", + "word": "Parttern", "start": 3.1999998, "end": 3.36, "confidence": 0.9970235 }, { - "word": "大", + "word": "Thank", "start": 3.36, "end": 3.6799998, "confidence": 0.98627764 }, { - "word": "家", + "word": "You", "start": 3.6799998, "end": 4.0, "confidence": 0.9939551 @@ -606,6 +609,8 @@ draft_id = add_koubo_from_srt( ) +add_image_impl(image_url="https://pic1.imgdb.cn/item/689aff2758cb8da5c81e64a2.png", start = 0, end = 4, draft_id=draft_id) + save_result = save_draft_impl(draft_id, draft_folder) print(save_result) From 0a05b6487b16329da7a9be33fc1986b7ed418b9b Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 18:02:50 +0800 Subject: [PATCH 05/10] add pattern readme --- pattern/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 pattern/README.md diff --git a/pattern/README.md b/pattern/README.md new file mode 100644 index 0000000..af06c7a --- /dev/null +++ b/pattern/README.md @@ -0,0 +1,7 @@ +# Pattern Gallery + +## 001-words.py + +[![Words](https://img.youtube.com/vi/HLSHaJuNtBw/hqdefault.jpg)](https://www.youtube.com/watch?v=HLSHaJuNtBw) + + From 195a927f04a7be29de8c622de56d50bb77c228f8 Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 18:14:06 +0800 Subject: [PATCH 06/10] add coze md --- pattern/001-words-coze.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 pattern/001-words-coze.md diff --git a/pattern/001-words-coze.md b/pattern/001-words-coze.md new file mode 100644 index 0000000..2c80700 --- /dev/null +++ b/pattern/001-words-coze.md @@ -0,0 +1,12 @@ +# 扣子国内版 制作文字滚动效果的工作流 + +## 复制到工作流中 + +``` +{"type":"coze-workflow-clipboard-data","source":{"workflowId":"7537610990579695658","flowMode":0,"spaceId":"7472683780642258985","isDouyin":false,"host":"www.coze.cn"},"json":{"nodes":[{"id":"151918","type":"4","meta":{"position":{"x":700.202085075201,"y":-87}},"data":{"nodeMeta":{"description":"创建一个剪映草稿","icon":"https://p26-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/d3b11847a234484ab18b4c0a5acfb1bb~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757578417&x-signature=YZZ9CHMpnjQwRTBBnwC3Eb7ZQxo%3D","subtitle":"视频剪辑_剪映草稿助手:create_draft","title":"create_draft"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7504135160821071884","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"create_draft","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7503106218777395219","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"视频剪辑_剪映草稿助手","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"string","name":"error","required":false},{"type":"object","name":"output","schema":[{"type":"string","name":"draft_id","required":false},{"type":"string","name":"draft_url","required":false}],"required":false},{"type":"string","name":"purchase_link","required":false},{"type":"boolean","name":"success","required":false}]},"_temp":{"bounds":{"x":520.202085075201,"y":-87,"width":360,"height":112},"externalData":{"icon":"https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747190144847346721_ZtIC02VX5J.png?lk3s=cd508e2b&x-expires=1757584231&x-signature=U2UUrn5PzZLQLLYawyaL6pmWAbA%3D","apiName":"create_draft","pluginID":"7503106218777395219","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"defaultValue":1920,"description":"画布高度, default value is 1920","input":{},"name":"height","required":false,"type":"integer"},{"defaultValue":1080,"description":"画布宽度, default value is 1080","input":{},"name":"width","required":false,"type":"integer"}],"outputs":[{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"output","required":false,"schema":[{"input":{},"name":"draft_id","required":false,"type":"string"},{"input":{},"name":"draft_url","required":false,"type":"string"}],"type":"object"},{"input":{},"name":"purchase_link","required":false,"type":"string"},{"input":{},"name":"success","required":false,"type":"boolean"}],"updateTime":1754985565,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"创建一个剪映草稿","title":"create_draft","mainColor":"#CA61FF"}}},{"id":"116289","type":"4","meta":{"position":{"x":1961.3705029177988,"y":-86.99999999999999}},"data":{"nodeMeta":{"description":"向视频中添加图片","icon":"https://p26-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/d3b11847a234484ab18b4c0a5acfb1bb~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757580241&x-signature=OrOCpYsprFwsowGxGzxyuRaqq2A%3D","subtitle":"视频剪辑_剪映草稿助手:add_image","title":"add_image"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7504135160821055500","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"add_image","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7503106218777395219","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"视频剪辑_剪映草稿助手","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"end","input":{"type":"float","value":{"type":"ref","content":{"source":"block-output","blockID":"104868","name":"output.duration"},"rawMeta":{"type":4}}}},{"name":"image_url","input":{"type":"string","value":{"type":"literal","content":"https://pic1.imgdb.cn/item/689aff2758cb8da5c81e64a2.png","rawMeta":{"type":1}}}},{"name":"start","input":{"type":"float","value":{"type":"literal","content":0,"rawMeta":{"type":4}}}},{"name":"draft_id","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"151918","name":"output.draft_id"},"rawMeta":{"type":1}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"string","name":"error","required":false},{"type":"object","name":"output","schema":[{"type":"string","name":"draft_url","required":false},{"type":"string","name":"draft_id","required":false}],"required":false},{"type":"string","name":"purchase_link","required":false},{"type":"boolean","name":"success","required":false}]},"_temp":{"bounds":{"x":1781.3705029177988,"y":-86.99999999999999,"width":360,"height":112},"externalData":{"icon":"https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747190144847346721_ZtIC02VX5J.png?lk3s=cd508e2b&x-expires=1757584231&x-signature=U2UUrn5PzZLQLLYawyaL6pmWAbA%3D","apiName":"add_image","pluginID":"7503106218777395219","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"description":"遗弃不用,用intro_animation代替。入场动画,从飞书文档中查看支持的入场动画","input":{},"name":"animation","required":false,"type":"string"},{"description":"组合动画持续时间,单位秒","input":{},"name":"combo_animation_duration","required":false,"type":"float"},{"description":"蒙版类型,支持:线性、镜面、圆形、矩形、爱心、星形","input":{},"name":"mask_type","required":false,"type":"string"},{"description":"轨道相对位置,越大越靠前","input":{},"name":"relative_index","required":false,"type":"integer"},{"defaultValue":0.5,"description":"遗弃不用,用intro_animation_duration代替。入场动画持续时间,单位秒, default value is 0.5","input":{},"name":"animation_duration","required":false,"type":"float"},{"description":"组合动画,从飞书文档中查看支持的组合动画","input":{},"name":"combo_animation","required":false,"type":"string"},{"description":"结束时间,单位秒","input":{},"name":"end","required":true,"type":"float"},{"description":"蒙版的羽化参数,取值范围0~100,默认无羽化","input":{},"name":"mask_feather","required":false,"type":"float"},{"description":"垂直方向缩放","input":{},"name":"scale_y","required":false,"type":"float"},{"description":"垂直方向移动,1表示向上移动1个画布高度","input":{},"name":"transform_y","required":false,"type":"float"},{"defaultValue":0.5,"description":"蒙版的主要尺寸,以占素材高度的比例表示,默认为0.5, default value is 0.5","input":{},"name":"mask_size","required":false,"type":"float"},{"description":"转场效果,从飞书文档中查看支持的转场动画","input":{},"name":"transition","required":false,"type":"string"},{"description":"如果想基于已有的草稿继续编辑,这里填上次的草稿id,否则将创建新草稿","input":{},"name":"draft_id","required":false,"type":"string"},{"description":"图片链接","input":{},"name":"image_url","required":true,"type":"string"},{"description":"入场动画持续时间,单位秒","input":{},"name":"intro_animation_duration","required":false,"type":"float"},{"description":"矩形蒙版的圆角参数,仅在蒙版类型为矩形时允许设置,取值范围0~100","input":{},"name":"mask_round_corner","required":false,"type":"float"},{"description":"水平方向缩放","input":{},"name":"scale_x","required":false,"type":"float"},{"defaultValue":"C:\\Users\\Administrator\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft","description":"(遗弃,请在save_draft方法设置草稿路径)草稿文件夹路径,在设置->全局设置->草稿位置","input":{},"name":"draft_folder","required":false,"type":"string"},{"description":"视频高度,单位像素","input":{},"name":"height","required":false,"type":"float"},{"description":"蒙版顺时针旋转的角度,默认不旋转","input":{},"name":"mask_rotation","required":false,"type":"float"},{"description":"转场持续时间,单位秒","input":{},"name":"transition_duration","required":false,"type":"float"},{"description":"视频宽度,单位像素","input":{},"name":"width","required":false,"type":"float"},{"description":"蒙版中心点Y坐标(以素材的像素为单位),默认设置在素材中心","input":{},"name":"mask_center_y","required":false,"type":"float"},{"description":"背景高斯模糊,可选1,2,3,4四档,越大越模糊","input":{},"name":"background_blur","required":false,"type":"integer"},{"description":"出场动画持续时间,单位秒","input":{},"name":"outro_animation_duration","required":false,"type":"float"},{"description":"轨道名称","input":{},"name":"track_name","required":false,"type":"string"},{"defaultValue":false,"description":"是否反转蒙版,默认不反转, default value is false","input":{},"name":"mask_invert","required":false,"type":"boolean"},{"description":"矩形蒙版的宽度,仅在蒙版类型为矩形时允许设置,以占素材宽度的比例表示","input":{},"name":"mask_rect_width","required":false,"type":"float"},{"description":"出场动画,从飞书文档中查看支持的出场动画","input":{},"name":"outro_animation","required":false,"type":"string"},{"description":"蒙版中心点X坐标(以素材的像素为单位),默认设置在素材中心","input":{},"name":"mask_center_x","required":false,"type":"float"},{"description":"入场动画,从飞书文档中查看支持的入场动画","input":{},"name":"intro_animation","required":false,"type":"string"},{"description":"开始时间,单位秒","input":{},"name":"start","required":true,"type":"float"},{"description":"水平方向移动,1表示向右移动1个画布宽度","input":{},"name":"transform_x","required":false,"type":"float"}],"outputs":[{"input":{},"name":"purchase_link","required":false,"type":"string"},{"input":{},"name":"success","required":false,"type":"boolean"},{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"output","required":false,"schema":[{"input":{},"name":"draft_id","required":false,"type":"string"},{"input":{},"name":"draft_url","required":false,"type":"string"}],"type":"object"}],"updateTime":1754985565,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"向视频中添加图片","title":"add_image","mainColor":"#CA61FF"}}},{"id":"163273","type":"4","meta":{"position":{"x":201.24450767548979,"y":-87}},"data":{"nodeMeta":{"description":"识别字幕","icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Plugin-v2.jpg","subtitle":"字幕识别_识别音视频字幕:speech_recognition","title":"speech_recognition"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7505701180081963027","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"speech_recognition","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7505701180081946643","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"字幕识别_识别音视频字幕","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"url","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"audio"},"rawMeta":{"type":1}}}},{"name":"license_key","input":{"type":"string","value":{"type":"literal","content":"08B88A2C-1D16-4CE1-982E-E3732F2655F3","rawMeta":{"type":1}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"string","name":"purchase_link","required":false},{"type":"string","name":"srt","required":false},{"type":"string","name":"srt_url","required":false},{"type":"boolean","name":"success","required":false},{"type":"list","name":"words","schema":{"type":"object","schema":[{"type":"string","name":"text","required":false},{"type":"list","name":"words","schema":{"type":"object","schema":[{"type":"float","name":"end_time","required":false},{"type":"string","name":"text","required":false},{"type":"float","name":"begin_time","required":false}]},"required":false}]},"required":false},{"type":"string","name":"content","required":false},{"type":"string","name":"error","required":false}]},"_temp":{"bounds":{"x":21.244507675489785,"y":-87,"width":360,"height":112},"externalData":{"icon":"https://lf9-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747557199774072076_2049XEOw8V.png?lk3s=cd508e2b&x-expires=1757584231&x-signature=kla5IxtfRecePQN0S4tW7NRjDrc%3D","apiName":"speech_recognition","pluginID":"7505701180081946643","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"defaultValue":0,"description":"字体大小,不同编辑器对字体大小定义不同。这里采用剪映定义:font_size*10=像素, default value is 0","input":{},"name":"font_size","required":false,"type":"float"},{"defaultValue":"539C3FEB-74AE48D4-A964D52B-C520F801","description":"身份验证,可以在这里获取:https://www.coze.cn/store/project/7498257920212647946?bid=6g9oma7p44g00&entity_id=1, default value is 539C3FEB-74AE48D4-A964D52B-C520F801","input":{},"name":"license_key","required":false,"type":"string"},{"description":"播放链接","input":{},"name":"url","required":true,"type":"string"},{"defaultValue":0,"description":"屏幕宽度,像素大小, default value is 0","input":{},"name":"width","required":false,"type":"float"}],"outputs":[{"input":{},"name":"srt","required":false,"type":"string"},{"input":{},"name":"srt_url","required":false,"type":"string"},{"input":{},"name":"success","required":false,"type":"boolean"},{"input":{},"name":"words","required":false,"schema":{"schema":[{"input":{},"name":"text","required":false,"type":"string"},{"input":{},"name":"words","required":false,"schema":{"schema":[{"input":{},"name":"begin_time","required":false,"type":"float"},{"input":{},"name":"end_time","required":false,"type":"float"},{"input":{},"name":"text","required":false,"type":"string"}],"type":"object"},"type":"list"}],"type":"object"},"type":"list"},{"input":{},"name":"content","required":false,"type":"string"},{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"purchase_link","required":false,"type":"string"}],"updateTime":1754989695,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"识别字幕","title":"speech_recognition","mainColor":"#CA61FF"}}},{"id":"104868","type":"4","meta":{"position":{"x":1110.202085075201,"y":-86.99999999999999}},"data":{"nodeMeta":{"description":"获取时长","icon":"https://p6-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/d3b11847a234484ab18b4c0a5acfb1bb~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757582041&x-signature=zCiw6FE2smf6WarlWxzAxXKI4i0%3D","subtitle":"视频剪辑_剪映草稿助手:get_duration","title":"get_duration"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7514493672046510095","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"get_duration","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7503106218777395219","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"视频剪辑_剪映草稿助手","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"url","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"audio"},"rawMeta":{"type":1}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"object","name":"output","schema":[{"type":"float","name":"duration","required":false},{"type":"string","name":"video_url","required":false}],"required":false},{"type":"string","name":"purchase_link","required":false},{"type":"boolean","name":"success","required":false},{"type":"string","name":"error","required":false}]},"_temp":{"bounds":{"x":930.202085075201,"y":-86.99999999999999,"width":360,"height":112},"externalData":{"icon":"https://lf6-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747190144847346721_ZtIC02VX5J.png?lk3s=cd508e2b&x-expires=1757584231&x-signature=t3IWKstikOW7M7bbrFUt8ZWWFj0%3D","apiName":"get_duration","pluginID":"7503106218777395219","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"description":"链接","input":{},"name":"url","required":true,"type":"string"}],"outputs":[{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"output","required":false,"schema":[{"input":{},"name":"duration","required":false,"type":"float"},{"input":{},"name":"video_url","required":false,"type":"string"}],"type":"object"},{"input":{},"name":"purchase_link","required":false,"type":"string"},{"input":{},"name":"success","required":false,"type":"boolean"}],"updateTime":1754985565,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"获取时长","title":"get_duration","mainColor":"#CA61FF"}}},{"id":"117999","type":"21","meta":{"position":{"x":1520.202085075201,"y":-74},"canvasPosition":{"x":1478.6214429974773,"y":332.3224972435221}},"data":{"inputs":{"inputParameters":[{"name":"input","input":{"type":"list","schema":{"type":"object","schema":[{"type":"string","name":"text","required":false},{"type":"list","name":"words","schema":{"type":"object","schema":[{"type":"float","name":"end_time","required":false},{"type":"string","name":"text","required":false},{"type":"float","name":"begin_time","required":false}]},"required":false}]},"value":{"type":"ref","content":{"source":"block-output","blockID":"163273","name":"words"},"rawMeta":{"type":103}}}}],"loopCount":{"type":"integer","value":{"type":"literal","content":"10"}},"loopType":"array","variableParameters":[]},"nodeMeta":{"description":"用于通过设定循环次数和逻辑,重复执行一系列任务","icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg","mainColor":"#00B2B2","subTitle":"循环","title":"循环"},"outputs":[]},"blocks":[{"id":"161273","type":"9","meta":{"position":{"x":0,"y":100}},"data":{"inputs":{"inputDefs":[{"input":{},"name":"words","required":false,"schema":[{"name":"text","required":false,"type":"string"},{"name":"words","required":false,"schema":{"schema":[{"name":"end_time","required":false,"type":"float"},{"name":"text","required":false,"type":"string"},{"name":"begin_time","required":false,"type":"float"}],"type":"object"},"type":"list"}],"type":"object"},{"input":{},"name":"draft_id","required":false,"type":"string"}],"inputParameters":[{"name":"draft_id","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"151918","name":"output.draft_id"},"rawMeta":{"type":1}}}},{"name":"words","input":{"type":"object","schema":[{"type":"string","name":"text","required":false},{"type":"list","name":"words","schema":{"type":"object","schema":[{"type":"float","name":"end_time","required":false},{"type":"string","name":"text","required":false},{"type":"float","name":"begin_time","required":false}]},"required":false}],"value":{"type":"ref","content":{"source":"block-output","blockID":"117999","name":"input"},"rawMeta":{"type":6}}}}],"settingOnError":{},"spaceId":"7472683780642258985","type":0,"workflowId":"7537629037804470323","workflowVersion":"v0.0.4"},"nodeMeta":{"description":"words_001_sub_879000","icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Workflow-v2.jpg","isImageflow":false,"title":"words_001_sub_879000"},"outputs":[]},"_temp":{"bounds":{"x":1298.6214429974773,"y":432.3224972435221,"width":360,"height":112},"externalData":{"description":"words_001_sub_879000","icon":"https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/workflow.png?lk3s=81d4c505&x-expires=1754995834&x-signature=FYCRGr3go%2FnFMp4NwB6CWEXhWuk%3D","isImageflow":false,"title":"words_001_sub_879000","commit_id":"Bot_7537629037804470323_Publish_7537634183951220777","create_time":1754991021,"creator":{"avatar_url":"https://res.volccdn.com/obj/volc-console-fe/vconsole-static/cloudidentity.avartar-huoshan.9f69c68a.jpg","id":"2830571853585849","name":"RootUser_2104214584","self":true},"desc":"words_001_sub_879000","end_type":0,"flow_mode":0,"flow_version":"v0.0.4","flow_version_desc":"","icon_uri":"plugin_icon/workflow.png","is_project":false,"latest_flow_version":"v0.0.4","latest_flow_version_desc":"4","name":"words_001_sub_879000","output_nodes":[],"plugin_id":"7537629045962358811","space_id":"7472683780642258985","update_time":1754992221,"version":"","workflow_id":"7537629037804470323","inputsDefinition":[{"input":{},"name":"words","required":false,"schema":[{"name":"text","required":false,"type":"string"},{"name":"words","required":false,"schema":{"schema":[{"name":"end_time","required":false,"type":"float"},{"name":"text","required":false,"type":"string"},{"name":"begin_time","required":false,"type":"float"}],"type":"object"},"type":"list"}],"type":"object"},{"input":{},"name":"draft_id","required":false,"type":"string"}],"latestVersion":"v0.0.4","mainColor":"#00B83E"}}}],"edges":[{"sourceNodeID":"117999","targetNodeID":"161273","sourcePortID":"loop-function-inline-output"},{"sourceNodeID":"161273","targetNodeID":"117999","targetPortID":"loop-function-inline-input"}],"_temp":{"bounds":{"x":1340.202085075201,"y":-74,"width":360,"height":138},"externalData":{"icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg","description":"用于通过设定循环次数和逻辑,重复执行一系列任务","title":"循环","mainColor":"#00B2B2"}}},{"id":"124458","type":"4","meta":{"position":{"x":2371.370502917799,"y":-90.25}},"data":{"nodeMeta":{"title":"add_audio","icon":"https://p3-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/d3b11847a234484ab18b4c0a5acfb1bb~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757583845&x-signature=f2X8zzxn%2BoMi6SwBDUT14w%2B2iqk%3D","subtitle":"视频剪辑_剪映草稿助手:add_audio","description":"添加音频"},"inputs":{"apiParam":[{"name":"apiID","input":{"type":"string","value":{"type":"literal","content":"7505052737164410906","rawMeta":{"type":1}}}},{"name":"apiName","input":{"type":"string","value":{"type":"literal","content":"add_audio","rawMeta":{"type":1}}}},{"name":"pluginID","input":{"type":"string","value":{"type":"literal","content":"7503106218777395219","rawMeta":{"type":1}}}},{"name":"pluginName","input":{"type":"string","value":{"type":"literal","content":"视频剪辑_剪映草稿助手","rawMeta":{"type":1}}}},{"name":"pluginVersion","input":{"type":"string","value":{"type":"literal","content":"","rawMeta":{"type":1}}}},{"name":"tips","input":{"type":"string","value":{"type":"literal","content":"","rawMeta":{"type":1}}}},{"name":"outDocLink","input":{"type":"string","value":{"type":"literal","content":"","rawMeta":{"type":1}}}}],"inputParameters":[{"name":"audio_url","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"audio"},"rawMeta":{"type":1}}}},{"name":"draft_id","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"151918","name":"output.draft_id"},"rawMeta":{"type":1}}}},{"name":"target_start","input":{"type":"float","value":{"type":"literal","content":0,"rawMeta":{"type":4}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"string","name":"purchase_link","required":false},{"type":"boolean","name":"success","required":false},{"type":"string","name":"error","required":false},{"type":"object","name":"output","schema":[{"type":"string","name":"draft_id","required":false},{"type":"string","name":"draft_url","required":false}],"required":false}]},"_temp":{"bounds":{"x":2191.370502917799,"y":-90.25,"width":360,"height":112},"externalData":{"icon":"https://lf26-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747190144847346721_ZtIC02VX5J.png?lk3s=cd508e2b&x-expires=1757584332&x-signature=5i6sAn9gEtBqX3AW54qn6AJHdzU%3D","apiName":"add_audio","pluginID":"7503106218777395219","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"defaultValue":"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20240830/dzkngm/%E9%BE%99%E5%A9%89.mp3","description":"音频链接, default value is https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20240830/dzkngm/%E9%BE%99%E5%A9%89.mp3","input":{},"name":"audio_url","required":true,"type":"string"},{"defaultValue":1,"description":"变速, default value is 1","input":{},"name":"speed","required":false,"type":"float"},{"description":"轨道名称","input":{},"name":"track_name","required":false,"type":"string"},{"defaultValue":1,"description":"音量,取值范围[0,1], default value is 1","input":{},"name":"volume","required":false,"type":"float"},{"description":"截取原始素材结束时间","input":{},"name":"end","required":false,"type":"float"},{"defaultValue":0,"description":"截取原始素材开始时间, default value is 0","input":{},"name":"start","required":false,"type":"float"},{"description":"目标轨道开始时间","input":{},"name":"target_start","required":false,"type":"float"},{"defaultValue":"C:\\Users\\Administrator\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft","description":"草稿文件夹路径,在设置->全局设置->草稿位置, default value is C:\\Users\\Administrator\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft","input":{},"name":"draft_folder","required":false,"type":"string"},{"description":"如果想基于已有的草稿继续编辑,这里填上次的草稿id","input":{},"name":"draft_id","required":false,"type":"string"},{"description":"素材时长,单位s,主动设置可以大幅提升节点速度","input":{},"name":"duration","required":false,"type":"float"},{"description":"音效参数列表","input":{},"name":"effect_params","required":false,"schema":{"type":"float"},"type":"list"},{"description":"场景音效名","input":{},"name":"effect_type","required":false,"type":"string"}],"outputs":[{"input":{},"name":"purchase_link","required":false,"type":"string"},{"input":{},"name":"success","required":false,"type":"boolean"},{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"output","required":false,"schema":[{"input":{},"name":"draft_id","required":false,"type":"string"},{"input":{},"name":"draft_url","required":false,"type":"string"}],"type":"object"}],"updateTime":1754985565,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"添加音频","title":"add_audio","mainColor":"#CA61FF"}}}],"edges":[{"sourceNodeID":"163273","targetNodeID":"151918"},{"sourceNodeID":"151918","targetNodeID":"104868"},{"sourceNodeID":"117999","targetNodeID":"116289","sourcePortID":"loop-output"},{"sourceNodeID":"116289","targetNodeID":"124458"},{"sourceNodeID":"104868","targetNodeID":"117999"}]},"bounds":{"x":21.244507675489785,"y":-90.25,"width":2530.1259952423093,"height":154.25}} +``` + +## 子工作流 +``` +{"type":"coze-workflow-clipboard-data","source":{"workflowId":"7537629037804470323","flowMode":0,"spaceId":"7472683780642258985","isDouyin":false,"host":"www.coze.cn"},"json":{"nodes":[{"id":"104882","type":"21","meta":{"position":{"x":1515.0475400760736,"y":125.0817982952324},"canvasPosition":{"x":1378.7425180584742,"y":552.0873672761959}},"data":{"inputs":{"inputParameters":[{"name":"words","input":{"type":"list","schema":{"type":"object","schema":[{"type":"float","name":"end_time","required":false},{"type":"string","name":"text","required":false},{"type":"float","name":"begin_time","required":false}]},"value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"words.words"},"rawMeta":{"type":103}}}}],"loopCount":{"type":"integer","value":{"type":"literal","content":"10"}},"loopType":"array","variableParameters":[]},"nodeMeta":{"description":"用于通过设定循环次数和逻辑,重复执行一系列任务","icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg","mainColor":"#00B2B2","subTitle":"循环","title":"循环"},"outputs":[]},"blocks":[{"id":"106954","type":"4","meta":{"position":{"x":736.8905568920494,"y":100}},"data":{"nodeMeta":{"description":"添加文字","icon":"https://p26-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/d3b11847a234484ab18b4c0a5acfb1bb~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757580241&x-signature=OrOCpYsprFwsowGxGzxyuRaqq2A%3D","subtitle":"视频剪辑_剪映草稿助手:add_text","title":"add_text"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7505380341906178083","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"add_text","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7503106218777395219","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"视频剪辑_剪映草稿助手","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"end","input":{"type":"float","value":{"type":"ref","content":{"source":"block-output","blockID":"180951","name":"result"},"rawMeta":{"type":4}}}},{"name":"start","input":{"type":"float","value":{"type":"ref","content":{"source":"block-output","blockID":"157989","name":"result"},"rawMeta":{"type":4}}}},{"name":"text","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"words.text"},"rawMeta":{"type":1}}}},{"name":"background_alpha","input":{"type":"float","value":{"type":"literal","content":1,"rawMeta":{"type":4}}}},{"name":"background_color","input":{"type":"string","value":{"type":"literal","content":"#000000","rawMeta":{"type":1}}}},{"name":"border_alpha","input":{"type":"float","value":{"type":"literal","content":1,"rawMeta":{"type":4}}}},{"name":"border_color","input":{"type":"string","value":{"type":"literal","content":"#FFFFFF","rawMeta":{"type":1}}}},{"name":"border_width","input":{"type":"float","value":{"type":"literal","content":40,"rawMeta":{"type":4}}}},{"name":"draft_id","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"draft_id"},"rawMeta":{"type":1}}}},{"name":"fixed_width","input":{"type":"float","value":{"type":"literal","content":0.7,"rawMeta":{"type":4}}}},{"name":"font","input":{"type":"string","value":{"type":"literal","content":"金陵体","rawMeta":{"type":1}}}},{"name":"font_color","input":{"type":"string","value":{"type":"literal","content":"#000000","rawMeta":{"type":1}}}},{"name":"font_size","input":{"type":"float","value":{"type":"literal","content":8,"rawMeta":{"type":4}}}},{"name":"text_styles","input":{"type":"list","schema":{"type":"object"},"value":{"type":"ref","content":{"source":"block-output","blockID":"193548","name":"text_styles"},"rawMeta":{"type":103}}}},{"name":"track_name","input":{"type":"string","value":{"type":"literal","content":"text_main","rawMeta":{"type":1}}}},{"name":"transform_y","input":{"type":"float","value":{"type":"literal","content":-0.6,"rawMeta":{"type":4}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"object","name":"output","schema":[{"type":"string","name":"draft_id","required":false},{"type":"string","name":"draft_url","required":false}],"required":false},{"type":"string","name":"purchase_link","required":false},{"type":"boolean","name":"success","required":false},{"type":"string","name":"error","required":false}]},"_temp":{"bounds":{"x":1935.6330749505237,"y":652.0873672761959,"width":360,"height":112},"externalData":{"icon":"https://lf6-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/332473957890636_1747190144847346721_ZtIC02VX5J.png?lk3s=cd508e2b&x-expires=1757584798&x-signature=ZLtE4uFSvQ7XXTkzmQ%2FnoIUsBYo%3D","apiName":"add_text","pluginID":"7503106218777395219","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7439344939257495552","inputs":[{"description":"文本","input":{},"name":"text","required":true,"type":"string"},{"description":"轨道名称","input":{},"name":"track_name","required":false,"type":"string"},{"description":"视频宽度","input":{},"name":"width","required":false,"type":"float"},{"description":"背景透明度(范围0.0-1.0)","input":{},"name":"background_alpha","required":false,"type":"float"},{"description":"入场动画,支持的动画参考文档","input":{},"name":"intro_animation","required":false,"type":"string"},{"defaultValue":-1,"description":"高度限制,-1表示不限制,1表示一个画布高度,默认不限制, default value is -1","input":{},"name":"fixed_height","required":false,"type":"float"},{"defaultValue":"思源中宋","description":"字体,可选字体参考文档, default value is 思源中宋","input":{},"name":"font","required":false,"type":"string"},{"description":"文字透明度(范围0.0-1.0)","input":{},"name":"font_alpha","required":false,"type":"float"},{"defaultValue":8,"description":"字体大小, default value is 8","input":{},"name":"font_size","required":false,"type":"float"},{"description":"入场动画持续时间,单位s","input":{},"name":"intro_duration","required":false,"type":"float"},{"description":"开始时间","input":{},"name":"start","required":true,"type":"float"},{"defaultValue":0,"description":"背景样式(0 或者2), default value is 0","input":{},"name":"background_style","required":false,"type":"integer"},{"defaultValue":1,"description":"描边透明度(范围0.0-1.0), default value is 1","input":{},"name":"border_alpha","required":false,"type":"float"},{"description":"描边宽度","input":{},"name":"border_width","required":false,"type":"float"},{"description":"如果想基于已有的草稿继续编辑,这里填上次的草稿id","input":{},"name":"draft_id","required":false,"type":"string"},{"defaultValue":-1,"description":"宽度限制,-1表示不限制,1表示一个画布宽度,默认不限制, default value is -1","input":{},"name":"fixed_width","required":false,"type":"float"},{"description":"分段设置文本样式","input":{},"name":"text_styles","required":false,"schema":{"schema":[{"description":"边框","input":{},"name":"border","required":false,"schema":[{"description":"透明度,1表示不透明,0表示透明","input":{},"name":"alpha","required":false,"type":"float"},{"description":"颜色,例如#FFFFFF","input":{},"name":"color","required":false,"type":"string"},{"description":"宽度","input":{},"name":"width","required":false,"type":"float"}],"type":"object"},{"description":"结束字符位置,不包含","input":{},"name":"end","required":false,"type":"integer"},{"description":"字体","input":{},"name":"font","required":false,"type":"string"},{"description":"开始字符位置,包含","input":{},"name":"start","required":false,"type":"integer"},{"description":"文本样式","input":{},"name":"style","required":false,"schema":[{"description":"字体大小","input":{},"name":"size","required":false,"type":"integer"},{"description":"是否下划线","input":{},"name":"underline","required":false,"type":"boolean"},{"description":"是否加粗","input":{},"name":"bold","required":false,"type":"boolean"},{"description":"颜色,例如#FFFFFF","input":{},"name":"color","required":false,"type":"string"},{"description":"是否倾斜","input":{},"name":"italic","required":false,"type":"boolean"}],"type":"object"}],"type":"object"},"type":"list"},{"description":"是否竖排","input":{},"name":"vertical","required":false,"type":"boolean"},{"defaultValue":"#000000","description":"背景颜色(HEX格式), default value is #000000","input":{},"name":"background_color","required":false,"type":"string"},{"defaultValue":"#000000","description":"描边颜色(HEX格式), default value is #000000","input":{},"name":"border_color","required":false,"type":"string"},{"defaultValue":"#ff0000","description":"字体颜色(HEX格式,如:#FF0000), default value is #ff0000","input":{},"name":"font_color","required":false,"type":"string"},{"description":"视频高度","input":{},"name":"height","required":false,"type":"float"},{"description":"出场动画,支持的动画参考文档","input":{},"name":"outro_animation","required":false,"type":"string"},{"description":"出场动画持续时间,单位s","input":{},"name":"outro_duration","required":false,"type":"float"},{"description":"Y轴位置(以视频中心为原点,对应视频高度)。 - 垂直移动像素 = transform_y * 视频高度","input":{},"name":"transform_x","required":false,"type":"float"},{"description":"X轴位置(以视频中心为原点,对应视频宽度), - 水平移动像素 = transform_x * 视频宽度","input":{},"name":"transform_y","required":false,"type":"float"},{"defaultValue":"C:\\Users\\Administrator\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft","description":"草稿文件夹路径,在设置->全局设置->草稿位置, default value is C:\\Users\\Administrator\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft","input":{},"name":"draft_folder","required":false,"type":"string"},{"description":"结束时间","input":{},"name":"end","required":true,"type":"float"}],"outputs":[{"input":{},"name":"success","required":false,"type":"boolean"},{"input":{},"name":"error","required":false,"type":"string"},{"input":{},"name":"output","required":false,"schema":[{"input":{},"name":"draft_id","required":false,"type":"string"},{"input":{},"name":"draft_url","required":false,"type":"string"}],"type":"object"},{"input":{},"name":"purchase_link","required":false,"type":"string"}],"updateTime":1754985565,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"添加文字","title":"add_text","mainColor":"#CA61FF"}}},{"id":"157989","type":"4","meta":{"position":{"x":-518.8821681035878,"y":100}},"data":{"nodeMeta":{"description":"求两个数的商,输入两个数,返回两个数的商","icon":"https://p3-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/56e839d759074f8db1dc249d563d3697~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757581459&x-signature=4adr7sF57tzkf%2F%2BXC%2Fgk9mFN6Z4%3D","subtitle":"简易计算器:division","title":"division"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7485626894092910627","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"division","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7485626894092894243","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"简易计算器","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"num_one","input":{"type":"float","value":{"type":"ref","content":{"source":"block-output","blockID":"104882","name":"words.begin_time"},"rawMeta":{"type":4}}}},{"name":"num_two","input":{"type":"float","value":{"type":"literal","content":1000,"rawMeta":{"type":4}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"float","name":"result","required":false}]},"_temp":{"bounds":{"x":679.8603499548864,"y":652.0873672761959,"width":360,"height":112},"externalData":{"icon":"https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/4308351770956154_1742883042571963859_9eIIucOt0W.jpg?lk3s=cd508e2b&x-expires=1757584798&x-signature=S3U1XbOD06780Y6xOLsfwBt7DKQ%3D","apiName":"division","pluginID":"7485626894092894243","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7477398004849688586","inputs":[{"description":"数字1","input":{},"name":"num_one","required":true,"type":"float"},{"description":"数字2","input":{},"name":"num_two","required":true,"type":"float"}],"outputs":[{"input":{},"name":"result","required":false,"type":"float"}],"updateTime":1754797602,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"求两个数的商,输入两个数,返回两个数的商","title":"division","mainColor":"#CA61FF"}}},{"id":"180951","type":"4","meta":{"position":{"x":-83.10944310795043,"y":100}},"data":{"nodeMeta":{"description":"求两个数的商,输入两个数,返回两个数的商","icon":"https://p3-flow-product-sign.byteimg.com/tos-cn-i-13w3uml6bg/56e839d759074f8db1dc249d563d3697~tplv-13w3uml6bg-resize:128:128.image?rk3s=2e2596fd&x-expires=1757581459&x-signature=4adr7sF57tzkf%2F%2BXC%2Fgk9mFN6Z4%3D","subtitle":"简易计算器:division","title":"division_1"},"inputs":{"apiParam":[{"input":{"type":"string","value":{"content":"7485626894092910627","rawMeta":{"type":1},"type":"literal"}},"name":"apiID"},{"input":{"type":"string","value":{"content":"division","rawMeta":{"type":1},"type":"literal"}},"name":"apiName"},{"input":{"type":"string","value":{"content":"7485626894092894243","rawMeta":{"type":1},"type":"literal"}},"name":"pluginID"},{"input":{"type":"string","value":{"content":"简易计算器","rawMeta":{"type":1},"type":"literal"}},"name":"pluginName"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"pluginVersion"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"tips"},{"input":{"type":"string","value":{"content":"","rawMeta":{"type":1},"type":"literal"}},"name":"outDocLink"}],"inputParameters":[{"name":"num_one","input":{"type":"float","value":{"type":"ref","content":{"source":"block-output","blockID":"104882","name":"words.end_time"},"rawMeta":{"type":4}}}},{"name":"num_two","input":{"type":"float","value":{"type":"literal","content":1000,"rawMeta":{"type":4}}}}],"settingOnError":{"processType":1,"timeoutMs":180000,"retryTimes":0}},"outputs":[{"type":"float","name":"result","required":false}]},"_temp":{"bounds":{"x":1115.6330749505237,"y":652.0873672761959,"width":360,"height":112},"externalData":{"icon":"https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/4308351770956154_1742883042571963859_9eIIucOt0W.jpg?lk3s=cd508e2b&x-expires=1757584798&x-signature=S3U1XbOD06780Y6xOLsfwBt7DKQ%3D","apiName":"division","pluginID":"7485626894092894243","pluginProductStatus":1,"pluginProductUnlistType":0,"pluginType":1,"spaceID":"7477398004849688586","inputs":[{"description":"数字1","input":{},"name":"num_one","required":true,"type":"float"},{"description":"数字2","input":{},"name":"num_two","required":true,"type":"float"}],"outputs":[{"input":{},"name":"result","required":false,"type":"float"}],"updateTime":1754797602,"channel_id":2,"latestVersionTs":"0","latestVersionName":"","versionName":"","description":"求两个数的商,输入两个数,返回两个数的商","title":"division","mainColor":"#CA61FF"}}},{"id":"193548","type":"5","meta":{"position":{"x":326.8905568920495,"y":100}},"data":{"nodeMeta":{"description":"编写代码,处理输入变量来生成返回值","icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg","title":"代码","subTitle":"代码"},"inputs":{"inputParameters":[{"name":"sentences","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"100001","name":"words.text"},"rawMeta":{"type":1}}}},{"name":"word","input":{"type":"string","value":{"type":"ref","content":{"source":"block-output","blockID":"104882","name":"words.text"},"rawMeta":{"type":1}}}}],"code":"# 在这里,您可以通过 'args' 获取节点中的输入变量,并通过 'ret' 输出结果\n# 'args' 已经被正确地注入到环境中\n# 下面是一个示例,首先获取节点的全部输入参数params,其次获取其中参数名为'input'的值:\n# params = args.params; \n# input = params['input'];\n# 下面是一个示例,输出一个包含多种数据类型的 'ret' 对象:\n# ret: Output = { \"name\": '小明', \"hobbies\": [\"看书\", \"旅游\"] };\nasync def main(args: Args) -> Output:\n params = args.params\n # 取 sentences 中的唯一一句文本\n sentence = params['sentences']\n target_word = params['word']\n \n text_styles = []\n word_len = len(target_word)\n sent_len = len(sentence)\n index = 0\n \n # 在单句中查找所有目标词\n while index <= sent_len - word_len:\n # 精确匹配目标词\n if sentence[index:index + word_len] == target_word:\n # 构建样式结构体,仅颜色改为紫色(#9900FF)\n style_entry = {\n \"start\": index, # 起始位置(包含)\n \"end\": index + word_len, # 结束位置(不包含)\n \"style\": {\n \"color\": \"#9900FF\" # 紫色\n }\n }\n text_styles.append(style_entry)\n # 跳过已匹配部分,避免重复匹配\n index += word_len\n else:\n index += 1\n \n return {\"text_styles\": text_styles}","language":3,"settingOnError":{"switch":false,"processType":1,"timeoutMs":60000,"retryTimes":0}},"outputs":[{"type":"string","name":"text_styles","required":false}]},"_temp":{"bounds":{"x":1525.6330749505237,"y":652.0873672761959,"width":360,"height":112},"externalData":{"icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg","description":"编写代码,处理输入变量来生成返回值","title":"代码","mainColor":"#00B2B2"}}}],"edges":[{"sourceNodeID":"193548","targetNodeID":"106954"},{"sourceNodeID":"106954","targetNodeID":"104882","targetPortID":"loop-function-inline-input"},{"sourceNodeID":"104882","targetNodeID":"157989","sourcePortID":"loop-function-inline-output"},{"sourceNodeID":"157989","targetNodeID":"180951"},{"sourceNodeID":"180951","targetNodeID":"193548"}],"_temp":{"bounds":{"x":1335.0475400760736,"y":125.0817982952324,"width":360,"height":138},"externalData":{"icon":"https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg","description":"用于通过设定循环次数和逻辑,重复执行一系列任务","title":"循环","mainColor":"#00B2B2"}}}],"edges":[]},"bounds":{"x":1335.0475400760736,"y":125.0817982952324,"width":360,"height":137.99999999999997}} +``` \ No newline at end of file From 341fc022a9daf9d051e2d94266fe6a597864a973 Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Tue, 12 Aug 2025 18:30:42 +0800 Subject: [PATCH 07/10] Update README-zh.md --- README-zh.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README-zh.md b/README-zh.md index 7215550..e49b6fe 100644 --- a/README-zh.md +++ b/README-zh.md @@ -259,7 +259,8 @@ mcp_client.call_tool("add_text", { ## 进群交流 -![交流群](https://github.com/user-attachments/assets/343c0f57-1551-49c1-bec3-c6bbcdbbbf32) +![交流群](https://github.com/user-attachments/assets/d1927a21-0d4e-4967-b6ad-bb1cbb202c5b) + - 反馈问题 - 功能建议 From 29fc42bfc4cbcdd11490e6a358d1cc7e96a0c9ca Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Wed, 13 Aug 2025 18:36:18 +0800 Subject: [PATCH 08/10] add 002 partten --- pattern/002-relationship.py | 606 ++++++++++++++++++++++++++++++++++++ pattern/README.md | 2 + 2 files changed, 608 insertions(+) create mode 100644 pattern/002-relationship.py diff --git a/pattern/002-relationship.py b/pattern/002-relationship.py new file mode 100644 index 0000000..615267a --- /dev/null +++ b/pattern/002-relationship.py @@ -0,0 +1,606 @@ +import json +import random +import requests + +# Set API keys +QWEN_API_KEY = "your qwen api key" +PEXELS_API_KEY = "your pexels api key" +CAPCUT_API_KEY = "your capcut api key" +LICENSE_KEY="your capcut license key", + + +def llm(query = ""): + """ + Call the Tongyi Qianwen large language model + + Parameters: + + Returns: + dict: Dictionary containing title and list of sentences + """ + + # Build system prompt + system_prompt = """ + * **Context:** You are an AI expert specializing in modern interpersonal relationships and emotional communication. Your knowledge base is built on a deep understanding of popular emotional content on social media, and you excel at interpreting the dynamics and perspectives of relationships in a relaxed, colloquial style. + + * **Objective:** When the user inputs "Give me some random returns", your goal is to **randomly create** advice about male-female emotions, behavioral habits, or relationship guidance. Your content must strictly mimic the unique style shown in the examples below. + + * **Style:** Your generated content should have the following characteristics: + + * **Structure:** Use a list format, with each point being a short, independent sentence. + * **Wording:** Use colloquial language, often using the "When..." sentence pattern to describe a scenario. + * **Theme:** Content should revolve around "how to understand the other person", "which behaviors are attractive", or "advice for a specific gender". + + * **Tone:** Your tone should be friendly, sincere, slightly teasing, like a friend sharing experiences on social media. + + * **Audience:** Your audience is anyone interested in modern emotional relationships who wants to get advice in a relaxed way. + + * **Response:** When you receive the instruction "Give me some random returns", please **randomly select one** from the following examples as your response. Or, you can **randomly generate** a new one with a completely consistent style, and return it in the same JSON format: + + **Example 1 (How to understand girls):** + + ```json + { + "title": "How to understand girls", + "sentences": [ + "Hands on her stomach (Insecure)", + "She leans on you (Feels safe)", + "Covers her smile (Thinks your going to judge)", + "Stops texting you (Feels like she is annoying you)", + "Says she is fine (She is everything but fine)", + "When she hugs you (You mean a lot to her)" + ] + } + ``` + + **Example 2 (Tips for girls):** + + ```json + { + "title": "Tips for the girls (From the guys)", + "sentences": [ + "99/100 guys dont know what hip dips are and actually love your stretch marks", + "We can't tell that you like us by just viewing our story, just message us", + "When he's out with his boys, let him have this time (this is very important)", + "'I'm not ready for a relationship' - unless your the luckiest girl in the world your not getting cuffed", + "As Bruno mars said, 'your perfect just the way you are' so just be you, it'll work" + ] + } + ``` + + **Example 3 (Things guys find attractive in girls):** + + ```json + { + "title": "Things girls do that guys find attractive", + "sentences": [ + "Bed hair when it's all messy >>>", + "When you come work out with us", + "Your sleepy voice in the morning or after a nap", + "When you wear our t-shirts as pyjamas", + "When you have a funny or really bad laugh", + "When you initiate ...", + "When your good with animals or animals like you" + ] + } + ``` + """ + + # Build user prompt + user_prompt = f"Randomly create advice about male-female emotions, behavioral habits, or relationship guidance, based on user input: {query}" + + # Prepare request data + url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions" + headers = { + "Authorization": f"Bearer {QWEN_API_KEY}", + "Content-Type": "application/json" + } + data = { + "model": "qwen-plus", + "messages": [ + { + "role": "system", + "content": system_prompt + }, + { + "role": "user", + "content": user_prompt + } + ], + "temperature": 0.7, + "max_tokens": 16384, + "response_format": {"type": "json_object"} + } + + try: + # Send HTTP request + response = requests.post(url, headers=headers, json=data, timeout=30) + + # Check response status + if response.status_code == 200: + response_data = response.json() + + # Extract content from response + if 'choices' in response_data and len(response_data['choices']) > 0: + content = response_data['choices'][0]['message']['content'] + + try: + # Parse JSON response + result = json.loads(content) + + # Ensure result contains necessary fields + if "title" in result and "sentences" in result: + return result + except json.JSONDecodeError: + pass # If JSON parsing fails, will return predefined example + + # If API call fails or parsing fails, print error message + print(f"Error: {response.status_code}, {response.text if hasattr(response, 'text') else 'No response text'}") + except Exception as e: + # Catch all possible exceptions + print(f"Exception occurred: {str(e)}") + + +def search_pexels_videos(query="twilight", min_duration=10, orientation="portrait", per_page=15): + """ + Call Pexels API to search for videos + + Parameters: + query (str): Search keyword, default is "twilight" + min_duration (int): Minimum video duration (seconds), default is 10 seconds + orientation (str): Video orientation, default is "portrait" + per_page (int): Number of results per page, default is 15 + + Returns: + list: List containing video information + """ + url = "https://api.pexels.com/videos/search" + headers = { + "Authorization": PEXELS_API_KEY + } + params = { + "query": query, + "orientation": orientation, + "per_page": per_page, + "min_duration": min_duration + } + + try: + response = requests.get(url, headers=headers, params=params) + + if response.status_code == 200: + data = response.json() + videos = [] + + for video in data.get("videos", []): + # Get video file information + video_files = video.get("video_files", []) + # Filter out 16:9 ratio video files + portrait_videos = [file for file in video_files + if file.get("width") and file.get("height") and + file.get("height") / file.get("width") > 1.7] # Close to 16:9 ratio + + if portrait_videos: + # Select highest quality video file + best_quality = max(portrait_videos, key=lambda x: x.get("width", 0) * x.get("height", 0)) + + videos.append({ + "id": video.get("id"), + "url": video.get("url"), + "image": video.get("image"), + "duration": video.get("duration"), + "user": video.get("user", {}).get("name"), + "video_url": best_quality.get("link"), + "width": best_quality.get("width"), + "height": best_quality.get("height"), + "file_type": best_quality.get("file_type") + }) + + if videos: + random_video = random.choice(videos) + return random_video['video_url'] + return [] + else: + print(f"Error: {response.status_code}, {response.text}") + return [] + except Exception as e: + print(f"Exception occurred: {str(e)}") + return [] + + +def create_capcut_draft(width=1080, height=1920): + """ + Call CapCut API to create a new draft + + Parameters: + width (int): Video width, default is 1080 + height (int): Video height, default is 1920 + + Returns: + dict: Dictionary containing draft ID and download URL, or error message if failed + """ + url = "https://open.capcutapi.top/cut_jianying/create_draft" + headers = { + "Authorization": f"Bearer {CAPCUT_API_KEY}", + "Content-Type": "application/json" + } + data = { + "width": width, + "height": height + } + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + + if result.get("success"): + return { + "success": True, + "draft_id": result.get("output", {}).get("draft_id"), + "draft_url": result.get("output", {}).get("draft_url") + } + else: + return { + "success": False, + "error": result.get("error", "Unknown error") + } + else: + return { + "success": False, + "error": f"HTTP Error: {response.status_code}", + "response": response.text + } + except Exception as e: + return { + "success": False, + "error": str(e) + } + + +def add_video_to_draft(draft_id, video_url): + """ + Call CapCut API to add video to draft + + Parameters: + draft_id (str): Draft ID + video_url (str): Video URL + + Returns: + dict: Dictionary containing draft ID and download URL, or error message if failed + """ + url = "https://open.capcutapi.top/cut_jianying/add_video" + headers = { + "Authorization": f"Bearer {CAPCUT_API_KEY}", + "Content-Type": "application/json" + } + data = { + "video_url": video_url, + "draft_id": draft_id, + "end": 10 # Set video duration to 10 seconds + } + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + + if result.get("success"): + return { + "success": True, + "draft_id": result.get("output", {}).get("draft_id"), + "draft_url": result.get("output", {}).get("draft_url") + } + else: + return { + "success": False, + "error": result.get("error", "Unknown error") + } + else: + return { + "success": False, + "error": f"HTTP Error: {response.status_code}", + "response": response.text + } + except Exception as e: + return { + "success": False, + "error": str(e) + } + +def add_text_to_draft(draft_id, text, font="ZY_Starry", +font_color="#FFFFFF", +background_color="#000000", +background_alpha=0.5, +background_style=2, +background_round_radius=10, + transform_y=0, + transform_x=0, + font_size=10.0, + fixed_width=0.6, + track_name="text_main"): + """ + Call CapCut API to add text to draft + + Parameters: + draft_id (str): Draft ID + text (str): Text content + start_time (float): Text start time on timeline (seconds), default is 0 + end_time (float): Text end time on timeline (seconds), default is 5 + font (str): Font, default is "ZY_Starry" + font_color (str): Font color, default is white + background_color (str): Background color, default is black + background_alpha (float): Background transparency, default is 0.5 + transform_y (float): Y-axis position offset, default is 0 + transform_x (float): X-axis position offset, default is 0 + font_size (float): Font size, default is 10.0 + + Returns: + dict: Dictionary containing draft ID and download URL, or error message if failed + """ + url = "https://open.capcutapi.top/cut_jianying/add_text" + headers = { + "Authorization": f"Bearer {CAPCUT_API_KEY}", + "Content-Type": "application/json" + } + data = { + "text": text, + "start": 0, + "end": 10, + "draft_id": draft_id, + "font": font, + "font_color": font_color, + "font_size": font_size, + "transform_y": transform_y, + "transform_x": transform_x, + "fixed_width": fixed_width, + "background_color": background_color, + "background_alpha": background_alpha, + "background_style": background_style, + "background_round_radius": background_round_radius, + "track_name": track_name + } + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + + if result.get("success"): + return { + "success": True, + "draft_id": result.get("output", {}).get("draft_id"), + "draft_url": result.get("output", {}).get("draft_url") + } + else: + return { + "success": False, + "error": result.get("error", "Unknown error") + } + else: + return { + "success": False, + "error": f"HTTP Error: {response.status_code}", + "response": response.text + } + except Exception as e: + return { + "success": False, + "error": str(e) + } + +def generate_video(draft_id, resolution="720P", framerate="24"): + """ + Call CapCut API to render video + + Parameters: + draft_id (str): Draft ID + license_key (str): License key + resolution (str): Video resolution, default is "720P" + framerate (str): Video frame rate, default is "24" + + Returns: + dict: Dictionary containing task ID, or error message if failed + """ + url = "https://open.capcutapi.top/cut_jianying/generate_video" + headers = { + "Authorization": f"Bearer {CAPCUT_API_KEY}", + "Content-Type": "application/json" + } + data = { + "draft_id": draft_id, + "license_key": LICENSE_KEY, + "resolution": resolution, + "framerate": framerate + } + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + + if result.get("success"): + return { + "success": True, + "task_id": result.get("output", {}).get("task_id") + } + else: + return { + "success": False, + "error": result.get("error", "Unknown error") + } + else: + return { + "success": False, + "error": f"HTTP Error: {response.status_code}", + "response": response.text + } + except Exception as e: + return { + "success": False, + "error": str(e) + } + +def check_task_status(task_id): + """ + Call CapCut API to check task status + + Parameters: + task_id (str): Task ID + + Returns: + dict: Dictionary containing task status and results, or error message if failed + """ + url = "https://open.capcutapi.top/cut_jianying/task_status" + headers = { + "Authorization": f"Bearer {CAPCUT_API_KEY}", + "Content-Type": "application/json" + } + data = { + "task_id": task_id + } + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + + if result.get("success"): + output = result.get("output", {}) + return { + "success": True, + "status": output.get("status"), + "progress": output.get("progress"), + "result": output.get("result"), # Video URL + "error": output.get("error") + } + else: + return { + "success": False, + "error": result.get("error", "Unknown error") + } + else: + return { + "success": False, + "error": f"HTTP Error: {response.status_code}", + "response": response.text + } + except Exception as e: + return { + "success": False, + "error": str(e) + } + + +# Example usage +if __name__ == "__main__": + + # Call LLM function and print result + result = llm() + print(json.dumps(result, indent=2, ensure_ascii=False)) + + # 1. Create draft + draft_result = create_capcut_draft() + print("Draft creation result:", json.dumps(draft_result, indent=2, ensure_ascii=False)) + + if draft_result.get("success"): + + draft_id = draft_result.get("draft_id") + + # 2. Search Pexels videos + video_url = search_pexels_videos() + print("Pexels video URL:", video_url) + + # 3. Add video to draft + if video_url: + add_result = add_video_to_draft(draft_result.get("draft_id"), video_url) + print("Add video result:", json.dumps(add_result, indent=2, ensure_ascii=False)) + + + # 5. Add title text + title_result = add_text_to_draft( + draft_id=draft_id, + text=result["title"], + font="ZY_Starry", # Use starry font + font_color="#FFFFFF", # White font + background_color="#000000", # Black background + background_alpha=1, # Background transparency + background_style=1, + background_round_radius=10, + transform_y=0.7, # Located at the top of the screen (1 is top edge, -1 is bottom edge) + transform_x=0, # Horizontally centered + font_size=13.0, # Larger font + track_name = "title", + fixed_width=0.6 + ) + print("Add title result:", json.dumps(title_result, indent=2, ensure_ascii=False)) + + # 6. Add sentence text + sentence_count = len(result["sentences"]) + for i, sentence in enumerate(result["sentences"]): + # Calculate vertical position - evenly distributed in the middle of the screen + transform_y = 0.5 - (1.1 * (i + 1) / (sentence_count + 1)) + + # Determine horizontal alignment - odd sentences left-aligned, even sentences right-aligned + if i % 2 == 0: # Odd sentences (counting from 0) + transform_x = -0.5 # Left-aligned + else: # Even sentences + transform_x = 0.5 # Right-aligned + + sentence_result = add_text_to_draft( + draft_id=draft_id, + text=sentence, + font="ZY_Fantasy", # Use fantasy font + font_color="#FFFFFF", # White font + transform_y=transform_y, # Vertical position + transform_x=transform_x, # Horizontal position (left-right alignment) + background_alpha=0, + font_size=7.0, # Smaller font + fixed_width=0.3, + track_name=f"text_{i}" + ) + print(f"Add sentence {i+1} result:", json.dumps(sentence_result, indent=2, ensure_ascii=False)) + + # 7. Render video + print("\nStarting video rendering...") + generate_result = generate_video(draft_id) + print("Video rendering request result:", json.dumps(generate_result, indent=2, ensure_ascii=False)) + + if generate_result.get("success"): + task_id = generate_result.get("task_id") + print(f"Task ID: {task_id}, starting to poll task status...") + + # 8. Poll task status + import time + max_attempts = 30 # Maximum 30 polling attempts + attempt = 0 + + while attempt < max_attempts: + status_result = check_task_status(task_id) + print(f"Poll count {attempt+1}, status:", json.dumps(status_result, indent=2, ensure_ascii=False)) + + if not status_result.get("success"): + print("Failed to check task status:", status_result.get("error")) + break + + status = status_result.get("status") + if status == "SUCCESS": + print("\nVideo rendering successful!") + print("Video URL:", status_result.get("result")) + break + elif status == "FAILED": + print("\nVideo rendering failed:", status_result.get("error")) + break + + # Wait 5 seconds before checking again + print("Waiting 5 seconds before checking again...") + time.sleep(5) + attempt += 1 + + if attempt >= max_attempts: + print("\nPolling timeout, please check task status manually later") \ No newline at end of file diff --git a/pattern/README.md b/pattern/README.md index af06c7a..da033f1 100644 --- a/pattern/README.md +++ b/pattern/README.md @@ -4,4 +4,6 @@ [![Words](https://img.youtube.com/vi/HLSHaJuNtBw/hqdefault.jpg)](https://www.youtube.com/watch?v=HLSHaJuNtBw) +## 002-relationship.py +[![Relationship](https://img.youtube.com/vi/f2Q1OI_SQZo/hqdefault.jpg)](https://www.youtube.com/watch?v=f2Q1OI_SQZo) From cce0500bc4f48694b063d49bd9ad8905777415d0 Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Sun, 17 Aug 2025 15:42:51 +0800 Subject: [PATCH 09/10] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b6a71ea..4c3e648 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,15 @@ Enjoy It! 😀😀😀 **Combine AI-generated images and videos using CapCutAPI** +[More](pattern) + [![Airbnb](https://img.youtube.com/vi/1zmQWt13Dx0/hqdefault.jpg)](https://www.youtube.com/watch?v=1zmQWt13Dx0) [![Horse](https://img.youtube.com/vi/IF1RDFGOtEU/hqdefault.jpg)](https://www.youtube.com/watch?v=IF1RDFGOtEU) [![Song](https://img.youtube.com/vi/rGNLE_slAJ8/hqdefault.jpg)](https://www.youtube.com/watch?v=rGNLE_slAJ8) + ## Key Features @@ -286,4 +289,4 @@ If you want to: -*Made with ❤️ by the CapCutAPI Community* \ No newline at end of file +*Made with ❤️ by the CapCutAPI Community* From 55c28c6b4af912917f83b4b96f02875271545956 Mon Sep 17 00:00:00 2001 From: sun-guannan Date: Sun, 17 Aug 2025 15:44:27 +0800 Subject: [PATCH 10/10] Update README.md --- pattern/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pattern/README.md b/pattern/README.md index da033f1..5cf49ef 100644 --- a/pattern/README.md +++ b/pattern/README.md @@ -2,8 +2,12 @@ ## 001-words.py +[source](001-words.py) + [![Words](https://img.youtube.com/vi/HLSHaJuNtBw/hqdefault.jpg)](https://www.youtube.com/watch?v=HLSHaJuNtBw) ## 002-relationship.py +[source](002-relationship.py) + [![Relationship](https://img.youtube.com/vi/f2Q1OI_SQZo/hqdefault.jpg)](https://www.youtube.com/watch?v=f2Q1OI_SQZo)