跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI

Python 基于主视频删减片段并插入镜头视频

一个 Python 脚本,用于自动化生成剪映草稿。功能包括从主视频中删除指定时间段,并在特定时间点插入额外的镜头视频。脚本包含参数校验、时间格式转换及素材拼接逻辑,适合需要批量处理视频剪辑流程的场景。

锁机制发布于 2026/3/30更新于 2026/7/2451 浏览

使用前请确保安装必要的 Python 库,例如使用以下命令安装:

pip install pyJianYingDraft

以下是完整的脚本示例,用于根据主视频创建剪映草稿,删除指定时间段,添加镜头视频,并保存到草稿文件夹。

import pyJianYingDraft as draft
from pyJianYingDraft import trange, ClipSettings, tim
from typing import *

try:
    from xbot.app.logging import trace as print
except:
    from xbot import print

def create_jianying_draft_from_clips(draft_name, main_video_path, delete_ranges, lens_info_dict, draft_folder_path):
    """
    title: 基于主视频删减片段并插入镜头生成剪映草稿
    description: 根据主视频 %main_video_path% 创建剪映草稿,删除指定时间段 %delete_ranges%,添加镜头视频 %lens_info_dict%,并保存到草稿文件夹 %draft_folder_path%。
    inputs:
        - draft_name (str): 草稿项目名称,eg: "我的视频草稿"
        - main_video_path (file): 主视频文件路径,eg: "C:/videos/main.mp4"
        - delete_ranges (list): 需要删除的时间段列表,格式 [("开始时间","结束时间")], eg: [("00:00:01,640","00:00:02,640")]
        - lens_info_dict (dict): 镜头视频信息字典,格式 {"镜头名":[视频路径,开始时间]}, eg: {"镜头 A":["C:/lens.mp4","00:00:01,640"]}
        - draft_folder_path (folder): 剪映草稿文件夹路径,eg: "D:/JianyingPro Drafts"
    outputs:
        - None
    """
    # 检查输入参数
    if not draft_name or not isinstance(draft_name, str):
        raise ValueError("草稿名称不能为空且必须为字符串")
    if not main_video_path:
        raise ValueError("主视频路径不能为空")
    if  (delete_ranges, ):
         ValueError()
      (lens_info_dict, ):
         ValueError()
      draft_folder_path:
         ValueError()

     ():
        
        :
            h, m, s_ms = time_str.replace(, ).split()
             
         Exception  e:
             ValueError()

     ():
        
        script.add_track(draft.TrackType.video, )  
        
        parsed_deletes = []
         start_str, end_str  delete_ranges:
            start = tim(_convert_time(start_str))  
            end = tim(_convert_time(end_str))
             start >= end:
                 ValueError()
            parsed_deletes.append((start, end))
        
        parsed_deletes.sort(key= x: x[])
        
        video_material = draft.VideoMaterial(main_video_path)
        total_duration = video_material.duration  
        
        keep_ranges = []
        prev_end =   
         delete_start, delete_end  parsed_deletes:
            
             delete_start > prev_end:
                keep_ranges.append((prev_end, delete_start))
            
            prev_end = (prev_end, delete_end)
        
        
         prev_end < total_duration:
            keep_ranges.append((prev_end, total_duration))
        
        current_start =   
         keep_start, keep_end  keep_ranges:
             keep_start >= keep_end:
                  
            
            segment = draft.VideoSegment(
                video_material,
                target_timerange=trange(current_start, keep_end - keep_start),  
                source_timerange=trange(keep_start, keep_end - keep_start)  
            )
            script.add_segment(segment, )
            current_start += (keep_end - keep_start)  

     ():
        
         lens_name, lens_info  lens_info_dict.items():
             (lens_info) != :
                 ValueError()
            lens_video_path, lens_start_time = lens_info
            :
                lens_video_material = draft.VideoMaterial(lens_video_path)
             Exception  e:
                 ValueError()
            start_time = tim(_convert_time(lens_start_time))
            
            script.add_track(draft.TrackType.video, track_name=lens_name, relative_index=)
            
            lens_segment = draft.VideoSegment(
                lens_video_material,
                trange(start_time, lens_video_material.duration),  
                clip_settings=ClipSettings(
                    scale_x=main_mat.width / lens_video_material.width,  
                    scale_y=main_mat.height / lens_video_material.height,  
                )
            )
            
            script.add_segment(lens_segment, lens_name)

    :
        
        draft_folder = draft.DraftFolder(draft_folder_path)
        
        main_mat = draft.VideoMaterial(main_video_path)
        script = draft_folder.create_draft(
            draft_name,
            main_mat.width,
            main_mat.height,
        )
        
        _add_main_video_segments(script, main_video_path, delete_ranges)
        
        _add_lens_videos(script, lens_info_dict, main_mat)
        
        script.save()
        ()
     Exception  e:
         Exception()


