# -*- coding: utf-8 -*- """ 营销短视频生成自动化 功能清单 1、打开并读取任务 2、按照初始化剪映草稿、分别添加视频轨、音频轨、字幕轨和图片轨等、生成视频执行任务 """ import asyncio from pathlib import Path import edge_tts async def audio_gen( text: str, output_path: Path, voice_name: str = "zh-CN-XiaoxiaoNeural" ): # 可用的中文语音列表 # chinese_voices = { # "女声-晓晓": "zh-CN-XiaoxiaoNeural", # 年轻女声,自然 # "女声-晓辰": "zh-CN-XiaochenNeural", # 年轻女声,温暖 # "女声-晓墨": "zh-CN-XiaomoNeural", # 女声,富有表现力 # "男声-晓悠": "zh-CN-XiaoyouNeural", # 儿童音,可爱 # "男声-晓涵": "zh-CN-XiaohanNeural", # 年轻男声,温暖 # "男声-晓睿": "zh-CN-XiaoruiNeural", # 成熟男声,沉稳 # "女声-晓倩": "zh-CN-XiaoqianNeural", # 女声,成熟 # "男声-晓东": "zh-CN-XiaodongNeural", # 男声,权威 # } # 生成语音 communicate = edge_tts.Communicate( text, voice_name, rate="+0%", pitch="+0Hz", volume="+0%" ) await communicate.save(output_path) print(f"语音已保存到: {output_path}") # ---- import pycapcut as capcut from pycapcut import KeyframeProperty, SEC from pycapcut import FontType, TextStyle, ClipSettings from typing import List import srt async def video_merge_audio_and_caption( video_path: Path, audioPathList: List[Path], image_path: Path, subtitleList: List[srt.Subtitle], output_path: Path, ): PROJECT_DIR = "C:\\Users\\z4938\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft" draft_folder = capcut.DraftFolder(PROJECT_DIR) script = draft_folder.create_draft("新草稿", 1920, 1080) print("成功创建 draft(剪映项目草稿)") # 添加视频轨 video_track_id = 1 script.add_track( capcut.TrackType.video, track_name="视频", relative_index=video_track_id ) video_mat = capcut.VideoMaterial(video_path) video_seg = capcut.VideoSegment(video_mat, capcut.Timerange(0, video_mat.duration)) video_seg.add_keyframe(KeyframeProperty.alpha, video_seg.duration - SEC, 1.0) video_seg.add_keyframe(KeyframeProperty.alpha, video_seg.duration, 0.0) video_seg.volume = 0 script.add_segment(video_seg, "视频") print( f"视频素材导入成功,素材ID:{video_seg.material_id}, 片段id:{video_seg.segment_id}" ) # 添加logo图片轨 logo_track_id = 2 script.add_track( capcut.TrackType.video, track_name="logo图片", relative_index=logo_track_id ) logo_mat = capcut.VideoMaterial(image_path) logo_seg = capcut.VideoSegment(logo_mat, capcut.Timerange(0, video_mat.duration)) logo_seg.add_keyframe(KeyframeProperty.alpha, video_seg.duration - SEC, 1.0) logo_seg.add_keyframe(KeyframeProperty.alpha, video_seg.duration, 0.0) script.add_segment(logo_seg, "logo图片") print(f"logo导入成功,视频轨道id:{logo_track_id}") # 添加音频轨 script.add_track(capcut.TrackType.audio, track_name="音频", relative_index=3) for audio_path in audioPathList: audio_mat = capcut.AudioMaterial(audio_path) audio_seg = capcut.AudioSegment( audio_mat, capcut.Timerange(0, audio_mat.duration), source_timerange=capcut.Timerange(0, audio_mat.duration), ) script.add_segment(audio_seg, "音频") print( f"音频素材导入成功,素材ID:{audio_seg.material_id}, 片段id:{audio_seg.segment_id}" ) # 添加字幕轨 script.add_track(capcut.TrackType.text, track_name="字幕", relative_index=4) for subtitle in subtitleList: text_seg = capcut.TextSegment( subtitle.content, capcut.Timerange( subtitle.start.total_seconds(), subtitle.end.total_seconds() ), font=FontType.下午茶, style=TextStyle( size=5.0, color=(0.7, 0.7, 1.0), auto_wrapping=True, underline=True, align=1, ), clip_settings=ClipSettings(transform_y=-0.8), ) script.add_segment(text_seg, "字幕") print("字幕添加成功") export_result = script.export( output_path=output_path, resolution="1080p", fps=30, quality="high" ) print(f"视频导出完成!result: {export_result}, 成品路径:{output_path}") # ---- from datetime import timedelta from moviepy import AudioFileClip async def main(): TEXT_PATH_STR = "D:\\develop\\trkj\\resources\\tts_text.txt" AUDIO_PATH_STR_FMT = "D:\\develop\\trkj\\resources\\audio_tts_{}.aac" SRT_PATH_STR = "D:\\develop\\trkj\\resources\\tts_text_srt.srt" VIDEO_PATH_STR = "D:\\develop\\trkj\\resources\\test_video.mp4" IMAGE_PATH_STR = "D:\\develop\\trkj\\resources\\logo.png" OUTPUT_PATH_STR = "D:\\develop\\trkj\\resources\\video_output.mp4" videoPath = Path(VIDEO_PATH_STR) audioPathList = list() subtitleList = list() imagePath = Path(IMAGE_PATH_STR) outputPath = Path(OUTPUT_PATH_STR) with open(TEXT_PATH_STR, "r", encoding="UTF-8") as text_f: line = text_f.readline() i = 0 next_start_seconds = timedelta(seconds=0.0) while line: audioPath = AUDIO_PATH_STR_FMT.format(i) # 每行生成音频 await audio_gen(line, audioPath) audioPathList.append(audioPath) # 创建音频对应的字幕 audio = AudioFileClip(audioPath) try: current_start_seconds = next_start_seconds current_end_seconds = next_start_seconds + timedelta( seconds=audio.duration ) subtitle = srt.Subtitle( index=i + 1, start=current_start_seconds, end=current_end_seconds, content=line.strip(), ) subtitleList.append(subtitle) finally: audio.close() line = text_f.readline() i = i + 1 next_start_seconds = current_end_seconds srt_content = srt.compose(subtitleList) with open(SRT_PATH_STR, "w", encoding="UTF-8") as srt_file: srt_file.write(srt_content) print(f"字幕文件已生成: {SRT_PATH_STR}") await video_merge_audio_and_caption( videoPath, audioPathList, imagePath, subtitleList, outputPath ) if __name__ == "__main__": asyncio.run(main())