前言

字幕文件中包含很多段信息,每一段表示了一句话的起始结束时间和内容,因此便涉及到了端点检测技术和语音识别技术。

  • 端点检测:pydub.silence.detect_nonsilent
  • 语音识别:aip.AipSpeech(百度接口)

pip install pydub
pip install baidu-aip

1. 流程

  • 视频提取音频
  • 对音频进行端点检测,生成一句一句的音频
  • 对各句音频进行语音识别
  • 整合成字幕srt格式

2. 代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from moviepy.editor import *
from pydub import *
from aip import AipSpeech

video_file = r'C:\Users\Lenovo\Desktop\video_sep\test.mp4'
audio_file = r'C:\Users\Lenovo\Desktop\test.wav'
srt_file = r'C:\Users\Lenovo\Desktop\srt\test.srt'

## transform to audio
video = VideoFileClip(video_file)
video.audio.write_audiofile(audio_file, ffmpeg_params=['-ar','16000','-ac','1'])

## segment
sound = AudioSegment.from_wav(audio_file)
timestamp_list = silence.detect_nonsilent(sound, 700, sound.dBFS*1.3, 1)    # look here
for i in range(len(timestamp_list)):
    d = timestamp_list[i][1] - timestamp_list[i][0]
    print("Section is :", timestamp_list[i], "duration is:", d)
print('dBFS: {0}, max_dBFS: {1}, duration: {2}, split: {3}'.format(round(sound.dBFS,2),round(sound.max_dBFS,2),sound.duration_seconds,len(timestamp_list)))

def format_time(ms):
    hours = ms // 3600000
    ms = ms % 3600000
    minutes = ms // 60000
    ms = ms % 60000
    seconds = ms // 1000
    mseconds = ms % 1000
    return '{:0>2d}:{:0>2d}:{:0>2d},{:0>3d}'.format(hours, minutes, seconds, mseconds)

## 以下在百度AI开放平台申请获得
## https://ai.baidu.com/tech/speech
APP_ID = ''
API_KEY = ''
SECRET_KEY = ''
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

idx = 0
text = []
for i in range(len(timestamp_list)):
    d = timestamp_list[i][1] - timestamp_list[i][0]
    data = sound[timestamp_list[i][0]:timestamp_list[i][1]].raw_data
    ## asr
    result = client.asr(data, 'pcm', 16000, {'lan': 'zh',})     ## and look here
    if result['err_no'] == 0:
        text.append('{0}\n{1} --> {2}\n'.format(idx, format_time(timestamp_list[i][0]), format_time(timestamp_list[i][1])))
        text.append( result['result'][0]) #.replace(",", "")
        text.append('\n')
        idx = idx + 1
        # print(format_time(timestamp_list[i][0]/ 1000), "txt is ", result['result'][0])
with open(srt_file,"w") as f:
    f.writelines(text)

3. 字幕生成的其他方式

3.1 通过双门限法进行端点检测

双门限法的原理是浊音的能量高于清音,清音的过零率高于无声部分。因此,其核心在于:先利用能量,将浊音部分区分出来,再利用过零率,将清音也提取出来,就完成了端点检测。

在这里插入图片描述

3.2 通过 SpeechRcognition 进行语音识别

SpeechRcognition 可以说是一款语音识别集合器,共包含了谷歌、必应、IBM等七个识别器:

  • recognize_bing():Microsoft Bing Speech
  • recognize_google(): Google Web Speech API
  • recognize_google_cloud():Google Cloud Speech - requires installation of the google-cloud-speech package
  • recognize_houndify(): Houndify by SoundHound
  • recognize_ibm():IBM Speech to Text
  • recognize_sphinx():CMU Sphinx - requires installing PocketSphinx
  • recognize_wit():Wit.ai

基本使用方法如下:

import speech_recognition as sr
r = sr.Recognizer()
test = sr.AudioFile(r'C:\Users\Lenovo\Desktop\test.wav')
with test as source:
    audio = r.record(source)
r.recognize_google(audio, language='zh-CN', show_all= True)

但好像需要翻墙才能用…

3.3 通过autosub包直接生成字幕文件

autosub是一个直接可以生成字幕文件的python库。基本用法如下:

autosub -S zh-CN -D zh-CN [你的视频/音频文件名]

不过这种方法也需要翻墙,我尝试了更改proxy也没什么效果…

4. 总结

总体而言,字幕生成需要的两个技术块,各有多种实现方法,而我最终选取的pydub加baidu-aip是相对简单并且有效的一种。不过实测效果并没有达到我的期望,因为一开始端点检测就不是十分准确,导致在错误的句子里上下文关系也不太对,语音识别也会有偏差了。更进一步的端点检测方法还得综合考虑能量和过零率,最好还要自定义地加上各个句子长度不能相差太大的限制等等。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