使用 Whisper 生成带时间戳的 SRT 字幕文件及进阶应用

心靈之曲
发布: 2025-09-29 13:19:18
原创
454人浏览过

使用 Whisper 生成带时间戳的 SRT 字幕文件及进阶应用

本文详细阐述了如何利用 OpenAI Whisper 模型从音频或视频文件中提取转录文本,并将其格式化为标准的 SRT 字幕文件,包含精确的时间戳。文章首先介绍了Whisper转录结果的结构,随后提供了将这些结果转换为SRT格式的Python代码示例。此外,还探讨了如何通过集成如 PyAnnote 等工具实现说话人分离(Speaker Diarization),从而生成更具识别度的多说话人SRT字幕,并提供了相关的注意事项与最佳实践。

1. 理解 Whisper 的转录结果

openai whisper 模型在完成音频转录后,其返回的 result 对象不仅仅包含完整的转录文本 (result['text']),还包含一个关键的 segments 列表。这个 segments 列表是生成带时间戳 srt 文件的基础,它将整个音频分解成多个语义连贯的短句或片段,每个片段都带有精确的起始时间 (start)、结束时间 (end) 和对应的文本内容 (text)。

result['segments'] 的典型结构如下:

[
  {
    "id": 0,
    "seek": 0,
    "start": 0.0,
    "end": 3.4,
    "text": " 这是一个示例。",
    "tokens": [50363, 261, 264, 5322, 1079, 286, 264, 1374, 13, 50533],
    "temperature": 0.0,
    "avg_logprob": -0.21,
    "compression_ratio": 1.2,
    "no_speech_prob": 0.001
  },
  {
    "id": 1,
    "seek": 3.4,
    "start": 3.4,
    "end": 6.8,
    "text": " 我们将学习如何生成SRT文件。",
    "tokens": [50533, 261, 264, 5322, 1079, 286, 264, 1374, 13, 50533],
    "temperature": 0.0,
    "avg_logprob": -0.21,
    "compression_ratio": 1.2,
    "no_speech_prob": 0.001
  }
  // ... 更多片段
]
登录后复制

可以看到,start 和 end 字段提供了以秒为单位的时间戳,这是构建 SRT 文件的核心数据。

2. 从 Whisper 输出生成 SRT 文件

要将 Whisper 的转录结果转换为 SRT 格式,我们需要遍历 result['segments'] 列表,并按照 SRT 文件的标准格式进行输出。SRT 文件遵循以下结构:

1
00:00:00,000 --> 00:00:03,400
这是一个示例。

2
00:00:03,400 --> 00:00:06,800
我们将学习如何生成SRT文件。
登录后复制

以下是修改后的 Python 代码,它在转录完成后,将结果保存为 .srt 文件:

import os
import whisper
from tqdm import tqdm
import datetime

# 定义存储mp4文件的根目录
root_folder = "C:\Video"

# 加载 Whisper 模型
print("Loading whisper model...")
model = whisper.load_model("base") # 可以根据需求选择 "tiny", "base", "small", "medium", "large"
print("Whisper model complete.")

# 获取待转录的mp4文件数量
print("Getting number of files to transcribe...")
num_files = sum(1 for dirpath, dirnames, filenames in os.walk(root_folder) for filename in filenames if filename.endswith(".mp4"))
print("Number of files: ", num_files)

# 转录mp4文件并显示进度条
with tqdm(total=num_files, desc="Transcribing Files") as pbar:
    for dirpath, dirnames, filenames in os.walk(root_folder):
        for filename in filenames:
            if filename.endswith(".mp4"):
                filepath = os.path.join(dirpath, filename)
                print(f"\nTranscribing: {filename}")
                # 进行转录,fp16=False 适用于没有GPU或GPU不支持FP16的情况
                result = model.transcribe(filepath, fp16=False, verbose=True)

                # 获取不带扩展名的文件名
                filename_no_ext = os.path.splitext(filename)[0]

                # 生成 SRT 文件
                srt_filepath = os.path.join(dirpath, filename_no_ext + '.srt')
                with open(srt_filepath, 'w', encoding='utf-8') as f_srt:
                    for i, segment in enumerate(result['segments']):
                        # SRT 片段序号
                        f_srt.write(str(i + 1) + '\n')

                        # 格式化时间戳
                        start_time = str(datetime.timedelta(seconds=segment['start']))
                        end_time = str(datetime.timedelta(seconds=segment['end']))

                        # 处理毫秒部分,timedelta 默认是微秒,需要转换
                        # 格式化为 HH:MM:SS,msmsms
                        start_ms = int((segment['start'] % 1) * 1000)
                        end_ms = int((segment['end'] % 1) * 1000)

                        start_str = f"{int(segment['start'] // 3600):02}:{int((segment['start'] % 3600) // 60):02}:{int(segment['start'] % 60):02},{start_ms:03}"
                        end_str = f"{int(segment['end'] // 3600):02}:{int((segment['end'] % 3600) // 60):02}:{int(segment['end'] % 60):02},{end_ms:03}"

                        f_srt.write(f"{start_str} --> {end_str}\n")

                        # 写入转录文本
                        f_srt.write(segment['text'].strip() + '\n\n') # strip() 移除 Whisper 可能生成的首尾空格

                print(f"SRT file saved to: {srt_filepath}")

                # 如果仍然需要txt文件,可以保留以下代码
                # transcription = result['text']
                # with open(os.path.join(dirpath, filename_no_ext + '.txt'), 'w', encoding='utf-8') as f_txt:
                #     f_txt.write(transcription)

                pbar.update(1)

