python_制作视频开头_根据短句字长占总字幕的长度比例拆分

效果

python 复制代码
import os
import pyJianYingDraft as draft
from pyJianYingDraft import TrackType, trange, TextStyle, ClipSettings,TextIntro
from typing import List, Dict, Tuple

def rgb_255_to_float(rgb_tuple: tuple, decimal_places: int = 4) -> tuple:
    """将0-255的RGB值转换为0-1的浮点数"""
    for value in rgb_tuple:
        if not (0 <= value <= 255):
            raise ValueError(f"RGB值必须在0-255之间,当前值:{value}")
    return tuple(round(v / 255, decimal_places) for v in rgb_tuple)

def create_jianying_draft(
    draft_name: str,
    resolution: str,
    audio_path: str,
    background_image_path: str,
    background_music_path: str,
    text_styles: List[Dict],
    draft_folder_path: str
) -> None:
    """
    创建剪映草稿,包含音频、背景图片、背景音乐和文字轨道
    
    参数:
        draft_name: 草稿名称
        resolution: 画面尺寸,如"1920*1080"
        audio_path: 音频文件路径
        background_image_path: 底层图片路径
        background_music_path: 背景音乐路径
        text_styles: 文字样式列表
        draft_folder_path: 剪映草稿文件夹路径
    """
    # 校验输入文件是否存在
    for path in [audio_path, background_image_path, background_music_path]:
        if not os.path.exists(path):
            raise FileNotFoundError(f"文件不存在: {path}")
    
    # 解析分辨率
    try:
        width, height = map(int, resolution.split('*'))
    except ValueError:
        raise ValueError(f"分辨率格式错误: {resolution},正确格式应为'宽*高'(如1920*1080)")
    
    # 创建草稿文件夹实例
    draft_folder = draft.DraftFolder(draft_folder_path)
    
    # 创建新草稿(不允许覆盖)
    script = draft_folder.create_draft(
        draft_name, 
        width, 
        height, 
        allow_replace=False
    )
    
    # 添加所需轨道
    script.add_track(TrackType.audio, "main_audio")       # 主音频轨道
    script.add_track(TrackType.video, "background_image") # 背景图片轨道
    script.add_track(TrackType.audio, "bgm")              # 背景音乐轨道
    script.add_track(TrackType.audio, "last_text_bgm")    # 最后文字背景音乐轨道

    
    # 获取主音频时长(微秒)
    main_audio_material = draft.AudioMaterial(audio_path)
    main_audio_duration = main_audio_material.duration
    
    # 添加主音频到轨道
    main_audio_segment = draft.AudioSegment(
        audio_path,
        trange(0, main_audio_duration)
    )
    script.add_segment(main_audio_segment, "main_audio")
    
    # 添加底层图片(与音频时长对齐)
    background_image_segment = draft.VideoSegment(
        background_image_path,
        trange(0, main_audio_duration)
    )
    script.add_segment(background_image_segment, "background_image")
    
    # 添加背景音乐(与音频时长对齐)
    bgm_segment = draft.AudioSegment(
        background_music_path,
        trange(0, main_audio_duration)
    )
    bgm_segment.volume = 1  
    script.add_segment(bgm_segment, "bgm")
    
    # 处理文字轨道
    num_texts = len(text_styles)
    if num_texts == 0:
        raise("警告:文字样式列表为空,未添加任何文字轨道")
    else:
                # 计算每个文本的长度(包含标点符号)和总长度
        total_length = 0
        for text_info_dict in text_styles:
            total_length = total_length+len(text_info_dict ["text"])+1
        
        current_start_time = 0  # 当前文本片段的开始时间

        for i, text_info_dict in enumerate(text_styles):

            # 计算当前文本的长度占比
            text_length = len(text_info_dict["text"])+1
            text_ratio = text_length / total_length
            # 根据比例计算当前文本的显示时长
            text_duration = int(main_audio_duration * text_ratio)

            # 创建独立文字轨道
            track_name = f"text_track_{i}"
            script.add_track(TrackType.text, track_name)
            
            # 计算文字显示时间范围(从当前开始时间一直到整个草稿结束)
            text_timerange = trange(current_start_time, main_audio_duration-current_start_time)
            
            # 结束时间
            text_end_time = current_start_time + text_duration

            # 转换RGB颜色
            try:
                rgb = tuple(text_info_dict["colorRgb"])
                color_float = rgb_255_to_float(rgb)
            except KeyError:
                raise KeyError(f"文字样式列表第{i}项缺少'colorRgb'属性")
            
            # 转换位置坐标
            x_pos = text_info_dict["xPosition"]
            y_pos = text_info_dict["yPosition"]
            transform_x = x_pos / width
            transform_y = y_pos / height
            
            # 获取字体(处理不存在的字体)
            font_name = text_info_dict["fontName"]
            try:
                font = getattr(draft.FontType, font_name)
            except AttributeError:
                print(f"警告:字体'{font_name}'不存在,将使用默认字体")
                font = draft.FontType.文轩体
            
            # 创建文字片段
            text_segment = draft.TextSegment(
                text=text_info_dict["text"],
                timerange=text_timerange,
                font=font,
                style=TextStyle(
                    size=text_info_dict["fontSize"],
                    color=color_float,
                    bold=text_info_dict["isBold"] == "是" or text_info_dict["isBold"] == True,
                    align=1  # 居中对齐
                ),
                clip_settings=ClipSettings(
                    transform_x=transform_x,
                    transform_y=transform_y
                )
            )
            
            # 动画持续时间
            animation_duration = text_end_time-current_start_time

            #如果是最后一个,则添加入场动画
            if i == num_texts - 1:
                # 添加缩小动画
                text_segment.add_animation(TextIntro.缩小, duration=animation_duration)
                # 为最后一段文字添加背景音乐,持续时长以这段音频时长为准
                # 获取音频时长(微秒)
                last_text_audio_duration = draft.AudioMaterial(last_text_background_music_path).duration
                last_text_background_music_segment = draft.AudioSegment(
                    last_text_background_music_path,
                    trange(current_start_time, last_text_audio_duration)
                )
                last_text_background_music_segment.volume = 1  
                script.add_segment(last_text_background_music_segment, "last_text_bgm")
            else:
                text_segment.add_animation(TextIntro.打字机IV, duration=animation_duration)

            # 添加文字到轨道
            script.add_segment(text_segment, track_name)

            # 更新下一个文本的开始时间
            current_start_time += text_duration
    
    # 保存草稿
    script.save()
    
    # 打印成功信息
    print(f"剪映草稿 {draft_name} 创建成功!")


