From cd615b06daf8a35fd23f0ec498ae54e3a0993b6b Mon Sep 17 00:00:00 2001 From: liubiren Date: Mon, 5 Jan 2026 22:05:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E6=9B=B4=E6=96=B0=20from=20N?= =?UTF-8?q?UC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 短视频合成自动化/@AutomationLog.txt | 2 + 短视频合成自动化/draft.py | 11 ++- 短视频合成自动化/export.py | 100 ++++++++++++++++++---------- 短视频合成自动化/main.py | 2 +- 4 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 短视频合成自动化/@AutomationLog.txt diff --git a/短视频合成自动化/@AutomationLog.txt b/短视频合成自动化/@AutomationLog.txt new file mode 100644 index 0000000..db78d81 --- /dev/null +++ b/短视频合成自动化/@AutomationLog.txt @@ -0,0 +1,2 @@ +2026-01-05 15:44:22.377 export.py[409] export -> Find Control Timeout(10s): {NameContains: '删除', VisibleOnly: True, ControlType: MenuItemControl} +2026-01-05 15:46:56.070 export.py[409] export -> Find Control Timeout(10s): {NameContains: '删除', VisibleOnly: True, ControlType: MenuItemControl} diff --git a/短视频合成自动化/draft.py b/短视频合成自动化/draft.py index 31a6068..4e3fb19 100644 --- a/短视频合成自动化/draft.py +++ b/短视频合成自动化/draft.py @@ -22,9 +22,9 @@ class JianYingDraft: # noinspection PyShadowingNames def __init__( self, + drafts_folder: pyJianYingDraft.DraftFolder, draft_name: str, materials_folder_path: Path, - drafts_folder_path: str = r"E:\JianyingPro Drafts", allow_replace: bool = True, video_width: int = 1080, video_height: int = 1920, @@ -32,9 +32,9 @@ class JianYingDraft: ): """ 初始化 - :param drafts_folder_path: 剪映草稿文件夹路径 + :param drafts_folder: 剪映草稿文件夹管理器 :param draft_name: 草稿名称 - :param allow_replace: 是否允许覆盖同名草稿 + :param allow_replace: 是否允许覆盖同名草稿(若不允许覆盖同名草稿需初始化剪映草稿文件夹) :param video_width: 视频宽度,默认为 1080像素 :param video_height: 视频高度,默认为 1920像素 :param video_fps: 视频帧率(单位为帧/秒),默认为 30 @@ -42,11 +42,8 @@ class JianYingDraft: """ # noinspection PyBroadException try: - # 初始化草稿文件夹管理器 - self.draft_folder = pyJianYingDraft.DraftFolder(drafts_folder_path) - # 新建草稿 - self.draft = self.draft_folder.create_draft( + self.draft = drafts_folder.create_draft( draft_name=draft_name, allow_replace=allow_replace, width=video_width, diff --git a/短视频合成自动化/export.py b/短视频合成自动化/export.py index ddc0a02..e07990f 100644 --- a/短视频合成自动化/export.py +++ b/短视频合成自动化/export.py @@ -25,7 +25,8 @@ class JianYingExport: def __init__( self, materials_folder_path: str, - jianying_program_path: str = r"E:\JianyingPro\5.9.0.11632\JianyingPro.exe", + program_path: str = r"E:\JianyingPro\5.9.0.11632\JianyingPro.exe", + drafts_folder_path: str = r"E:\JianyingPro Drafts", draft_counts: int = 10, video_width: int = 1080, video_height: int = 1920, @@ -33,7 +34,8 @@ class JianYingExport: ): """ 初始化 - :param jianying_program_path: 剪映执行程序路径 + :param program_path: 剪映执行程序路径 + :param drafts_folder_path: 剪映草稿文件夹路径 :param materials_folder_path: 素材文件夹路径 :param draft_counts: 草稿数,默认为 10 :param video_width: 视频宽度,默认为 1080像素 @@ -42,13 +44,22 @@ class JianYingExport: """ # noinspection PyBroadException try: - self.jianying_program_path = Path(jianying_program_path) - if not self.jianying_program_path.exists(): + self.program_path = Path(program_path) + if not self.program_path.exists(): raise RuntimeError("剪映执行程序路径不存在") # 初始化剪映专业版进程 self.jianying_process = None + self.drafts_folder_path = Path(drafts_folder_path) + if not self.drafts_folder_path.exists(): + raise RuntimeError("剪映草稿文件夹路径不存在") + + # 初始化草稿文件夹管理器 + self.drafts_folder = pyJianYingDraft.DraftFolder( + folder_path=self.drafts_folder_path.as_posix() + ) + self.materials_folder_path = Path(materials_folder_path) if not self.materials_folder_path.exists(): raise RuntimeError("素材文件夹路径不存在") @@ -57,7 +68,7 @@ class JianYingExport: self.exports_folder_path = Path( self.materials_folder_path.as_posix().replace("materials", "exports") ) - self.exports_folder_path.mkdir(exist_ok=True) + self.exports_folder_path.mkdir() # 若导出文件夹存在则抛出异常,需手动处理 self.materials = {} # 初始化素材文件夹内所有素材 @@ -294,7 +305,7 @@ class JianYingExport: self.video_fps = video_fps self.draft_counts = draft_counts - # 初始化批量生成草稿的所有草稿名称,用于批量导出 + # 初始化所有草稿名称 self.draft_names = [] except Exception as exception: @@ -350,6 +361,50 @@ class JianYingExport: else: raise RuntimeError("声明不存在") + def export(self, batch_draft_counts: int = 1): + """ + 导出草稿 + :param batch_draft_counts: 每批次导出草稿数 + """ + # 按照工作流和工作配置拼接素材,生成草稿 + self._generate() + + # 批次导出 + for batch_start in range(0, self.draft_counts, batch_draft_counts): + # 当前批次所有草稿名称 + batch_draft_names = self.draft_names[ + batch_start : batch_start + batch_draft_counts + ] + + # 启动剪映专业版进程 + self._start_process() + time.sleep(2) + + # 初始化剪映控制器 + jianying_controller = pyJianYingDraft.JianyingController() + + for draft_name in batch_draft_names: + print(f"正在导出 {draft_name}...") + if (self.exports_folder_path / f"{draft_name}.mp4").is_file(): + print("存在相同名称的草稿,跳过") + continue + + jianying_controller.export_draft( + draft_name=draft_name, + output_path=self.exports_folder_path.as_posix(), + ) + print("已完成") + print() + + # 关闭剪映专业版进程 + self._close_process() + time.sleep(2) + + for draft_name in batch_draft_names: + # 就已导出草稿删除 + self.drafts_folder.remove(draft_name=draft_name) + time.sleep(2) + def _generate( self, ) -> None: @@ -364,6 +419,7 @@ class JianYingExport: # 实例化 JianYingDraft draft = JianYingDraft( + drafts_folder=self.drafts_folder, draft_name=draft_name, video_width=self.video_width, video_height=self.video_height, @@ -407,7 +463,7 @@ class JianYingExport: print("已完成") print() - # 按照草稿名称倒叙排序 + # 就所有草稿名称倒叙排序排序 self.draft_names.sort(reverse=True) def _random( @@ -423,34 +479,6 @@ class JianYingExport: key: random.choice(value) for key, value in self.configuration[work].items() } - def export(self): - """ - 导出草稿 - """ - # 按照工作流和工作配置拼接素材,生成草稿 - self._generate() - - # 启动剪映专业版进程 - self._start_process() - time.sleep(10) - - # 初始化剪映控制器 - jianying_controller = pyJianYingDraft.JianyingController() - - for draft_name in self.draft_names: - print(f"正在导出 {draft_name}...") - if (self.exports_folder_path / f"{draft_name}.mp4").is_file(): - print("存在相同名称的草稿,跳过") - continue - jianying_controller.export_draft( - draft_name=draft_name, output_path=self.exports_folder_path.as_posix() - ) - print("已完成") - print() - - # 关闭剪映专业版进程 - self._close_process() - def _start_process(self, timeout: int = 60) -> None: """ 启动剪映专业版进程 @@ -463,7 +491,7 @@ class JianYingExport: # 非堵塞方法 self.jianying_process = subprocess.Popen( - args=self.jianying_program_path.as_posix(), + args=self.program_path.as_posix(), shell=True, # 适配 Windows路径中的空格 stdout=subprocess.DEVNULL, # 重定向 stderr=subprocess.DEVNULL, diff --git a/短视频合成自动化/main.py b/短视频合成自动化/main.py index dfe3a5c..77c9ed8 100644 --- a/短视频合成自动化/main.py +++ b/短视频合成自动化/main.py @@ -10,7 +10,7 @@ if __name__ == "__main__": # 实例化 JianYingExport jianying_export = JianYingExport( materials_folder_path=r"E:\jianying\materials\260104", - draft_counts=1, + draft_counts=2, ) # 导出草稿