mirror of
https://github.com/sun-guannan/CapCutAPI.git
synced 2025-11-25 03:15:00 +08:00
add effect catogory
This commit is contained in:
@@ -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
|
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
|
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 create_draft import get_or_create_draft
|
||||||
from util import generate_draft_url
|
from util import generate_draft_url
|
||||||
from settings import IS_CAPCUT_ENV
|
from settings import IS_CAPCUT_ENV
|
||||||
|
|
||||||
def add_effect_impl(
|
def add_effect_impl(
|
||||||
effect_type: str, # Changed to string type
|
effect_type: str, # Changed to string type
|
||||||
|
effect_category: Literal["scene", "character"],
|
||||||
start: float = 0,
|
start: float = 0,
|
||||||
end: float = 3.0,
|
end: float = 3.0,
|
||||||
draft_id: Optional[str] = None,
|
draft_id: Optional[str] = None,
|
||||||
@@ -18,6 +19,7 @@ def add_effect_impl(
|
|||||||
"""
|
"""
|
||||||
Add an effect to the specified draft
|
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_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 start: Start time (seconds), default 0
|
||||||
:param end: End time (seconds), default 3 seconds
|
: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
|
: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
|
duration = end - start
|
||||||
t_range = trange(f"{start}s", f"{duration}s")
|
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 IS_CAPCUT_ENV:
|
||||||
# If in CapCut environment, use CapCut effects
|
# If in CapCut environment, use CapCut effects
|
||||||
|
if effect_category == "scene":
|
||||||
|
try:
|
||||||
effect_enum = CapCut_Video_scene_effect_type[effect_type]
|
effect_enum = CapCut_Video_scene_effect_type[effect_type]
|
||||||
if effect_enum is None:
|
except:
|
||||||
|
effect_enum = None
|
||||||
|
elif effect_category == "character":
|
||||||
|
try:
|
||||||
effect_enum = CapCut_Video_character_effect_type[effect_type]
|
effect_enum = CapCut_Video_character_effect_type[effect_type]
|
||||||
|
except:
|
||||||
|
effect_enum = None
|
||||||
else:
|
else:
|
||||||
# Default to using JianYing effects
|
# Default to using JianYing effects
|
||||||
|
if effect_category == "scene":
|
||||||
|
try:
|
||||||
effect_enum = Video_scene_effect_type[effect_type]
|
effect_enum = Video_scene_effect_type[effect_type]
|
||||||
if effect_enum is None:
|
except:
|
||||||
|
effect_enum = None
|
||||||
|
elif effect_category == "character":
|
||||||
|
try:
|
||||||
effect_enum = Video_character_effect_type[effect_type]
|
effect_enum = Video_character_effect_type[effect_type]
|
||||||
|
except:
|
||||||
|
effect_enum = None
|
||||||
|
|
||||||
if effect_enum is 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)
|
# Add effect track (only when track doesn't exist)
|
||||||
if track_name is not None:
|
if track_name is not None:
|
||||||
|
|||||||
@@ -642,6 +642,7 @@ def add_effect():
|
|||||||
# Get required parameters
|
# Get required parameters
|
||||||
effect_type = data.get('effect_type') # Effect type name, will match from Video_scene_effect_type or Video_character_effect_type
|
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
|
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
|
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
|
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
|
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
|
# Call add_effect_impl method
|
||||||
draft_result = add_effect_impl(
|
draft_result = add_effect_impl(
|
||||||
effect_type=effect_type,
|
effect_type=effect_type,
|
||||||
|
effect_category=effect_category,
|
||||||
start=start,
|
start=start,
|
||||||
end=end,
|
end=end,
|
||||||
draft_id=draft_id,
|
draft_id=draft_id,
|
||||||
|
|||||||
128
example.py
128
example.py
@@ -9,6 +9,8 @@ import threading
|
|||||||
from pyJianYingDraft.text_segment import TextStyleRange, Text_style, Text_border
|
from pyJianYingDraft.text_segment import TextStyleRange, Text_style, Text_border
|
||||||
from util import hex_to_rgb
|
from util import hex_to_rgb
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
# Base URL of the service, please modify according to actual situation
|
# Base URL of the service, please modify according to actual situation
|
||||||
BASE_URL = f"http://localhost:{PORT}"
|
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 = {
|
data = {
|
||||||
"video_url": video_url,
|
"video_url": video_url,
|
||||||
"height": height,
|
"height": height,
|
||||||
|
"draft_id": draft_id,
|
||||||
"track_name": track_name,
|
"track_name": track_name,
|
||||||
"transform_y": transform_y,
|
"transform_y": transform_y,
|
||||||
"scale_x": scale_x,
|
"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)
|
return make_request("add_video", data)
|
||||||
|
|
||||||
def add_effect(effect_type, start, end, draft_id=None, track_name="effect_01",
|
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"""
|
"""API call to add effect"""
|
||||||
data = {
|
data = {
|
||||||
"effect_type": effect_type,
|
"effect_type": effect_type,
|
||||||
@@ -337,6 +340,9 @@ def add_effect(effect_type, start, end, draft_id=None, track_name="effect_01",
|
|||||||
"height": height
|
"height": height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if effect_category:
|
||||||
|
data["effect_category"] = effect_category
|
||||||
|
|
||||||
if draft_id:
|
if draft_id:
|
||||||
data["draft_id"] = draft_id
|
data["draft_id"] = draft_id
|
||||||
|
|
||||||
@@ -364,6 +370,59 @@ def test_effect_01():
|
|||||||
return effect_result
|
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():
|
def test_text():
|
||||||
"""Test adding text with various features"""
|
"""Test adding text with various features"""
|
||||||
draft_folder = CAPCUT_DRAFT_FOLDER
|
draft_folder = CAPCUT_DRAFT_FOLDER
|
||||||
@@ -2280,36 +2339,37 @@ def test_transition_02():
|
|||||||
print("Unable to get draft ID, skipping save operation.")
|
print("Unable to get draft ID, skipping save operation.")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test01()
|
# test01()
|
||||||
test02()
|
# test02()
|
||||||
test_effect_01() # Run effect test
|
# test_effect_01() # Run effect test
|
||||||
test_audio01()
|
test_effect_02()
|
||||||
test_audio02()
|
# test_audio01()
|
||||||
test_audio03()
|
# test_audio02()
|
||||||
test_audio04()
|
# test_audio03()
|
||||||
test_image01()
|
# test_audio04()
|
||||||
test_image02()
|
# test_image01()
|
||||||
test_image03()
|
# test_image02()
|
||||||
test_image04()
|
# test_image03()
|
||||||
# test_video()
|
# test_image04()
|
||||||
test_video_02()
|
# # test_video()
|
||||||
test_text()
|
# test_video_02()
|
||||||
test_video_track01()
|
# test_text()
|
||||||
test_video_track02()
|
# test_video_track01()
|
||||||
test_video_track03()
|
# test_video_track02()
|
||||||
test_video_track04()
|
# test_video_track03()
|
||||||
test_keyframe()
|
# test_video_track04()
|
||||||
test_keyframe_02()
|
# test_keyframe()
|
||||||
test_subtitle_01()
|
# test_keyframe_02()
|
||||||
test_subtitle_02()
|
# test_subtitle_01()
|
||||||
test_subtitle()
|
# test_subtitle_02()
|
||||||
test_stiker_01()
|
# test_subtitle()
|
||||||
test_stiker_02()
|
# test_stiker_01()
|
||||||
test_stiker_03()
|
# test_stiker_02()
|
||||||
test_transition_01()
|
# test_stiker_03()
|
||||||
test_transition_02()
|
# test_transition_01()
|
||||||
# test_generate_image01()
|
# test_transition_02()
|
||||||
# test_generate_image02()
|
# # test_generate_image01()
|
||||||
# test_speech_01()
|
# # test_generate_image02()
|
||||||
test_mask_01()
|
# # test_speech_01()
|
||||||
test_mask_02()
|
# test_mask_01()
|
||||||
|
# test_mask_02()
|
||||||
|
|||||||
66
examples/example_capcut_effect.py
Normal file
66
examples/example_capcut_effect.py
Normal file
@@ -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()
|
||||||
@@ -3,3 +3,4 @@ psutil
|
|||||||
flask
|
flask
|
||||||
requests
|
requests
|
||||||
oss2
|
oss2
|
||||||
|
json5
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json5 # 替换原来的json模块
|
||||||
|
|
||||||
# 配置文件路径
|
# 配置文件路径
|
||||||
CONFIG_FILE_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.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):
|
if os.path.exists(CONFIG_FILE_PATH):
|
||||||
try:
|
try:
|
||||||
with open(CONFIG_FILE_PATH, "r", encoding="utf-8") as f:
|
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:
|
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:
|
if "mp4_oss_config" in local_config:
|
||||||
MP4_OSS_CONFIG = local_config["mp4_oss_config"]
|
MP4_OSS_CONFIG = local_config["mp4_oss_config"]
|
||||||
|
|
||||||
except (json.JSONDecodeError, IOError):
|
except Exception as e:
|
||||||
# 配置文件加载失败,使用默认配置
|
# 配置文件加载失败,使用默认配置
|
||||||
pass
|
pass
|
||||||
Reference in New Issue
Block a user