# 示例调用
if __name__ == "__main__":
    draft_name = "视频草稿20"
    resolution = "1920*1080"
    audio_path = "D:\\Desktop\\演示文件\\新建文件夹\\广告男声.mp3"
    background_image_path = "D:\\Desktop\\演示文件\\新建文件夹\\底图.png"
    background_music_path = "D:\\Desktop\\演示文件\\新建文件夹\\打字声.mp3"
    last_text_background_music_path = "D:\\Desktop\\演示文件\\新建文件夹\\bulingbuling.MP3"
    draft_folder = r"D:\download_software\JianyingPro Drafts"
    
    text_styles = [
        {"text":"挑战","fontName":"新青年体","fontSize":18,"colorRgb":[255,0,0],"isBold":"否","xPosition":-1133,"yPosition":710},
        {"text":"每天拆解一个","fontName":"新青年体","fontSize":18,"colorRgb":[248,245,245],"isBold":"否","xPosition":393,"yPosition":720},
        {"text":"视频剪辑知识点","fontName":"新青年体","fontSize":18,"colorRgb":[255,222,0],"isBold":"否","xPosition":-71,"yPosition":293},
        {"text":"今天是","fontName":"新青年体","fontSize":18,"colorRgb":[248,245,245],"isBold":"否","xPosition":-136,"yPosition":-124},
        {"text":"闪回转场效果","fontName":"新青年体","fontSize":18,"colorRgb":[255,222,0],"isBold":"否","xPosition":-95,"yPosition":-594}
    ]
    
    create_jianying_draft(
        draft_name=draft_name,
        resolution=resolution,
        audio_path=audio_path,
        background_image_path=background_image_path,
        background_music_path=background_music_path,
        text_styles=text_styles,
        draft_folder_path=draft_folder
    )
相关推荐
Deitymoon9 分钟前
RV1126——GOP模式调节画面质量
音视频
早起CaiCai14 分钟前
【Pytorch 实践1】手写数字
人工智能·pytorch·python
吴梓穆26 分钟前
Python 语法基础 函数
开发语言·python
huangdong_30 分钟前
京东商品图片与视频采集技术深度解析:m3u8视频合并、SKU图提取
经验分享·音视频
Kobebryant-Manba33 分钟前
学习文本处理
开发语言·python
m0_6174939438 分钟前
PaddleOCR报错:OneDnnContext does not have the input Filter 解决方案汇总
python
李可以量化40 分钟前
量化迅投 QMT vs 聚宽 (JoinQuant)全面分析
python·量化·qmt·ptrade·聚宽
雾沉川1 小时前
Nano11 25H2 精简版 Windows11 系统介绍与部署实操教程
windows
旅僧1 小时前
运行UMI镜像
python
ellenwan20261 小时前
期货跨期价差程序化怎么做:天勤 SP 合约与腿比例核对
python·区块链