ML8*_*L85 2 python audio speech-recognition webrtc librosa
我正在使用 webrtcvad 和 pydub 处理音频文件。任何片段的分割都是通过句子的沉默来进行的。有什么方法可以在字级边界条件下完成分割吗?(在每个说出的单词之后)?如果librosa/ffmpeg/pydub有这样的功能,每个人声可以分割吗?但分割后,我需要人声的开始和结束时间,准确地说是人声部分在原始文件中的位置。ffmpeg 分割的一种简单解决方案或方法也定义为:
https://gist.github.com/vadimkantorov/00bf4fbe4323360722e3d2220cc2915e
但这也是通过沉默进行分割,并且对于每个填充数或帧大小,分割是不同的。我正在尝试按声音分开。例如,我已手动完成此操作,原始文件、拆分词及其在 json 中的时间位置位于链接下提供的文件夹中:
www.mediafire.com/file/u4ojdjezmw4vocb/attached_problem.tar.gz
将音频预处理成合适的特征后,可以使用隐马尔可夫模型来处理简单的音频分割问题。语音的典型特征是声级、声音活动/浊音。为了获得词级分割(而不是句子),需要具有相当高的时间分辨率。不幸的是,pyWebRTCVAD 没有可调节的时间平滑功能,因此它可能不适合该任务。
在您的音频样本中,有一位电台主持人用德语说得相当快。查看您标记的单词边界的声级,很明显,在某些单词之间声级并没有真正下降。这就排除了简单的声级分割模型。
总而言之,获得一般语音信号的良好结果可能相当困难。但幸运的是,这已经得到了很好的研究,并且有现成的解决方案可用。这些通常使用声学模型(单词和音素的发音)以及语言模型(可能的单词顺序),这是在多个小时的音频中学习的。
所有这些功能都包含在语音识别框架中,并且许多功能允许通过计时获得字级输出。下面是一些使用Vosk的工作代码。
Vosk 的替代品是PocketSphinx。或者使用 Google Cloud、Amazon Web Services、Azure Cloud 等的在线语音识别服务。
import sys
import os
import subprocess
import json
import math
# tested with VOSK 0.3.15
import vosk
import librosa
import numpy
import pandas
def extract_words(res):
jres = json.loads(res)
if not 'result' in jres:
return []
words = jres['result']
return words
def transcribe_words(recognizer, bytes):
results = []
chunk_size = 4000
for chunk_no in range(math.ceil(len(bytes)/chunk_size)):
start = chunk_no*chunk_size
end = min(len(bytes), (chunk_no+1)*chunk_size)
data = bytes[start:end]
if recognizer.AcceptWaveform(data):
words = extract_words(recognizer.Result())
results += words
results += extract_words(recognizer.FinalResult())
return results
def main():
vosk.SetLogLevel(-1)
audio_path = sys.argv[1]
out_path = sys.argv[2]
model_path = 'vosk-model-small-de-0.15'
sample_rate = 16000
audio, sr = librosa.load(audio_path, sr=16000)
# convert to 16bit signed PCM, as expected by VOSK
int16 = numpy.int16(audio * 32768).tobytes()
# XXX: Model must be downloaded from https://alphacephei.com/vosk/models
# https://alphacephei.com/vosk/models/vosk-model-small-de-0.15.zip
if not os.path.exists(model_path):
raise ValueError(f"Could not find VOSK model at {model_path}")
model = vosk.Model(model_path)
recognizer = vosk.KaldiRecognizer(model, sample_rate)
res = transcribe_words(recognizer, int16)
df = pandas.DataFrame.from_records(res)
df = df.sort_values('start')
df.to_csv(out_path, index=False)
print('Word segments saved to', out_path)
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
使用 .WAV 文件和输出文件的路径运行程序。
python vosk_words.py attached_problem/main.wav out.csv
Run Code Online (Sandbox Code Playgroud)
该脚本在 CSV 中输出单词及其时间。然后可以使用这些计时来分割音频文件。这是示例输出:
conf,end,start,word
0.618949,1.11,0.84,also
1.0,1.32,1.116314,eine
1.0,1.59,1.32,woche
0.411941,1.77,1.59,des
Run Code Online (Sandbox Code Playgroud)
将输出(底部)与您提供的示例文件(顶部)进行比较,它看起来相当不错。
它实际上在 42.25 秒处提取了一个注释中未包含的单词“und”。
归档时间: |
|
查看次数: |
5072 次 |
最近记录: |