2604007 更新短视频广告合成方法

This commit is contained in:
liubiren 2026-04-07 19:00:13 +08:00
parent af44e24d60
commit cf790bc3db
3 changed files with 71 additions and 32 deletions

Binary file not shown.

View File

@ -21,7 +21,7 @@ from drafts import Drafts
sys.path.append(Path(__file__).parent.parent.as_posix())
class JianYingManager:
class DraftsManager:
"""
剪映草稿管理器
"""
@ -45,11 +45,11 @@ class JianYingManager:
# 初始化所有素材
self.materials = self._init_materials()
# 初始化成品文件夹路径
# 初始化导出视频文件夹路径
self.products_folder_path = Path(
materials_folder_path.replace("materials", "products")
)
# 若成品文件夹存路径已存在则先删除
# 若导出视频文件夹路径已存在则先删除
if self.products_folder_path.exists():
shutil.rmtree(self.products_folder_path)
self.products_folder_path.mkdir(parents=True)
@ -150,7 +150,7 @@ class JianYingManager:
# 构建标识图片路径
logo_image_path = self.materials_folder_path / "标识图片.png"
if logo_image_path.exists() and logo_image_path.is_file():
materials["logo_image_path"] = [logo_image_path] # 有且只有一张标识
materials["logo_image_path"] = [logo_image_path] # 有且只有一张标识图片
else:
materials["logo_image_path"] = []
@ -175,6 +175,15 @@ class JianYingManager:
else:
materials["statement_texts"] = []
# 构建声明图片路径
statement_image_path = self.materials_folder_path / "声明图片.png"
if statement_image_path.exists() and statement_image_path.is_file():
materials["statement_image_path"] = [
statement_image_path
] # 有且只有一张声明图片
else:
materials["statement_image_path"] = []
# 构建声明视频文件夹路径
statement_video_folder_path = self.materials_folder_path / "声明视频"
if (
@ -215,11 +224,16 @@ class JianYingManager:
"淘宝闪购_达人": [
"add_background_video",
"add_background_audio",
"add_subtitle_video",
"add_mid_roll_video",
"add_post_roll_video",
"add_logo_video",
"add_statement_video",
], # 淘宝闪购_达人先就背景视频、背景音频、字幕视频截取前 5 秒,再添加中贴视频、后贴视频、标识视频、声明视频和生成视频
], # 先分别添加背景视频(其中背景视频叠加背景音频和字幕视频,支持设置截取背景视频持续时长)、中贴视频和后贴视频,最后叠加标识视频和声明视频
"存量": [
"add_background_video",
"add_statement_image",
], # 就背景视频添加声明图片
}
# 默认以素材文件夹名称为工作流名称
workflow_name = self.materials_folder_path.stem
@ -228,7 +242,7 @@ class JianYingManager:
if not workflow:
raise RuntimeError(f"该工作流 {workflow_name} 未配置")
# 节点配置模板
# 所有工作配置
configurations = {
"generate_subtitle": {
"texts": self.materials["subtitle_texts"],
@ -318,6 +332,17 @@ class JianYingManager:
},
], # 图像调节设置
}, # 添加声明工作配置
"add_statement_image": {
"material_path": self.materials["statement_image_path"],
"clip_settings": [
{
"scale_x": 0.4,
"scale_y": 0.4,
"transform_x": 0.00,
"transform_y": -0.85,
},
],
}, # 添加声明图片工作配置
"add_statement_video": {
"material_path": self.materials["statement_video_path"],
"volume": [1.0], # 播放音量
@ -379,7 +404,7 @@ class JianYingManager:
video_width: int = 1080,
video_height: int = 1920,
video_fps: int = 30,
duration_capture: Optional[int] = None,
capture_duration: Optional[int] = None,
) -> None:
"""
批量创建草稿
@ -387,29 +412,38 @@ class JianYingManager:
:param video_width: 视频宽度单位为像素默认为 1080
:param video_height: 视频高度单位为像素默认为 1920
:param video_fps: 视频帧率单位为帧/默认为 30
:param duration_capture: 截取背景视频时长单位为秒默认为 None
:param capture_duration: 截取背景视频时长单位为秒默认为 None
:return:
"""
draft_index = 1 # 草稿索引
while True:
# 获取节点配置
configurations = self._get_configurations(duration_capture=duration_capture)
# 获取工作配置
configurations = self._get_configurations(capture_duration=capture_duration)
# 若包含添加字幕视频则使用字幕视频时长作为视频时长,否则使用背景视频时长作为视频时长
if "add_subtitle_video" in configurations:
video_duration = VideoMaterial(
path=configurations["add_subtitle_video"][
"material_path"
].as_posix()
).duration
video_duration = min(
VideoMaterial(
path=configurations["add_background_video"][
"material_path"
].as_posix()
).duration,
VideoMaterial(
path=configurations["add_subtitle_video"][
"material_path"
].as_posix()
).duration,
)
else:
video_duration = video_duration = VideoMaterial(
path=configurations["add_background_video"][
"material_path"
].as_posix()
).duration
if duration_capture:
video_duration = duration_capture * 1_000_000 # 转换为微秒单位
# 转换为微秒单位
if capture_duration:
video_duration = capture_duration * 1_000_000
# 添加中贴视频持续时长
if "add_mid_roll_video" in configurations:
@ -479,7 +513,7 @@ class JianYingManager:
print("-> 正在添加字幕视频...", end="")
draft.add_video_segment(**configurations[node_name])
print("已完成")
# 添加标识
# 添加标识图片
case "add_logo_image":
print("-> 正在添加标识图片...", end="")
draft.add_video_segment(**configurations[node_name])
@ -494,6 +528,11 @@ class JianYingManager:
print("-> 正在添加声明文本...", end="")
draft.add_text_segment(**configurations[node_name])
print("已完成")
# 添加声明图片
case "add_statement_image":
print("-> 正在添加声明图片...", end="")
draft.add_video_segment(**configurations[node_name])
print("已完成")
# 添加声明视频
case "add_statement_video":
print("-> 正在添加声明视频...", end="")
@ -525,12 +564,12 @@ class JianYingManager:
def _get_configurations(
self,
duration_capture: Optional[int] = None,
capture_duration: Optional[int] = None,
) -> Dict[str, Any]:
"""
获取节点配置
:param duration_capture: 截取背景视频时长单位为秒默认为 None
:return: 节点配置
获取工作配置
:param capture_duration: 截取背景视频时长单位为秒默认为 None
:return: 工作配置
"""
configurations = {}
for node_name in self.configurations:
@ -559,11 +598,11 @@ class JianYingManager:
background_video_duration = VideoMaterial(
path=configurations["add_background_video"]["material_path"].as_posix()
).duration
if duration_capture:
background_video_duration = duration_capture * 1_000_000
if capture_duration:
background_video_duration = capture_duration * 1_000_000
# 若包含添加字幕频则在添加背景视频时其播放音量设置为 0
if "add_subtitle_audio" in configurations:
# 若包含添加字幕频则在添加背景视频时其播放音量设置为 0
if "add_subtitle_video" in configurations:
configurations["add_background_video"]["volume"] = 0.0
# 中贴视频特殊处理:背景视频、背景音频和字幕视频在轨道上的范围为 (0, 背景视频时长),中贴视频在轨道上的范围为 (背景视频时长, 中贴视频时长)

View File

@ -4,15 +4,15 @@
"""
# 列举导入模块
from jiangying_manager import JianYingManager
from drafts_manager import DraftsManager
if __name__ == "__main__":
# 实例化 JianYingManager
jianying_manager = JianYingManager(
materials_folder_path=r"E:\jianying\materials\淘宝闪购_达人",
# 实例化 DraftsManager
drafts_manager = DraftsManager(
materials_folder_path=r"E:\jianying\materials\存量",
)
# 导出视频
jianying_manager.batch_create(
draft_counts=200,
drafts_manager.batch_create(
draft_counts=1,
)