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

视频字幕python自动提取

写在前面:主要原理是提取视频中的音频,通过语音识别文字的方法完成字幕提取;因此,不支持没有声音的视频。

1.音频提取


def convert_mp4_to_mp3(input_file, output_file):
    """Convert MP4 video file to MP3 audio."""
    video_clip = VideoFileClip(input_file)
    audio = video_clip.audio
    audio.write_audiofile(output_file)

2.音频转文字

model = whisper.load_model(WHISPER_MODEL_PATH).to(device)
def transcribe_audio(file_path):
    """Transcribe audio file using Whisper model."""
    result = model.transcribe(
    file_path,
    language="zh",# Explicitly tell Whisper to use Chinese
    task="transcribe",
    initial_prompt="这是一段视频教程,请加上标点符号",
    beam_size=5,# Add beam_size directly
    prompt="- 吃了没?- 吃了。",# Add prompt directly
    word_timestamps=True,  # 设置为 True 以获取单词时间戳
    fp16=False,
    )
    return result

3.文字保存为字幕


def save_transcription_to_srt(segments, file_path):
    """Save transcription segments to an SRT file."""
    with open(file_path, 'w', encoding='utf-8') as f:
        for i, segment in enumerate(segments):
            f.write(f"{i + 1}\n")
            f.write(f"{seconds_to_hmsm(segment['start'])} --> {seconds_to_hmsm(segment['end'])}\n")
            translated_text = translate_text(segment['text'])
            f.write(segment['text'] + f'\n{translated_text}\n\n')

该代码中

translated_text = translate_text(segment['text'])

功能是对字幕进行翻译,因此保存的字幕为双语字幕(解放字幕组劳动力o(* ̄▽ ̄*)ブ)。翻译方法很多,简单提供一个基于ollama的翻译。


def translate_text(content):
    """Translate text to English using Ollama."""
    stream = ollama.chat(
        model="llama3.2:1b",
        messages=[{"role": "user", "content": f"下列文字翻译为简体中文,只输出翻译结果:{content}"}],
        stream=True
    )
    output = ''
    for chunk in stream:
        output += chunk['message']['content']
    return output

在上述功能的基础上,进阶两个功能。

4.更新字幕到视频内


def videoclip_with_subtitles(src_mp4, dst_mp4, srt_file):
    """Add translated subtitles to the video."""
    video = VideoFileClip(src_mp4)
    subtitles = parse_srt(srt_file)
    text_clips = []

    for text, start, duration in tqdm(subtitles):
        # translated_text = translate_text(text)
        wrapped_text = insert_newlines(text, max_words=10)
        text_clip = (TextClip(wrapped_text, font='msyh.ttc', fontsize=30, color='red')
                     .set_position('top')
                     .set_duration(duration)
                     .set_start(start))
        text_clips.append(text_clip)
    
    final_video = CompositeVideoClip([video, *text_clips])
    final_video.write_videofile(dst_mp4, audio_codec='aac')

其中字幕解析为:


def parse_srt(srt_file):
    """Parse SRT file and return subtitles as text, start time, and duration."""
    subtitles = []
    with open(srt_file, 'r', encoding='utf-8') as file:
        content = file.read()
        entries = re.split(r'\n\n+', content.strip())
        for entry in entries:
            lines = entry.splitlines()
            if len(lines) >= 3:
                time_range = lines[1]
                start, end = time_range.split('-->')
                start_time = convert_srt_time_to_seconds(start)
                duration = convert_srt_time_to_seconds(end) - start_time
                text = '\n'.join(lines[2:])
                subtitles.append((text, start_time, duration))
    return subtitles

5.根据新的字幕,生成新的音频(方法很多,另开贴,更新后网址会贴在这里),即可以将外文音频转为中文音频。(代码还存在一些缺陷,修改后更新)

