语音技术在播客领域的应用(2)

         播客是以语音为主,各种基于AI 的语音技术在播客领域十分重要。

语音转文本

Whisper

        Whisper 是OpenAI 推出的开源语音辨识工具,可以把音档转成文字,支援超过50 种语言。这款工具是基于68 万小时的训练资料,其中包含11.7 万小时的多语言语音数据,涵盖了96 种不同语言。由于资料量庞大,Whisper 在英文的识别精准度相当高,而中文的错误率(Word Error Rate, WER)大约是14.7%,表现也不俗。

Whisper 这个名字来自 WSPSR:Web-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", format="wav")# simple export
file_handle = sound.export("/path/to/output.mp3", format="mp3")# more complex export
file_handle = sound.export("/path/to/output.mp3",format="mp3",bitrate="192k",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, format="mp3")
静音切片(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:(x+1)*1000].max_dBFS)chunks = split_on_silence(clip,min_silence_len=1000,silence_thresh=-16,keep_silence=100
)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, format="mp3")
# 示例代码:音频合并
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, format="mp3")
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}\n'fp.write(line)model_size = "large-v3"
os.environ['OPENAI_API_KEY'] ="sk-ZqGx7uD7sHMyITyIrxFDjbvVEAi84izUGGRwN23N9NbnqTbL"
os.environ['OPENAI_BASE_URL'] ="https://api.chatanywhere.tech/v1"
asr_model=whisper.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_token="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")
asr_result = asr_model.transcribe(audio, language="zh", fp16=False)
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_token="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")# run the pipeline on an audio file
diarization = pipeline("buss.wav")
audio = AudioSegment.from_wav("buss.wav")
i=0
for turn, _, speaker in diarization.itertracks(yield_label=True):print(f"start={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, format="wav")text = model.transcribe("audio-%s.wav"% i,language="zh", fp16=False)["text"]print(text)      i=i+1    

方法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_token="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")# run the pipeline on an audio file
diarization = pipeline("buss.wav")
audio = AudioSegment.from_wav("buss.wav")
i=0
for turn, _, speaker in diarization.itertracks(yield_label=True):print(f"start={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,language="zh", fp16=False)["text"]print(text)

Spotify 的 AI 语音翻译

        

    Spotify  正在尝试将外语播客转换成为母语的播客,意味着您最喜欢的播客可能会以您的母语被听到。

        跨越文化、国家和社区,我们分享的故事将我们联系在一起。而且,更多时候,讲述者的声音和故事本身一样具有分量。15 年来,Spotify 的全球平台让各行各业的创作者能够与世界各地的观众分享他们的作品。从本质上讲,这是通过技术实现的,技术利用音频的力量克服了访问、边界和距离的障碍。但随着最近的进步,我们一直在想:是否还有更多方法可以弥合语言障碍,让全世界都能听到这些声音?

     但你需要花时间和精力去做。你可以把播客的文字记录下来,然后把它(一次几段)输入到谷歌翻译或ChatGPT中(并让它翻译)。翻译完材料后,将其复制并粘贴到新脚本中。然后,重新录制。这里的成功取决于以下几点: 

  • 发音:你用外语说话时感觉如何?我们很多人在高中学习西班牙语,但你的日语水平如何?
  • 翻译准确性:谷歌的支持文档声称谷歌翻译的准确率可能高达 94%。但这并未考虑到口语(例如,它如何翻译“cat got your tongue”或“in the zeitgeist?”这样的表达?)。
  • 耐心:您愿意重新录制和重新编辑。

这是无法回避的;这是一项艰巨的任务,即使只是将几集翻译成另一种语言。那么,如果你能负担得起帮助,你有什么选择?

Whisper-web

GitHub - xenova/whisper-web: ML-powered speech recognition directly in your browser

结束语

        国内平台提供的各项语音转换服务就速度和质量而言,都非常出色,但是API 过于复杂。云平台控制台太凌乱。也没有多少demo程序。作为底层研究,还是要研究Whisper, pyannote-audio和pydub。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/67803.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch使用教程(13)-一文搞定模型的可视化和训练过程监控

一、简介 在现代深度学习的研究和开发中,模型的可视化和监控是不可或缺的一部分。PyTorch,作为一个流行的深度学习框架,通过其丰富的生态系统提供了多种工具来满足这一需求。其中,torch.utils.tensorboard 是一个强大的接口&…

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证6)

