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

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

sql 复制代码
import pyJianYingDraft as draft
from pyJianYingDraft import trange, ClipSettings,tim

def create_jianying_draft_from_clips(draft_name,main_video_path,delete_ranges,lens_info_dict,draft_folder_path):
    
    # 时间格式转换函数(处理00:00:01,640格式)
    def convert_time(time_str):
        h, m, s_ms = time_str.replace(',', '.').split(':')
        return f"{int(h)}h{int(m)}m{s_ms}s"
    
    # 1、创建草稿文件夹实例
    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, 
    )

    # 2、计算出主视频的剩余目标区间并添加到草稿中
    def add_main_video_segments():

        script.add_track(draft.TrackType.video, "video_track")  # 创建视频轨道

        # 解析删除区间(转换为微秒,并按起始时间排序)
        parsed_deletes = []
        for start_str, end_str in delete_ranges:
            start = tim(convert_time(start_str)) # 转换为微秒
            end = tim(convert_time(end_str))
            parsed_deletes.append((start, end))
        
        # 按起始时间排序,确保区间顺序正确(避免交叉区间导致计算错误)
        parsed_deletes.sort(key=lambda x: x[0])

        # 3. 获取视频总时长
        video_material = draft.VideoMaterial(main_video_path)
        total_duration = video_material.duration  # 微秒

        # 4. 动态计算保留区间
        keep_ranges = []
        prev_end = 0  # 上一个区间的结束位置

        for delete_start, delete_end in parsed_deletes:
            # 若当前删除区间的起点 > 上一个区间的终点,说明中间有需要保留的部分
            if delete_start > prev_end:
                keep_ranges.append((prev_end, delete_start))
            # 更新上一个区间的终点为当前删除区间的终点
            prev_end = max(prev_end, delete_end)  # 处理区间重叠的情况

        # 添加最后一个保留区间(从最后一个删除区间的终点到视频结束)
        if prev_end < total_duration:
            keep_ranges.append((prev_end, total_duration))

        print("保留的视频片段时间区间", keep_ranges)

        # 5. 截取并拼接保留的片段
        current_start = 0  # 轨道上的起始位置(确保无缝拼接)
        for keep_start, keep_end in keep_ranges:
            if keep_start >= keep_end:
                continue  # 跳过无效区间
            # 截取素材中[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, "video_track")
            current_start += (keep_end - keep_start)  # 更新下一段的起始位置

    # 3、添加镜头视频
    def add_lens_videos():

        for lens_name, lens_info in lens_info_dict.items():
            lens_video_path, lens_start_time = lens_info
            lens_video_material = draft.VideoMaterial(lens_video_path)
            start_time = tim(convert_time(lens_start_time))
             # 创建视频轨道
            script.add_track(draft.TrackType.video, track_name=lens_name, relative_index=1) 
            # 创建镜头片段
            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)

    add_main_video_segments()
    add_lens_videos()
    script.save()

draft_name="草稿名称4"
main_video_path=r"C:\Users\Jordan\Downloads\【25-41格雷灰】【脚本_2】\【25-41格雷灰】【脚本_1】.mp4"
delete_ranges=[("00:00:01,640","00:00:02,640"),("00:00:03,640","00:00:04,640")]
lens_info_dict={"镜头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"]}
draft_folder_path=r"D:\download_software\JianyingPro Drafts"

create_jianying_draft_from_clips(draft_name,main_video_path,delete_ranges,lens_info_dict,draft_folder_path)
相关推荐
破茧蝴蝶6 小时前
Python分布式爬虫完整教程
开发语言·python
大哥您好6 小时前
QEMU 11.1.2 多架构编译指南(x86_64 / aarch64 / riscv64)
linux·服务器
Sayai6 小时前
ComfyUI+混元视频实战:12G 显存跑 13G 模型,5 分钟出片(国产开源,附模型与工作流)
人工智能·aigc·音视频·comfyui·hunyuanvideo·混元视频
benchmark_cc6 小时前
量化系统架构设计:为什么应该将数据获取与策略逻辑解耦?
python·数据分析·pandas·量化交易·股票数据·quantdash
凤山老林6 小时前
Spring Boot 启动冲刺:耗时剖析、懒加载策略与事件驱动初始化优化
spring boot·后端·python
小白快快跑哦7 小时前
python-字符串全解(六):正则表达式-逻辑运算或
python·正则表达式·字符串·逻辑运算
Thinker QAQ7 小时前
并发编程(九):BlockingQueue 与 Channel——语言层的原子性、可见性与有序性
java·python·go·并发编程·channel·blockingqueue·message passing
道满科技7 小时前
Function Calling 参数总出错?只修参数就行
linux·windows·python
Android系统攻城狮8 小时前
Linux Gstreamer深度解析之gst_audio_ring_buffer_prepare_read调用流程与实战(七十四)
linux·运维·服务器·gstreamer音视频·音视频进阶
我科绝伦(Huanhuan Zhou)8 小时前
Linux 通用压力测试脚本合集:磁盘 + 网络
linux·网络·压力测试