def text_to_speech(text, mp3_filename="output.mp3"):
    # 初始化TTS引擎
    engine = pyttsx3.init()
    
    # 设置语音属性(可选)
    engine.setProperty('rate', 150)  # 语速
    engine.setProperty('volume', 1)  # 音量 (0.0到1.0)
    
    # 保存为WAV文件
    wav_filename = "1.wav"
    engine.save_to_file(text, wav_filename)
    engine.runAndWait()

    # 使用pydub将WAV转换为MP3
    audio = AudioSegment.from_wav(wav_filename)
    audio.export(mp3_filename, format="mp3")

# 读取字幕文件
subs = pysrt.open('data\\27364690929-1-192.srt')

# 创建一个空的音频文件列表
audio_clips = []

# 遍历每条字幕
for sub in tqdm(subs):
    # 将字幕文本转换为语音
    text_list = sub.text.split('\n')
    text_zh = text_list[-1]  # 确保提取的文本是字符串而不是列表

    # 生成音频文件
    audio_filename = f"audio_temp/audio_{sub.index}.mp3"
    text_to_speech(text_zh, audio_filename)

    # 创建音频片段
    audio_clip = AudioFileClip(audio_filename)

    # 确保使用正确的单位:毫秒到秒
    # duration = (sub.end.ordinal - sub.start.ordinal) / 1000  # 转为秒
    # audio_clip = audio_clip.set_duration(duration)

    # 计算合适的开始时间
    start_time = sub.start.ordinal  # 转为秒
    audio_clip = audio_clip.set_start(start_time)

    audio_clips.append(audio_clip)

# 合并所有音频片段
final_audio = concatenate_audioclips(audio_clips)

将新的音频合并到视频内,即可完成音频替换

video = VideoFileClip('data\\27364690929-1-192.mp4').without_audio()

# 将新的音频合并到视频中
final_video = video.set_audio(final_audio)

# 保存最终视频
final_video.write_videofile('data\\27364690929-1-192-zh-audio.mp4', codec='libx264')

github上有一些非常棒的类似项目,做完才看到,还没深入研究,大家可以上去多看看。

相关文章:

  • Redis + Caffeine多级缓存电商场景深度解析
  • 北斗导航 | 改进最小二乘残差法的接收机自主完好性监测算法原理,公式,应用,研究综述,matlab代码
  • 在java中使用Redis
  • C 语言输入输出详解
  • 从零构建大语言模型全栈开发指南:第三部分:训练与优化技术-3.2.3预训练任务设计:掩码语言建模(MLM)与下一句预测(NSP)
  • 伊利工业旅游4.0,近距离感受高品质的魅力
  • Navicat连接postgresql时出现“datlastsysoid does not exist”报错的问题
  • Ruoyi-vue前后端分离系统部署
  • 如何在linux中部署dns服务 主备dns (详细全过程)
  • vue中使用threejs的加载纹理没有效果
  • 安卓-关于setOnTouchListener和setOnClickListener冲突的问题
  • 2025_0327_生活记录
  • vue配置.eslintrc、.prettierrc详解
  • 如何让 AI 搜索为您的企业可见性战略助力飞升!
  • 外贸独立站相关知识扫盲
  • 网路传输层UDP/TCP
  • 【YOLOE: Real-Time Seeing Anything】predict_visual_prompt.py视觉推理代码分析(检测版本)
  • 【漏洞修复】为了修复ARM64 Android10系统的第三方库漏洞,将ARM64 Android16的系统库直接拷贝到Android10系统如何?
  • 【HTML】验证与调试工具
  • webpack配置详解+项目实战
  • wordpress注册跳过邮箱验证/河南纯手工seo
  • 做动态头像的网站/营业推广方式
  • 网站安全证书过期怎么办/深圳网络推广有几种方法
  • 专门做电商的招聘网站/百度推广入口登录
  • 房产网站建设/运营商推广5g技术
  • 旅游网站需求分析/百度客服中心人工电话