print("\nAll files transcribed and SRT files generated.")
登录后复制

代码说明:

  • datetime.timedelta 和时间格式化: SRT 格式要求时间戳为 HH:MM:SS,ms。虽然 datetime.timedelta 可以方便地计算时间差,但直接转换为字符串时,其毫秒部分可能不符合 SRT 的 xxx,yyy 格式。因此,代码中直接通过数学运算来提取小时、分钟、秒和毫秒,并使用 f-string 进行格式化,确保毫秒部分始终为三位数。
  • segment['text'].strip(): Whisper 生成的文本片段有时可能包含前导或尾随空格,strip() 方法可以清除这些不必要的空格,使字幕更整洁。
  • 编码 建议使用 encoding='utf-8' 打开文件,以确保正确处理各种语言字符。

3. 进阶:集成说话人分离 (Speaker Diarization)

虽然上述方法可以生成带时间戳的 SRT 文件,但如果音频中包含多个说话人,生成的字幕不会区分是谁在说话。为了在 SRT 文件中标识不同的说话人,我们需要进行说话人分离(Speaker Diarization)。说话人分离是一种识别音频中不同说话人并标注其说话时段的技术。

PyAnnote 的作用:

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店 56
查看详情 AppMall应用商店

PyAnnote 是一个强大的开源工具包,专注于音频分析,其中包括高质量的说话人分离功能。通过集成 PyAnnote,我们可以:

  1. 识别说话人边界: 精确地识别音频中每个说话人开始和结束说话的时间点。
  2. 分配说话人标签: 为每个说话片段分配一个唯一的说话人标签(例如:[Speaker A]、[Speaker B])。

集成思路:

集成 PyAnnote 通常涉及以下步骤:

  1. 运行 Whisper 转录: 首先使用 Whisper 获取初步的文本转录和时间戳。
  2. 运行 PyAnnote 说话人分离: 将相同的音频文件输入到 PyAnnote 模型中,获取每个说话人的时间段和标签。
  3. 合并结果: 将 Whisper 的文本片段与 PyAnnote 的说话人标签进行匹配。这通常意味着遍历 Whisper 的每个文本片段,根据其时间戳,查找在该时间段内说话的 PyAnnote 识别出的说话人。
  4. 生成增强型 SRT: 在 SRT 文件的文本内容前加上说话人标签,例如:[Speaker A] 这是一个示例。

示例(概念性,不含完整 PyAnnote 代码):

# ... (Whisper 转录代码,获取 result['segments']) ...

# 假设您已通过 PyAnnote 获取了说话人分离结果,
# 格式可能类似:[{'speaker': 'SPEAKER_00', 'start': 0.5, 'end': 2.1}, ...]
# diarization_result = run_pyannote_diarization(filepath) 

# 合并 Whisper 和 Diarization 结果,生成增强型 SRT
# for i, segment in enumerate(result['segments']):
#     # 查找与当前segment时间重叠的diarization_result,确定说话人
#     speaker_label = get_speaker_for_segment(segment, diarization_result) 
#     formatted_text = f"[{speaker_label}] {segment['text'].strip()}"
#     # ... 写入 SRT 文件 ...
登录后复制

请注意,PyAnnote 的集成需要额外的安装和配置,并且其 API 使用方式相对复杂,涉及到模型加载、管道构建等。具体的实现会超出本教程的范围,但其核心思想是利用两个工具的优势,共同生成更丰富、更准确的字幕。

4. 注意事项与最佳实践

  • Whisper 模型选择: Whisper 提供多种模型尺寸(tiny, base, small, medium, large)。模型越大,准确度越高,但转录速度越慢,所需的内存也越多。根据您的硬件资源和准确度需求进行选择。
  • fp16 参数: fp16=True 可以在支持半精度浮点运算的 GPU 上显著提高转录速度并减少内存占用。如果您的系统没有兼容的 GPU 或遇到错误,请将其设置为 False。
  • verbose 参数: verbose=True 会在转录过程中在控制台输出详细信息。在批量处理时,如果不需要这些实时日志,可以设置为 False 以减少输出。
  • 文件路径: 确保 root_folder 路径正确,并且 Python 脚本对该目录及其子目录有读写权限。
  • 长音频文件处理: 对于非常长的音频文件,Whisper 会自动进行分块处理。但在极端情况下,内存使用仍可能较高。如果遇到内存问题,可能需要手动将音频文件预处理成更小的片段。
  • SRT 时间戳精度: Whisper 提供的 start 和 end 时间戳通常精确到毫秒级别,足以满足大多数字幕需求。

总结

通过本文的指导,您应该已经掌握了如何利用 OpenAI Whisper 模型不仅生成音频的文本转录,还能进一步将其格式化为标准的 SRT 字幕文件,并包含精确的时间戳。此外,我们还探讨了通过集成 PyAnnote 等专业工具实现说话人分离的进阶应用,这能为多说话人场景下的字幕文件增添关键的说话人标识信息,从而大大提升字幕的可用性和阅读体验。在实际应用中,根据项目需求和资源限制,合理选择 Whisper 模型和是否集成说话人分离功能,将帮助您高效地生成高质量的字幕。

以上就是使用 Whisper 生成带时间戳的 SRT 字幕文件及进阶应用的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号