mirror of
https://github.com/sun-guannan/CapCutAPI.git
synced 2025-11-25 03:15:00 +08:00
216 lines
8.3 KiB
Python
216 lines
8.3 KiB
Python
import pyJianYingDraft as draft
|
||
from settings.local import IS_CAPCUT_ENV
|
||
from util import generate_draft_url, hex_to_rgb
|
||
from pyJianYingDraft import trange, Font_type
|
||
from typing import Optional
|
||
from pyJianYingDraft import exceptions
|
||
from create_draft import get_or_create_draft
|
||
from pyJianYingDraft.text_segment import TextBubble, TextEffect
|
||
|
||
def add_text_impl(
|
||
text: str,
|
||
start: float,
|
||
end: float,
|
||
draft_id: str = None,
|
||
transform_y: float = -0.8,
|
||
transform_x: float = 0,
|
||
font: str = "文轩体",
|
||
font_color: str = "#ffffff",
|
||
font_size: float = 8.0,
|
||
track_name: str = "text_main",
|
||
vertical: bool = False, # 是否竖排显示
|
||
font_alpha: float = 1.0, # 透明度,范围0.0-1.0
|
||
# 描边参数
|
||
border_alpha: float = 1.0,
|
||
border_color: str = "#000000",
|
||
border_width: float = 0.0, # 默认不显示描边
|
||
# 背景参数
|
||
background_color: str = "#000000",
|
||
background_style: int = 1,
|
||
background_alpha: float = 0.0, # 默认不显示背景
|
||
# 气泡效果
|
||
bubble_effect_id: Optional[str] = None,
|
||
bubble_resource_id: Optional[str] = None,
|
||
# 文本花字
|
||
effect_effect_id: Optional[str] = None,
|
||
intro_animation: Optional[str] = None, # 入场动画类型
|
||
intro_duration: float = 0.5, # 入场动画持续时间(秒),默认0.5秒
|
||
outro_animation: Optional[str] = None, # 出场动画类型
|
||
outro_duration: float = 0.5, # 出场动画持续时间(秒),默认0.5秒
|
||
width: int = 1080,
|
||
height: int = 1920,
|
||
fixed_width: float = -1, # 文本固定宽度比例,默认-1表示不固定
|
||
fixed_height: float = -1, # 文本固定高度比例,默认-1表示不固定
|
||
):
|
||
"""
|
||
向指定草稿添加文本字幕(参数可配置版本)
|
||
:param text: 文本内容
|
||
:param start: 开始时间(秒)
|
||
:param end: 结束时间(秒)
|
||
:param draft_id: 草稿ID(可选,默认None则创建新草稿)
|
||
:param transform_y: Y轴位置(默认-0.8,屏幕下方)
|
||
:param transform_x: X轴位置(默认0,屏幕中间)
|
||
:param font: 字体名称(支持Font_type中的所有字体)
|
||
:param font_color: 字体颜色 #FFF0FF
|
||
:param font_size: 字体大小(浮点值,默认8.0)
|
||
:param track_name: 轨道名称
|
||
:param vertical: 是否竖排显示(默认False)
|
||
:param font_alpha: 文字透明度,范围0.0-1.0(默认1.0,完全不透明)
|
||
:param border_alpha: 描边透明度,范围0.0-1.0(默认1.0)
|
||
:param border_color: 描边颜色(默认黑色)
|
||
:param border_width: 描边宽度(默认0.0,不显示描边)
|
||
:param background_color: 背景颜色(默认黑色)
|
||
:param background_style: 背景样式(默认1)
|
||
:param background_alpha: 背景透明度(默认0.0,不显示背景)
|
||
:param bubble_effect_id: 气泡效果ID
|
||
:param bubble_resource_id: 气泡资源ID
|
||
:param effect_effect_id: 花字效果ID
|
||
:param intro_animation: 入场动画类型
|
||
:param intro_duration: 入场动画持续时间(秒),默认0.5秒
|
||
:param outro_animation: 出场动画类型
|
||
:param outro_duration: 出场动画持续时间(秒),默认0.5秒
|
||
:param width: 视频宽度(像素)
|
||
:param height: 视频高度(像素)
|
||
:param fixed_width: 文本固定宽度比例,范围0.0-1.0,默认-1表示不固定
|
||
:param fixed_height: 文本固定高度比例,范围0.0-1.0,默认-1表示不固定
|
||
:return: 更新后的草稿信息
|
||
"""
|
||
# 校验字体是否在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"不支持的字体:{font},请使用Font_type中的字体之一:{available_fonts}")
|
||
|
||
# 校验alpha值范围
|
||
if not 0.0 <= font_alpha <= 1.0:
|
||
raise ValueError("alpha值必须在0.0到1.0之间")
|
||
if not 0.0 <= border_alpha <= 1.0:
|
||
raise ValueError("border_alpha值必须在0.0到1.0之间")
|
||
if not 0.0 <= background_alpha <= 1.0:
|
||
raise ValueError("background_alpha值必须在0.0到1.0之间")
|
||
|
||
# 获取或创建草稿
|
||
draft_id, script = get_or_create_draft(
|
||
draft_id=draft_id,
|
||
width=width,
|
||
height=height
|
||
)
|
||
|
||
# 添加文本轨道
|
||
if track_name is not None:
|
||
try:
|
||
imported_track = script.get_imported_track(draft.Track_type.text, name=track_name)
|
||
# 如果没有抛出异常,说明轨道已存在
|
||
except exceptions.TrackNotFound:
|
||
# 轨道不存在,创建新轨道
|
||
script.add_track(draft.Track_type.text, track_name=track_name)
|
||
else:
|
||
script.add_track(draft.Track_type.audio)
|
||
|
||
# 转换十六进制颜色为 RGB 元组
|
||
try:
|
||
rgb_color = hex_to_rgb(font_color)
|
||
rgb_border_color = hex_to_rgb(border_color)
|
||
except ValueError as e:
|
||
raise ValueError(f"颜色参数错误: {str(e)}")
|
||
|
||
# 创建text_border (描边)
|
||
text_border = None
|
||
if border_width > 0:
|
||
text_border = draft.Text_border(
|
||
alpha=border_alpha,
|
||
color=rgb_border_color,
|
||
width=border_width
|
||
)
|
||
|
||
# 创建text_background (背景)
|
||
text_background = None
|
||
if background_alpha > 0:
|
||
text_background = draft.Text_background(
|
||
color=background_color,
|
||
style=background_style,
|
||
alpha=background_alpha
|
||
)
|
||
|
||
# 创建气泡效果
|
||
text_bubble = None
|
||
if bubble_effect_id and bubble_resource_id:
|
||
text_bubble = TextBubble(
|
||
effect_id=bubble_effect_id,
|
||
resource_id=bubble_resource_id
|
||
)
|
||
|
||
# 创建花字效果
|
||
text_effect = None
|
||
if effect_effect_id:
|
||
text_effect = TextEffect(
|
||
effect_id=effect_effect_id
|
||
)
|
||
|
||
# 将比例转换为像素值
|
||
pixel_fixed_width = -1
|
||
pixel_fixed_height = -1
|
||
if fixed_width > 0:
|
||
pixel_fixed_width = int(fixed_width * script.width)
|
||
if fixed_height > 0:
|
||
pixel_fixed_height = int(fixed_height * script.height)
|
||
|
||
# 创建文本片段(使用可配置参数)
|
||
text_segment = draft.Text_segment(
|
||
text,
|
||
trange(f"{start}s", f"{end-start}s"),
|
||
font=font_type, # 使用Font_type中的字体
|
||
style=draft.Text_style(
|
||
color=rgb_color,
|
||
size=font_size,
|
||
align=1,
|
||
vertical=vertical, # 设置是否竖排
|
||
alpha=font_alpha # 设置透明度
|
||
),
|
||
clip_settings=draft.Clip_settings(transform_y=transform_y, transform_x=transform_x),
|
||
border=text_border,
|
||
background=text_background,
|
||
fixed_width=pixel_fixed_width,
|
||
fixed_height=pixel_fixed_height
|
||
)
|
||
|
||
if text_bubble:
|
||
text_segment.add_bubble(text_bubble.effect_id, text_bubble.resource_id)
|
||
if text_effect:
|
||
text_segment.add_effect(text_effect.effect_id)
|
||
|
||
# 添加入场动画
|
||
if intro_animation:
|
||
try:
|
||
if IS_CAPCUT_ENV:
|
||
animation_type = getattr(draft.CapCut_Text_intro, intro_animation)
|
||
else:
|
||
animation_type = getattr(draft.Text_intro, intro_animation)
|
||
# 将秒转换为微秒
|
||
duration_microseconds = int(intro_duration * 1000000)
|
||
text_segment.add_animation(animation_type, duration_microseconds) # 添加入场动画,设置持续时间
|
||
except:
|
||
print(f"警告:不支持的入场动画类型 {intro_animation},将忽略此参数")
|
||
|
||
# 添加出场动画
|
||
if outro_animation:
|
||
try:
|
||
if IS_CAPCUT_ENV:
|
||
animation_type = getattr(draft.CapCut_Text_outro, outro_animation)
|
||
else:
|
||
animation_type = getattr(draft.Text_outro, outro_animation)
|
||
# 将秒转换为微秒
|
||
duration_microseconds = int(outro_duration * 1000000)
|
||
text_segment.add_animation(animation_type, duration_microseconds) # 添加出场动画,设置持续时间
|
||
except:
|
||
print(f"警告:不支持的出场动画类型 {outro_animation},将忽略此参数")
|
||
|
||
# 添加文本片段到轨道
|
||
script.add_segment(text_segment, track_name=track_name)
|
||
|
||
return {
|
||
"draft_id": draft_id,
|
||
"draft_url": generate_draft_url(draft_id)
|
||
}
|