当前位置: 首页 > news >正文

python_字幕文本、音频、视频一键组合

python_字幕文本、音频、视频一键组合

importosimportreimportrandomimportpyJianYingDraftasdraftfrompyJianYingDraftimport(TrackType,TextStyle,ClipSettings,TextBackground,KeyframeProperty,trange)defsplit_subtitle(subtitle):"""将字幕按指定标点符号拆分短句,保留标点符号在句尾"""separators=r'([,。!,!?;])'parts=re.split(separators,subtitle)sentences=[]foriinrange(0,len(parts)-1,2):ifparts[i]orparts[i+1]:# 避免空字符串sentences.append(parts[i]+parts[i+1])# 处理可能剩余的部分(如果字幕不以标点结尾)iflen(parts)%2==1andparts[-1].strip():sentences.append(parts[-1].strip())returnsentencesdefcreate_jianying_draft(draft_name,subtitle_texts,audio_paths,video_paths,draft_folder_path,background_image=None,background_music=None,add_camera_movement=True):""" 创建剪映草稿,支持视频、音频、字幕同步处理,根据视频横竖屏自适应调整,支持字幕拆分和运镜效果 参数说明: draft_name: 草稿名称 subtitle_texts: 字幕文本列表 audio_paths: 音频路径列表 video_paths: 视频路径列表 draft_folder_path: 剪映草稿文件夹路径 background_image: 背景图片路径(可选) background_music: 背景音乐路径(可选) add_camera_movement: 是否添加运镜效果(可选,默认True) """# 定义6种运镜效果的关键帧设置函数defadd_zoom_in(segment,duration):"""从远到近(放大)"""segment.add_keyframe(KeyframeProperty.uniform_scale,0,1)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=0)defadd_zoom_out(segment,duration):"""从近到远(缩小)"""segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.25)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=0)defadd_move_up(segment,duration):"""从下到上"""segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.25)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=-0.25)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=0.25)defadd_move_down(segment,duration):"""从上到下"""segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.25)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=0.25)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=-0.25)defadd_move_left(segment,duration):"""从右到左"""segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.25)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=-0.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=0.25)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=0)defadd_move_right(segment,duration):"""从左到右"""segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.25)segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=duration,value=1.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=0,value=0.25)segment.add_keyframe(KeyframeProperty.position_x,time_offset=duration,value=-0.25)segment.add_keyframe(KeyframeProperty.position_y,time_offset=0,value=0)segment.add_keyframe(KeyframeProperty.position_y,time_offset=duration,value=0)# 运镜效果列表camera_effects=[add_zoom_in,add_zoom_out,add_move_up,add_move_down,add_move_left,add_move_right]# 校验输入参数长度一致性iflen(subtitle_texts)!=len(audio_paths)orlen(audio_paths)!=len(video_paths):raiseValueError("字幕文本列表、音频路径列表、视频路径列表长度必须一致")# 校验视频路径有效性ifnotvideo_paths:raiseValueError("视频路径列表不能为空")# 检查所有文件是否存在missing_files=[]forvideo_pathinvideo_paths:ifnotos.path.exists(video_path):missing_files.append(f"视频:{video_path}")foraudio_pathinaudio_paths:ifnotos.path.exists(audio_path):missing_files.append(f"音频:{audio_path}")ifbackground_imageandnotos.path.exists(background_image):missing_files.append(f"背景图片:{background_image}")ifbackground_musicandnotos.path.exists(background_music):missing_files.append(f"背景音乐:{background_music}")ifmissing_files:raiseFileNotFoundError(f"以下文件不存在:\n"+"\n".join(missing_files))# 初始化草稿文件夹draft_folder=draft.DraftFolder(draft_folder_path)# 检查草稿是否已存在ifdraft_folder.has_draft(draft_name):raiseFileExistsError(f"草稿 '{draft_name}' 已存在,不允许覆盖")# 获取第一个视频的信息以确定尺寸和横竖屏first_video=draft.VideoMaterial(video_paths[0])width,height=first_video.width,first_video.height# 根据视频横竖屏设置字幕参数ifwidth>height:# 横屏font_size=6.0subtitle_y=-0.8else:# 竖屏font_size=13.0subtitle_y=-0.3# 创建新草稿script=draft_folder.create_draft(draft_name,width,height,allow_replace=False# 不允许覆盖已有草稿)# 添加所需轨道track_builder=script.add_track(TrackType.video,"视频轨道")\.add_track(TrackType.audio,"音频轨道")\.add_track(TrackType.text,"字幕轨道")ifbackground_image:# 背景图片放到底层(相对索引值大表示更靠后)track_builder.add_track(TrackType.video,"背景图片轨道",relative_index=3)ifbackground_music:track_builder.add_track(TrackType.audio,"背景音乐轨道")current_time=0# 当前时间点(微秒)total_duration=0# 总时长(微秒)separators=r'([,。!,!?;])'# 处理每个片段(视频、音频、字幕)foriinrange(len(subtitle_texts)):audio_path=audio_paths[i]video_path=video_paths[i]subtitle_text=subtitle_texts[i]# 创建音频片段并获取时长audio_material=draft.AudioMaterial(audio_path)audio_duration=audio_material.duration time_range=trange(current_time,audio_duration)audio_segment=draft.AudioSegment(audio_path,time_range)script.add_segment(audio_segment,"音频轨道")# 创建视频片段(根据音频时长调整速度)video_material=draft.VideoMaterial(video_path)video_duration=video_material.duration speed=video_duration/audio_duration# 计算所需速度以匹配音频时长video_segment=draft.VideoSegment(video_path,time_range,speed=speed)# 设置视频居中显示video_segment.clip_settings=ClipSettings(transform_x=0,transform_y=0,)# 添加关键帧确保视频保持比例video_segment.add_keyframe(KeyframeProperty.uniform_scale,time_offset=0,value=1.0)# 随机添加运镜效果ifadd_camera_movement:effect=random.choice(camera_effects)effect(video_segment,audio_duration)script.add_segment(video_segment,"视频轨道")# 拆分字幕为短句并添加sentences=split_subtitle(subtitle_text)total_length=len(subtitle_text)# 如果没有拆分出短句(无标点符号),使用原字幕ifnotsentences:sentences=[subtitle_text]# 计算每个短句的显示时间并添加current_sub_time=current_timeforsentenceinsentences:# 计算短句长度占比(避免除零错误)iftotal_length==0:ratio=1.0/len(sentences)else:ratio=len(sentence)/total_length# 计算当前短句的显示时长sentence_duration=int(audio_duration*ratio)# 确保至少有100ms的显示时间sentence_duration=max(sentence_duration,100000)# 100,000微秒 = 0.1秒# 计算当前短句的时间范围sentence_time_range=trange(current_sub_time,sentence_duration)# 添加字幕片段text_segment=draft.TextSegment(re.sub(separators,'',sentence),# 移除标点符号sentence_time_range,font=draft.FontType.文轩体,style=TextStyle(color=(1.0,1.0,1.0),# 白色文字size=font_size,# 根据横竖屏设置字体大小align=1,# 居中对齐auto_wrapping=True,# 开启自动换行max_line_width=0.8,# 每行最大宽度为屏幕宽度的80%),background=TextBackground(color="#000000",# 黑色背景alpha=0.5,# 背景透明度round_radius=0.1,# 背景圆角height=0.15,# 背景高度width=0.8# 背景宽度),clip_settings=ClipSettings(transform_y=subtitle_y)# 根据横竖屏设置位置)script.add_segment(text_segment,"字幕轨道")# 更新当前字幕时间current_sub_time+=sentence_duration# 更新时间current_time+=audio_duration total_duration=current_time# 处理背景图片ifbackground_image:image_segment=draft.VideoSegment(background_image,trange(0,total_duration))script.add_segment(image_segment,"背景图片轨道")# 处理背景音乐ifbackground_music:music_material=draft.AudioMaterial(background_music)music_duration=music_material.duration current_music_time=0# 循环添加背景音乐直到达到总时长whilecurrent_music_time<total_duration:remaining_time=total_duration-current_music_time segment_duration=min(music_duration,remaining_time)music_segment=draft.AudioSegment(background_music,trange(current_music_time,segment_duration),volume=0.3,# 降低背景音乐音量source_timerange=trange(0,segment_duration))script.add_segment(music_segment,"背景音乐轨道")current_music_time+=segment_duration# 保存草稿script.save()# 打印成功提示print(f"剪映草稿{draft_name}创建成功!")# 使用示例:create_jianying_draft(draft_name="示例草稿19",subtitle_texts=["在一座古老小镇,每到清明便细雨纷纷。年轻画师林羽,每到此时总会对着一幅未完成的画发呆。","这幅画始于七年前,画中女子荷风微摆衣角,宛如仙子。","七年前,林羽与名叫婉清的姑娘相遇,二人一见钟情。"],audio_paths=['D:\\Desktop\\test_folder\\jianying_materials_2\\audios\\01.mp3','D:\\Desktop\\test_folder\\jianying_materials_2\\audios\\02.mp3','D:\\Desktop\\test_folder\\jianying_materials_2\\audios\\03.mp3'],video_paths=['D:\\Desktop\\test_folder\\jianying_materials_2\\videos\\04.mp4','D:\\Desktop\\test_folder\\jianying_materials_2\\videos\\05.mp4','D:\\Desktop\\test_folder\\jianying_materials_2\\videos\\06.mp4'],# background_image="D:\\Desktop\\test_folder\\jianying_materials_2\\影刀logo图片_横版.png",background_image="D:\\Desktop\\test_folder\\jianying_materials_2\\影刀logo图片_竖版.png",background_music="D:\\Desktop\\test_folder\\jianying_materials_2\\background_music.mp3",draft_folder_path="D:\\download_software\\JianyingPro Drafts")
http://www.cnnetsun.cn/news/51209.html