重新创建WebApi项目,安装Microsoft.AspNetCore.Authentication.JwtBearer包,将之前JwtBearer测试项目中的初始化函数,jwt配置类、token生成类全部挪到项目中。   重新编写login函数,之前测试Cookie和Session认证时用的函数适合m…

【Linux系统】—— 编译器 gcc/g++ 的使用

【Linux系统】—— 编译器 gcc/g 的使用 1 用 gcc 直接编译2 翻译环境2.1 预处理(进行宏替换)2.2 编译(生成汇编)2.3 汇编(生成机器可识别代码)2.4 链接2.5 记忆小技巧2.6 编译方式2.7 几个问题2.7.1 如何理…

[已解决]chatgpt被降智了怎么办?(无法联网、识别图片、文件、画图)

文章目录 1、治标办法一发图2、治本方法—使用ChatGPT中国区代理官方站点 1、治标办法一发图 该方法原本就有,但是在1.1日ChatGPT降智事件中突然失效。于1月11日,该方法又突然有效,因此也标志着本次ChatGPT降智事件的结束。当你ChatGPT出现降…

缓存、数据库双写一致性解决方案

双写一致性问题的核心是确保数据库和缓存之间的数据同步,以避免缓存与数据库数据不同步的问题,尤其是在高并发和异步环境下。本文将探讨双写一致性面临的主要问题和解决方案,重点关注最终一致性。 本文讨论的是最终一致性问题 双写一致性面…

element el-table合并单元格

合并 表格el-table添加方法:span-method"” <el-table v-loading"listLoading" :data"SHlist" ref"tableList" element-loading-text"Loading" border fit highlight-current-row :header-cell-style"headClass" …

qml OpacityMask详解

1、概述 OpacityMask是QML&#xff08;Qt Meta-Object Language&#xff09;中的一种图形效果&#xff0c;它使用另一个项目&#xff08;通常是一个图像或图形项&#xff09;作为遮罩来控制源项目的透明度。这种效果允许开发者通过遮罩的alpha通道来精确地控制源项目中哪些部分…

RabbitMQ1-消息队列

目录 MQ的相关概念 什么是MQ 为什么要用MQ MQ的分类 MQ的选择 RabbitMQ RabbitMQ的概念 四大核心概念 RabbitMQ的核心部分 各个名词介绍 MQ的相关概念 什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&am…

渗透测试之SSRF漏洞原理 危害 产生的原因 探测手法 防御手法 绕过手法 限制的手段

目录 SSRF说明: SSRF攻击流程 原理&#xff1a; 危害: SSRF产生的原因 ssrf漏洞利用{危害} 探测手法是否存在SSRF漏洞 如何找ssrf漏洞位置 分享连接地址 google hack url关键字 PHP语言中可能出现的ssrf漏洞函数 file_get_contents sockopen() curl_exec() SSRF…

centos9编译安装opensips 二【进阶篇-定制目录+模块】推荐

环境&#xff1a;centos9 last opensips -V version: opensips 3.6.0-dev (x86_64/linux) flags: STATS: On, DISABLE_NAGLE, USE_MCAST, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, HP_MALLOC, DBG_MALLOC, CC_O0, FAST_LOCK-ADAPTIVE_WAIT ADAPTIVE_WAIT_LOOPS1024, MAX_RE…

【前端】CSS学习笔记(1)

目录 CSS的简介CSS的概念语法 CSS的引入方式内联样式&#xff08;行内样式&#xff09;内部样式外部样式&#xff08;推荐&#xff09; 选择器全局选择器元素选择器类选择器ID选择器合并选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器伪类选择器:link:visited:hover:ac…