draft_name = 
main_video_path = 
delete_ranges = [(, ), (, )]
lens_info_dict = {
    : [, ],
    : [, ]
}
draft_folder_path = 
create_jianying_draft_from_clips(draft_name, main_video_path, delete_ranges, lens_info_dict, draft_folder_path)
not
isinstance
list
raise
"删除时间段必须为列表格式"
if
not
isinstance
dict
raise
"镜头信息必须为字典格式"
if
not
raise
"草稿文件夹路径不能为空"
def
_convert_time
time_str
"""时间格式转换函数 (处理 00:00:01,640 格式)"""
try
','
'.'
':'
return
f"{int(h)}h{int(m)}m{s_ms}s"
except
as
raise
f"时间格式错误:{time_str},正确格式应为 '00:00:01,640'"
def
_add_main_video_segments
script, main_video_path, delete_ranges
"""添加主视频片段(删除指定区间后的剩余部分)"""
"video_track"
# 创建视频轨道
# 解析删除区间(转换为微秒,并按起始时间排序)
for
in
# 转换为微秒
if
raise
f"删除时间段起始时间不能大于等于结束时间:{start_str} - {end_str}"
# 按起始时间排序,确保区间顺序正确
lambda
0
# 获取视频总时长
# 微秒
# 动态计算保留区间
0
# 上一个区间的结束位置
for
in
# 若当前删除区间的起点 > 上一个区间的终点,说明中间有需要保留的部分
if
# 更新上一个区间的终点为当前删除区间的终点
max
# 处理区间重叠的情况
# 添加最后一个保留区间(从最后一个删除区间的终点到视频结束)
if
# 截取并拼接保留的片段
0
# 轨道上的起始位置(确保无缝拼接)
for
in
if
continue
# 跳过无效区间
# 截取素材中 [keep_start, keep_end) 的片段
# 轨道上的位置和时长
# 素材中截取的区间
"video_track"
# 更新下一段的起始位置
def
_add_lens_videos
script, lens_info_dict, main_mat
"""添加镜头视频到不同轨道"""
for
in
if
len
2
raise
f"镜头信息格式错误:{lens_name},应包含 [视频路径,开始时间]"
try
except
as
raise
f"无法加载镜头视频:{lens_video_path}"
# 创建视频轨道
1
# 创建镜头片段
# 关键设置:强制缩放镜头视频以填充整个画布,确保完全覆盖
# 按宽度比例缩放
# 按高度比例缩放
# 添加片段到对应轨道
try
# 1、创建草稿文件夹实例
# 创建新草稿 (使用主视频的分辨率)
# 2、添加主视频片段(处理删除区间)
# 3、添加镜头视频
# 4、保存草稿
print
f"剪映草稿 '{draft_name}' 创建成功!"
except
as
raise
f"创建剪映草稿失败:{str(e)}"
# 示例调用
"草稿名称 4"
r"C:\Users\Jordan\Downloads\【25-41 格雷灰】【脚本_2】\【25-41 格雷灰】【脚本_1】.mp4"
"00:00:01,640"
"00:00:02,640"
"00:00:03,640"
"00:00:04,640"
"镜头 A"
r"C:\Users\Jordan\Downloads\【25-41 格雷灰】【脚本_2】\【25-41 格雷灰】【镜头_拉链】.MP4"
"00:00:01,640"
"镜头 B"
r"D:\Desktop\20251206223742_rec_.mp4"
"00:00:06,640"
r"D:\download_software\JianyingPro Drafts"

目录

  1. 示例调用
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Dify 本地与公网部署及 Docker 镜像切换指南
  • 工业机器人工具坐标系与多传感器标定实战指南
  • RK3588 MIPI 摄像头采集与 WebRTC 低延迟推流实战
  • 前端防录屏原理:EME 与 DRM 机制及实战代码
  • MultiResUNet:重新思考多模态生物医学图像分割的 U-Net 架构
  • SwiftUI 零基础入门指南:快速上手与实战解析
  • MySQL 主从集群原理及 Docker 实战部署
  • 国内用户升级 GitHub Copilot 专业版支付方案
  • 深度解析 UGC、PGC、AIGC 等内容生成模式与区别
  • VS Code 配合 Overleaf Workshop 插件实现 AI 辅助 LaTeX 写作
  • 高精度混凝土缺陷与桥梁病害巡检数据集(YOLO 格式)
  • 前端流式输出技术:原理与实战指南
  • Lycium++ - OpenHarmony PC C/C++ 增强编译框架
  • 零基础到精通 AI 大模型:详细学习路线与实践技巧
  • C/C++依赖管理:Conan 深度解析与实战
  • Go 命令行 AI 对话客户端开发:从环境部署到核心实现
  • Whisper-WebUI 本地部署与核心功能详解
  • 本地部署 Llama3 8B/70B 大模型:CPU/GPU 运行方案详解
  • Windows 环境下编译与运行 llama.cpp 实战指南
  • Discord 机器人创建与配置完整指南

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online