网站访问速度检测,怎么做公众号推文,四川建设网四川住建厅,辽宁朝阳网站建设播客是以语音为主#xff0c;各种基于AI 的语音技术在播客领域十分重要。
语音转文本
Whisper Whisper 是OpenAI 推出的开源语音辨识工具#xff0c;可以把音档转成文字#xff0c;支援超过50 种语言。这款工具是基于68 万小时的训练资料#xff0c;其中包含11.7 万小时的… 播客是以语音为主各种基于AI 的语音技术在播客领域十分重要。
语音转文本
Whisper Whisper 是OpenAI 推出的开源语音辨识工具可以把音档转成文字支援超过50 种语言。这款工具是基于68 万小时的训练资料其中包含11.7 万小时的多语言语音数据涵盖了96 种不同语言。由于资料量庞大Whisper 在英文的识别精准度相当高而中文的错误率Word Error Rate, WER大约是14.7%表现也不俗。
Whisper 这个名字来自 WSPSRWeb-scale Supervised Pretraining for Speech Recognition
文本转语音TTS TTS(Text-to-Speech)是文本转语音的技术。现代都采用深度学习模型通常基于 Transformer 或类似架构。OpenAI 微软Google和国内大厂云平台都提供了TTS 服务。这项技术已经相当成熟。
最近提到的MaskGCT 是比较好的TTS特别是声音克隆做的非常好。
可以在这里试试
魔搭社区
语音分析 pyannote-audio 实现播客中发言人分离它将区分说话者 A 和说话者 B 等等。如果您想要更具体的内容即说话者的实际姓名那么您可以实现类似这样的功能。
Whisper 转录的准确性非常好但不幸的是它们没有说话人识别功能。
说话人识别功能是使用一个名为 pyannote 的 Python 库实现
pyannote 是说话者分离的开源项目。
pydub Pydub 是一个功能强大的 Python 库可简化处理音频文件的过程。它提供了一个用于处理音频的高级界面使执行加载、切片、连接和将效果应用于音频文件等任务变得容易。他处理的原始音频wav 文件
API 介绍pydub/API.markdown at master · jiaaro/pydub · GitHub
打开一个wav 文件
from pydub import AudioSegmentsong AudioSegment.from_wav(never_gonna_give_you_up.wav)
或者
song AudioSegment.from_mp3(never_gonna_give_you_up.mp3)
音频切片
# pydub does things in milliseconds
ten_seconds 10 * 1000first_10_seconds song[:ten_seconds]last_5_seconds song[-5000:]
指定音频的切片
# 从3秒开始切割持续1秒
clip song[3000:4000] # 从3秒到4秒的音频片段
导出文件
from pydub import AudioSegment
sound AudioSegment.from_file(/path/to/sound.wav, formatwav)# simple export
file_handle sound.export(/path/to/output.mp3, formatmp3)# more complex export
file_handle sound.export(/path/to/output.mp3,formatmp3,bitrate192k,tags{album: The Bends, artist: Radiohead},cover/path/to/albumcovers/radioheadthebends.jpg)# split sound in 5-second slices and export
for i, chunk in enumerate(sound[::5000]):with open(sound-%s.mp3 % i, wb) as f:chunk.export(f, formatmp3)
静音切片silence.split_on_silence()
根据音频文件中的静音分段。
from pydub import AudioSegment
from pydub.silence import split_on_silencesound AudioSegment.from_mp3(audio_files/xxxxxx.mp3)
clip sound[21*1000:45*1000]#graph the volume in 1 second increments
for x in range(0,int(len(clip)/1000)):print(x,clip[x*1000:(x1)*1000].max_dBFS)chunks split_on_silence(clip,min_silence_len1000,silence_thresh-16,keep_silence100
)print(number of chunks,len(chunks))
print (chunks)
实例
from pydub import AudioSegment
from pydub.playback import play
# 示例代码音频切割
def cut_audio(source_file_path, output_file_path, start_second, end_second):# 加载音频文件song AudioSegment.from_file(source_file_path)# 选择要切割的音频段segment song[start_second:end_second]# 导出切割后的音频文件segment.export(output_file_path, formatmp3)
# 示例代码音频合并
def merge_audio(filepaths, output_file_path):combined AudioSegment.empty()for filepath in filepaths:# 加载单个音频文件并添加到合并列表audio AudioSegment.from_file(filepath)combined audio# 导出合并后的音频文件combined.export(output_file_path, formatmp3)
cut_audio(example.mp3, cut_example.mp3, 10, 20) # 从第10秒到第20秒切割音频
merge_audio([part1.mp3, part2.mp3, part3.mp3], merged_example.mp3) # 合并三个音频文件
应用程序
方法1 先转换再将文字分段
from pyannote.core import Segment
import os
import whisper
from pyannote.audio import Pipeline
def get_text_with_timestamp(transcribe_res):timestamp_texts []print(transcribe_res[text])for item in transcribe_res[segments]:print(item)start item[start]end item[end]text item[text].strip()timestamp_texts.append((Segment(start, end), text))return timestamp_textsdef add_speaker_info_to_text(timestamp_texts, ann):spk_text []for seg, text in timestamp_texts:spk ann.crop(seg).argmax()spk_text.append((seg, spk, text))return spk_textdef merge_cache(text_cache):sentence .join([item[-1] for item in text_cache])spk text_cache[0][1]start round(text_cache[0][0].start, 1)end round(text_cache[-1][0].end, 1)return Segment(start, end), spk, sentencePUNC_SENT_END [,, ., ?, !, , 。, , ]def merge_sentence(spk_text):merged_spk_text []pre_spk Nonetext_cache []for seg, spk, text in spk_text:if spk ! pre_spk and pre_spk is not None and len(text_cache) 0:merged_spk_text.append(merge_cache(text_cache))text_cache [(seg, spk, text)]pre_spk spkelif text and len(text) 0 and text[-1] in PUNC_SENT_END:text_cache.append((seg, spk, text))merged_spk_text.append(merge_cache(text_cache))text_cache []pre_spk spkelse:text_cache.append((seg, spk, text))pre_spk spkif len(text_cache) 0:merged_spk_text.append(merge_cache(text_cache))return merged_spk_textdef diarize_text(transcribe_res, diarization_result):timestamp_texts get_text_with_timestamp(transcribe_res)spk_text add_speaker_info_to_text(timestamp_texts, diarization_result)res_processed merge_sentence(spk_text)return res_processeddef write_to_txt(spk_sent, file):with open(file, w) as fp:for seg, spk, sentence in spk_sent:line f{seg.start:.2f} {seg.end:.2f} {spk} {sentence}\nfp.write(line)model_size large-v3
os.environ[OPENAI_API_KEY] sk-ZqGx7uD7sHMyITyIrxFDjbvVEAi84izUGGRwN23N9NbnqTbL
os.environ[OPENAI_BASE_URL] https://api.chatanywhere.tech/v1
asr_modelwhisper.load_model(large-v3)print(model loaded)
audio asr_speaker_demo.wav
spk_rec_pipeline Pipeline.from_pretrained(pyannote/speaker-diarization-3.1, use_auth_tokenhf_pHLhjusrehOvHrqUhLbSgGYsuqTzNHClAO)
asr_result asr_model.transcribe(audio, languagezh, fp16False)
print(transcribe finished....)
diarization_result spk_rec_pipeline(audio)
print(diarization finished...)
final_result diarize_text(asr_result, diarization_result)
for segment, spk, sent in final_result:print([%.2fs - %.2fs] %s \n %s 。\n % (segment.start, segment.end, spk,sent))方法2 先分段再转换 分段转换export 段的语音文件然后分段转换。
import os
import whisper
from pyannote.audio import Pipeline
from pydub import AudioSegment
os.environ[OPENAI_API_KEY] sk-ZqGx7uD7sHMyITyIrxFDjbvVEAi84izUGGRwN23N9NbnqTbL
os.environ[OPENAI_BASE_URL] https://api.chatanywhere.tech/v1
model whisper.load_model(large-v3)
pipeline Pipeline.from_pretrained(pyannote/speaker-diarization-3.1,use_auth_tokenhf_pHLhjusrehOvHrqUhLbSgGYsuqTzNHClAO)# run the pipeline on an audio file
diarization pipeline(buss.wav)
audio AudioSegment.from_wav(buss.wav)
i0
for turn, _, speaker in diarization.itertracks(yield_labelTrue):print(fstart{turn.start:.1f}s stop{turn.end:.1f}s speaker_{speaker})clip audio[turn.start*1000:turn.end*1000]with open(audio-%s.wav % i, wb) as f:clip.export(f, formatwav)text model.transcribe(audio-%s.wav% i,languagezh, fp16False)[text]print(text) ii1 方法3 直接导入语音片段再转换
将Segments 转换成语音数据数组然后分段转换。
import os
import whisper
import numpy as np
from pyannote.audio import Pipeline
from pydub import AudioSegment
os.environ[OPENAI_API_KEY] sk-ZqGx7uD7sHMyITyIrxFDjbvVEAi84izUGGRwN23N9NbnqTbL
os.environ[OPENAI_BASE_URL] https://api.chatanywhere.tech/v1
model whisper.load_model(large-v3)
pipeline Pipeline.from_pretrained(pyannote/speaker-diarization-3.1,use_auth_tokenhf_pHLhjusrehOvHrqUhLbSgGYsuqTzNHClAO)# run the pipeline on an audio file
diarization pipeline(buss.wav)
audio AudioSegment.from_wav(buss.wav)
i0
for turn, _, speaker in diarization.itertracks(yield_labelTrue):print(fstart{turn.start:.1f}s stop{turn.end:.1f}s speaker_{speaker})audio_segment audio[turn.start*1000:turn.end*1000]if audio_segment.frame_rate ! 16000: # 16 kHzaudio_segment audio_segment.set_frame_rate(16000)if audio_segment.sample_width ! 2: # int16audio_segment audio_segment.set_sample_width(2)if audio_segment.channels ! 1: # monoaudio_segment audio_segment.set_channels(1) arr np.array(audio_segment.get_array_of_samples())arr arr.astype(np.float32)/32768.0text model.transcribe(arr,languagezh, fp16False)[text]print(text) Spotify 的 AI 语音翻译 Spotify 正在尝试将外语播客转换成为母语的播客意味着您最喜欢的播客可能会以您的母语被听到。 跨越文化、国家和社区我们分享的故事将我们联系在一起。而且更多时候讲述者的声音和故事本身一样具有分量。15 年来Spotify 的全球平台让各行各业的创作者能够与世界各地的观众分享他们的作品。从本质上讲这是通过技术实现的技术利用音频的力量克服了访问、边界和距离的障碍。但随着最近的进步我们一直在想是否还有更多方法可以弥合语言障碍让全世界都能听到这些声音 但你需要花时间和精力去做。你可以把播客的文字记录下来然后把它一次几段输入到谷歌翻译或ChatGPT中并让它翻译。翻译完材料后将其复制并粘贴到新脚本中。然后重新录制。这里的成功取决于以下几点
发音你用外语说话时感觉如何我们很多人在高中学习西班牙语但你的日语水平如何翻译准确性谷歌的支持文档声称谷歌翻译的准确率可能高达 94%。但这并未考虑到口语例如它如何翻译“cat got your tongue”或“in the zeitgeist?”这样的表达。耐心您愿意重新录制和重新编辑。
这是无法回避的这是一项艰巨的任务即使只是将几集翻译成另一种语言。那么如果你能负担得起帮助你有什么选择
结束语 国内平台提供的各项语音转换服务就速度和质量而言都非常出色但是API 过于复杂。云平台控制台太凌乱。也没有多少demo程序。作为底层研究还是要研究Whisper pyannote-audio和pydub。