相关文章:

  • Python第三次作业
  • 44、深入探索GDB调试技巧与C/C++代码调试
  • 复盘 Git+GitHub SSH 配置:从权限报错到免密推送的全流程解决方案
  • Screenbox媒体播放器隐藏功能终极指南:从入门到精通
  • FlashAttention终极指南:突破大模型训练内存瓶颈的完整教程
  • 冒泡排序 ~ 背下来的 哭
  • 手把手教你学Simulink——机器人轨迹跟踪场景实例:基于Simulink的永磁同步电机关节空间直线轨迹跟踪控制仿真
  • 盈富宝典 通达信主图
  • 14、Python在不同场景下的应用与实践
  • X-AnyLabeling 自动数据标注保姆级教程:从安装到格式转换全流程
  • 38、深入探索bc计算器、数组及特殊编程技巧
  • vue基于Spring Boot框架的技术实现的医院住院管理系统_229p8ejv
  • 基于vue的停车场预约管理系统地图_n7nz82g6_springboot php python nodejs
  • 基于vue的宠物领养系统的设计与实现_389i5918_springboot php python nodejs
  • 基于vue的生鲜团购管理系统设计与实现优惠卷_2av6282k_springboot php python nodejs
  • React Native桌面应用交互终极指南:从点击事件到原生菜单完整教程
  • Springboot美食分享网站a73c9(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • Springboot门店运营管理系统hd158(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • Stellarium望远镜控制实战指南:从硬件连接到精准观测
  • 快速验证:基于CentOS 7.6的测试环境搭建
  • AI定价实战指南:快速构建电商智能定价系统
  • VGGT三维重建终极指南:从零开始构建你的3D世界
  • 电商网站秒开秘籍:快马AI加载优化案例
  • 15分钟快速验证:谷歌服务离线包生成器原型开发
  • 1小时搞定ElementUI原型:快马平台实战
  • 从天喵装机案例看中小企业IT设备采购新范式
  • Flink面试题实战:从问题到解决方案
  • 5分钟用C# Socket搭建文件传输原型
  • 论文查重不花一分钱?宏智树AI开启学术诚信新“净”界!
  • 最强安卓投屏神器QtScrcpy