Java面试专题——面向对象

面向过程和面向对象的区别 面向过程&#xff1a;当事件比较简单的时候&#xff0c;利用面向过程&#xff0c;注重的是事件的具体的步骤/过程&#xff0c;注重的是过程中的具体的行为&#xff0c;以函数为最小单位&#xff0c;考虑怎么做。 面向对象&#xff1a;注重找“参与者…

电阻电位器可调电阻信号隔离变送器典型应用

电阻电位器可调电阻信号隔离变送器典型应用 产品描述&#xff1a; 深圳鑫永硕科技的XYS-5587系列是一进一出线性电子尺(电阻/电位计信号及位移)信号隔离变送器&#xff0c;是将输入电阻,线性电子尺,角度位移传感器信号进行采集,隔离,放大并转换成模拟量信号的小型仪表设备,并以…

Alluxio 联手 Solidigm 推出针对 AI 工作负载的高级缓存解决方案

作者&#xff1a;Wayne Gao, Yi Wang, Jie Chen, Sarika Mehta Alluxio 作为全球领先的 AI 缓存解决方案供应商&#xff0c; 提供针对 GPU 驱动 AI 负载的高速缓存。其可扩展架构支持数万个节点&#xff0c;能显著降低存储带宽的消耗。Alluxio 在解决 AI 存储挑战方面的前沿技…

文件系统格式RAW数据恢复全攻略

一、RAW文件系统格式深度解析 在数据存储的世界里&#xff0c;文件系统扮演着至关重要的角色&#xff0c;它负责管理和组织硬盘、U盘、SD卡等存储设备上的数据。而RAW文件系统格式&#xff0c;作为一种特殊状态&#xff0c;常常让许多用户感到困惑与不安。RAW格式并非一种标准…

探索 Stable-Diffusion-Webui-Forge:更快的AI图像生成体验

目录 简介&#x1f31f; 主要特点&#x1f4e5; 安装步骤1. 下载2. 配置环境和安装依赖3. 模型目录说明 &#x1f680; 运行 Stable-Diffusion-Webui-Forge1. 进入项目目录2. 运行项目3. 打开页面 &#x1f3a8; 使用体验常见问题&#x1f4dd; 小结 简介 Stable-Diffusion-We…

汇编与逆向(一)-汇编工具简介

RadASM是一款著名的WIN32汇编编辑器&#xff0c;支持MASM、TASM等多种汇编编译器&#xff0c;Windows界面&#xff0c;支持语法高亮&#xff0c;自带一个资源编辑器和一个调试器。 一、汇编IDE工具&#xff1a;RadASM RadASM有内置的语言包 下载地址&#xff1a;RadASM asse…

Yearning开源MySQL SQL审核平台

一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用. 本地部署&#xff0c;注重隐私&#xff0c;简单高效的MYSQL审计平台。 它可以通过流程审批&#xff0c;实现真实线上环境sql的审核和执行&#xff0c;还可以回滚执行&#xff0c;能够确保线上SQL更新的可靠性…

PyTorch使用教程(10)-torchinfo.summary网络结构可视化详细说明

1、基本介绍 torchinfo是一个为PyTorch用户量身定做的开源工具&#xff0c;其核心功能之一是summary函数。这个函数旨在简化模型的开发与调试流程&#xff0c;让模型架构一目了然。通过torchinfo的summary函数&#xff0c;用户可以快速获取模型的详细结构和统计信息&#xff0…

【2024 博客之星评选】请继续保持Passion

我尝试复盘自己2024年走的路&#xff0c;希望能给诸君一些借鉴。 文章目录 回头望感想与收获成长与教训今年计划感恩一些体己话 回头望 回望我的2024年&#xff0c;年初拿高绩效&#xff0c;但感觉逐渐被公司一点点剥离出中心&#xff1b;年中一直在学习防患于未然&#xff1b…