diff --git a/add_effect_impl.py b/add_effect_impl.py index 2015cab..211d7f9 100644 --- a/add_effect_impl.py +++ b/add_effect_impl.py @@ -1,12 +1,13 @@ from pyJianYingDraft import trange, Video_scene_effect_type, Video_character_effect_type, CapCut_Video_scene_effect_type, CapCut_Video_character_effect_type, exceptions import pyJianYingDraft as draft -from typing import Optional, Dict, List, Union +from typing import Optional, Dict, List, Union, Literal from create_draft import get_or_create_draft from util import generate_draft_url from settings import IS_CAPCUT_ENV def add_effect_impl( effect_type: str, # Changed to string type + effect_category: Literal["scene", "character"], start: float = 0, end: float = 3.0, draft_id: Optional[str] = None, @@ -18,6 +19,7 @@ def add_effect_impl( """ Add an effect to the specified draft :param effect_type: Effect type name, will be matched from Video_scene_effect_type or Video_character_effect_type + :param effect_category: Effect category, "scene" or "character", default "scene" :param start: Start time (seconds), default 0 :param end: End time (seconds), default 3 seconds :param draft_id: Draft ID, if None or corresponding zip file not found, a new draft will be created @@ -38,20 +40,35 @@ def add_effect_impl( duration = end - start t_range = trange(f"{start}s", f"{duration}s") - # Dynamically get effect type object + # Select the corresponding effect type based on effect category and environment + effect_enum = None if IS_CAPCUT_ENV: # If in CapCut environment, use CapCut effects - effect_enum = CapCut_Video_scene_effect_type[effect_type] - if effect_enum is None: - effect_enum = CapCut_Video_character_effect_type[effect_type] + if effect_category == "scene": + try: + effect_enum = CapCut_Video_scene_effect_type[effect_type] + except: + effect_enum = None + elif effect_category == "character": + try: + effect_enum = CapCut_Video_character_effect_type[effect_type] + except: + effect_enum = None else: # Default to using JianYing effects - effect_enum = Video_scene_effect_type[effect_type] - if effect_enum is None: - effect_enum = Video_character_effect_type[effect_type] + if effect_category == "scene": + try: + effect_enum = Video_scene_effect_type[effect_type] + except: + effect_enum = None + elif effect_category == "character": + try: + effect_enum = Video_character_effect_type[effect_type] + except: + effect_enum = None if effect_enum is None: - raise ValueError(f"Unknown effect type: {effect_type}") + raise ValueError(f"Unknown {effect_category} effect type: {effect_type}") # Add effect track (only when track doesn't exist) if track_name is not None: diff --git a/capcut_server.py b/capcut_server.py index 79c475a..ea460ba 100644 --- a/capcut_server.py +++ b/capcut_server.py @@ -642,6 +642,7 @@ def add_effect(): # Get required parameters effect_type = data.get('effect_type') # Effect type name, will match from Video_scene_effect_type or Video_character_effect_type start = data.get('start', 0) # Start time (seconds), default 0 + effect_category = data.get('effect_category', "scene") # Effect category, "scene" or "character", default "scene" end = data.get('end', 3.0) # End time (seconds), default 3 seconds draft_id = data.get('draft_id') # Draft ID, if None or corresponding zip file not found, create new draft track_name = data.get('track_name', "effect_01") # Track name, can be omitted when there is only one effect track @@ -665,6 +666,7 @@ def add_effect(): # Call add_effect_impl method draft_result = add_effect_impl( effect_type=effect_type, + effect_category=effect_category, start=start, end=end, draft_id=draft_id, diff --git a/example.py b/example.py index 5afd88f..5994bed 100644 --- a/example.py +++ b/example.py @@ -9,6 +9,8 @@ import threading from pyJianYingDraft.text_segment import TextStyleRange, Text_style, Text_border from util import hex_to_rgb +import shutil +import os # Base URL of the service, please modify according to actual situation BASE_URL = f"http://localhost:{PORT}" @@ -291,6 +293,7 @@ def add_video_impl(video_url, start=None, end=None, width=None, height=None, tra data = { "video_url": video_url, "height": height, + "draft_id": draft_id, "track_name": track_name, "transform_y": transform_y, "scale_x": scale_x, @@ -325,7 +328,7 @@ def add_video_impl(video_url, start=None, end=None, width=None, height=None, tra return make_request("add_video", data) def add_effect(effect_type, start, end, draft_id=None, track_name="effect_01", - params=None, width=1080, height=1920): + params=None, width=1080, height=1920, effect_category=None): """API call to add effect""" data = { "effect_type": effect_type, @@ -337,6 +340,9 @@ def add_effect(effect_type, start, end, draft_id=None, track_name="effect_01", "height": height } + if effect_category: + data["effect_category"] = effect_category + if draft_id: data["draft_id"] = draft_id @@ -364,6 +370,59 @@ def test_effect_01(): return effect_result +def test_effect_02(): + """Test service for adding effects""" + # draft_folder = "/Users/sunguannan/Movies/JianyingPro/User Data/Projects/com.lveditor.draft" + draft_folder = "/Users/sunguannan/Movies/CapCut/User Data/Projects/com.lveditor.draft" + + print("\nTest: Adding effects") + # First add video track + image_result = add_video_impl( + video_url="https://pan.superbed.cn/share/1nbrg1fl/jimeng_daweidai.mp4", + start=0, + end=3.0, + target_start=0, + width=1080, + height=1920 + ) + print(f"Video added successfully! {image_result['output']['draft_id']}") + image_result = add_video_impl( + video_url="https://pan.superbed.cn/share/1nbrg1fl/jimeng_daweidai.mp4", + draft_id=image_result['output']['draft_id'], + start=0, + end=3.0, + target_start=3, + ) + print(f"Video added successfully! {image_result['output']['draft_id']}") + + # Then add effect + effect_result = add_effect( + effect_type="Like", + effect_category="character", # Explicitly specify as character effect + start=3, + end=6, + draft_id=image_result['output']['draft_id'], + track_name="effect_01" + ) + print(f"Effect adding result: {effect_result}") + print(save_draft_impl(effect_result['output']['draft_id'], draft_folder)) + + source_folder = os.path.join(os.getcwd(), effect_result['output']['draft_id']) + destination_folder = os.path.join(draft_folder, effect_result['output']['draft_id']) + + if os.path.exists(source_folder): + print(f"Moving {effect_result['output']['draft_id']} to {draft_folder}") + shutil.move(source_folder, destination_folder) + print("Folder moved successfully!") + else: + print(f"Source folder {source_folder} does not exist") + + # Add log to prompt user to find the draft in CapCut + print(f"\n===== IMPORTANT =====\nPlease open CapCut and find the draft named '{effect_result['output']['draft_id']}'\n======================") + + # Return the first test result for subsequent operations (if any) + return effect_result + def test_text(): """Test adding text with various features""" draft_folder = CAPCUT_DRAFT_FOLDER @@ -2280,36 +2339,37 @@ def test_transition_02(): print("Unable to get draft ID, skipping save operation.") if __name__ == "__main__": - test01() - test02() - test_effect_01() # Run effect test - test_audio01() - test_audio02() - test_audio03() - test_audio04() - test_image01() - test_image02() - test_image03() - test_image04() - # test_video() - test_video_02() - test_text() - test_video_track01() - test_video_track02() - test_video_track03() - test_video_track04() - test_keyframe() - test_keyframe_02() - test_subtitle_01() - test_subtitle_02() - test_subtitle() - test_stiker_01() - test_stiker_02() - test_stiker_03() - test_transition_01() - test_transition_02() - # test_generate_image01() - # test_generate_image02() - # test_speech_01() - test_mask_01() - test_mask_02() + # test01() + # test02() + # test_effect_01() # Run effect test + test_effect_02() + # test_audio01() + # test_audio02() + # test_audio03() + # test_audio04() + # test_image01() + # test_image02() + # test_image03() + # test_image04() + # # test_video() + # test_video_02() + # test_text() + # test_video_track01() + # test_video_track02() + # test_video_track03() + # test_video_track04() + # test_keyframe() + # test_keyframe_02() + # test_subtitle_01() + # test_subtitle_02() + # test_subtitle() + # test_stiker_01() + # test_stiker_02() + # test_stiker_03() + # test_transition_01() + # test_transition_02() + # # test_generate_image01() + # # test_generate_image02() + # # test_speech_01() + # test_mask_01() + # test_mask_02() diff --git a/examples/example_capcut_effect.py b/examples/example_capcut_effect.py new file mode 100644 index 0000000..1c30f8e --- /dev/null +++ b/examples/example_capcut_effect.py @@ -0,0 +1,66 @@ +import os +import shutil +import sys + +# 添加父目录到系统路径 +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +# 从example.py中导入必要的函数 +from example import add_video_impl, add_effect, save_draft_impl + +def example_capcut_effect(): + """Test service for adding effects""" + # draft_folder = "/Users/sunguannan/Movies/JianyingPro/User Data/Projects/com.lveditor.draft" + draft_folder = "/Users/sunguannan/Movies/CapCut/User Data/Projects/com.lveditor.draft" + + print("\nTest: Adding effects") + # First add video track + image_result = add_video_impl( + video_url="https://pan.superbed.cn/share/1nbrg1fl/jimeng_daweidai.mp4", + start=0, + end=3.0, + target_start=0, + width=1080, + height=1920 + ) + print(f"Video added successfully! {image_result['output']['draft_id']}") + image_result = add_video_impl( + video_url="https://pan.superbed.cn/share/1nbrg1fl/jimeng_daweidai.mp4", + draft_id=image_result['output']['draft_id'], + start=0, + end=3.0, + target_start=3, + ) + print(f"Video added successfully! {image_result['output']['draft_id']}") + + # Then add effect + effect_result = add_effect( + effect_type="Like", + effect_category="character", # Explicitly specify as character effect + start=3, + end=6, + draft_id=image_result['output']['draft_id'], + track_name="effect_01" + ) + print(f"Effect adding result: {effect_result}") + print(save_draft_impl(effect_result['output']['draft_id'], draft_folder)) + + source_folder = os.path.join(os.getcwd(), effect_result['output']['draft_id']) + destination_folder = os.path.join(draft_folder, effect_result['output']['draft_id']) + + if os.path.exists(source_folder): + print(f"Moving {effect_result['output']['draft_id']} to {draft_folder}") + shutil.move(source_folder, destination_folder) + print("Folder moved successfully!") + else: + print(f"Source folder {source_folder} does not exist") + + # Add log to prompt user to find the draft in CapCut + print(f"\n===== IMPORTANT =====\nPlease open CapCut and find the draft named '{effect_result['output']['draft_id']}'\n=======================") + + # Return the first test result for subsequent operations (if any) + return effect_result + + +if __name__ == "__main__": + example_capcut_effect() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b3a6ea9..6080513 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ psutil flask requests oss2 +json5 \ No newline at end of file diff --git a/settings/local.py b/settings/local.py index 22127f0..cae0d94 100644 --- a/settings/local.py +++ b/settings/local.py @@ -3,7 +3,7 @@ """ import os -import json +import json5 # 替换原来的json模块 # 配置文件路径 CONFIG_FILE_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json") @@ -30,7 +30,8 @@ MP4_OSS_CONFIG=[] if os.path.exists(CONFIG_FILE_PATH): try: with open(CONFIG_FILE_PATH, "r", encoding="utf-8") as f: - local_config = json.load(f) + # 使用json5.load替代json.load + local_config = json5.load(f) # 更新是否是国际版 if "is_capcut_env" in local_config: @@ -60,6 +61,6 @@ if os.path.exists(CONFIG_FILE_PATH): if "mp4_oss_config" in local_config: MP4_OSS_CONFIG = local_config["mp4_oss_config"] - except (json.JSONDecodeError, IOError): + except Exception as e: # 配置文件加载失败,使用默认配置 pass \ No newline at end of file