当前位置: 首页 > news >正文

js -音频变音(听不出说话的人是谁)

学习参考来源:
https://zhuanlan.zhihu.com/p/634848804
https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API

实际效果:
http://www.qingkong.zone/laboratory?type=audio-confusion

前言

本文内容可结合上面学习参考来源,结合学习。
之前我遇到的需求主要是对人声进行变音处理,以确保无法通过声音识别出是谁说的这个话,保护隐私。通过Web Audio API即可实现该变声效果。

1. 获取Audio上下文

const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

2. 用 audioCtx 与音频源做关联

各个音频源关联方法:

(1) 与audio,vidio标签 或 Audio实例

const audio = new Audio()
const sourceNode = audioCtx.createMediaElementSource(audio)

(2) 获取麦克风

const stream = await navigator.mediaDevices.getUserMedia({ audio: true}).catch(function (error) {console.log(error);});
const sourceNode = audioCtx.createMediaStreamSource(stream)

(3) 使用 缓冲器

const loadAudioBuffer = async (url) => {const response = await fetch(url);const arrayBuffer = await response.arrayBuffer();return await audioCtx.decodeAudioData(arrayBuffer);
}
// 获取 audioBuffer
loadAudioBuffer(props.url).then((audioBuffer) => {audioCtx.audioBuffer = audioBuffer;
}).catch((error) => {console.error("Failed to load audio buffer:", error);
});// 创建缓冲区
const bufferNode = audioCtx.createBufferSource()

需要注意:缓冲区只能播放一次,所以创建缓冲区逻辑要与播放逻辑放在一起

3. 使用缓冲区后,改写原有音频播放、暂停

声音流添加处理效果就像穿项链一样,一个接一个(引自学习参考来源1)

// 创建多个不同作用功能的node节点
var analyser = audioCtx.createAnalyser();
var distortion = audioCtx.createWaveShaper();
var gainNode = audioCtx.createGain();
var biquadFilter = audioCtx.createBiquadFilter();
var convolver = audioCtx.createConvolver();// 将所有节点连接在一起source = audioCtx.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(distortion);
distortion.connect(biquadFilter);
biquadFilter.connect(convolver);
convolver.connect(gainNode);
gainNode.connect(audioCtx.destination);

上述代码是帮助你理解 AudioContext 的处理节点如何添加,不是实现代码。
audioCtx.destination 是 AudioContext 的输出源

播放

  if (flag) {// 创建缓冲区bufferNode = audioCtx.createBufferSource()bufferNode.buffer = audioCtx.audioBuffer;bufferNode.playbackRate.value = umlautValue;// 用于修改音量gainNode = audioCtx.createGain();bufferNode.connect(gainNode);gainNode.connect(audioCtx.destination);gainNode.gain.value = audioData.volume / 100;bufferNode.startTime = audioCtx.currentTime - audioData.currentTime;bufferNode.start(0, audioData.currentTime);bufferNode.onended = () => {audioData.status = "play";cancelAnimationFrame(animationFrameId);};} else {audio.play()}

暂停

  if (flag) {bufferNode.stop();audioData.currentTime = audioCtx.currentTime - bufferNode.startTime;cancelAnimationFrame(animationFrameId);} else {audio.pause()}

4. 使用 requestAnimationFrame 代替 timeupdate 获取实时信息

const updateCurrentTime = () => {if (bufferNode && bufferNode.playbackState === bufferNode.PLAYING_STATE) {audioData.currentTime = audioCtx.currentTime - bufferNode.startTime;audioData.currentValue = audioData.currentTime / audioData.duration * 100 * umlautValue;audioData.currentFormat = `${moment.utc(audioData.currentTime * 1000 * umlautValue).format("mm:ss")} / ${moment.utc(audioData.duration * 1000).format("mm:ss")}`;}animationFrameId = requestAnimationFrame(updateCurrentTime);
}

在需要关闭的地方

cancelAnimationFrame(animationFrameId);

5. 音频变音核心逻辑

本文走的是 变速变调 的路子,改变声音播放速率情况下,音调音色也会随着改变,例如玩过磁带的都知道,按快进功能会使声音变尖提高音调,慢放功能使声音变粗,降低音调。

为了让音频进度条与 加速或减速 的速率保持一致,需创建个变量做统一管理

const umlautValue = 1.5

6. 结尾

在销毁前记得销毁这些节点

  if (bufferNode) {bufferNode.stop();}if (gainNode) {gainNode.disconnect();}cancelAnimationFrame(animationFrameId);

喜欢的话不妨点个小小的赞与关注,您的赞与关注将是我源源不断的前进动力。

相关文章:

js -音频变音(听不出说话的人是谁)

学习参考来源: https://zhuanlan.zhihu.com/p/634848804 https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API 实际效果: http://www.qingkong.zone/laboratory?typeaudio-confusion 前言 本文内容可结合上面学习参考来源,结合…...

鸿蒙UI(ArkUI-方舟UI框架)

参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-layout-development-overview-V13 ArkUI简介 ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能&#xff…...

常见的http状态码 + ResponseEntity

常见的http状态码 ResponseStatus(HttpStatus.CREATED) 是 Spring Framework 中的注解,用于指定 HTTP 响应状态码。 1. 基本说明 HttpStatus.CREATED 对应 HTTP 状态码 201表示请求成功且创建了新的资源通常用于 POST 请求的处理方法上 2. 使用场景和示例 基本…...

pikachu - Cross-Site Scripting(XSS)

pikachu - Cross-Site Scripting(XSS) 声明! 笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人无关,切勿触碰法律底线,否则后果自负&#x…...

操作系统之文件系统的基本概念

目录 用户和磁盘视角的文件 文件控制块(FCB)和索引结点(inode) 文件的操作 创建文件(create系统调用) 写文件(write系统调用) 读文件(read系统调用) 重…...

深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践

引言 在 Android 开发中,AlarmManager 是一个非常重要的系统服务,用于设置定时任务或者周期性任务。无论是设置一个闹钟,还是定时进行数据同步,AlarmManager 都是不可或缺的工具之一。然而,随着 Android 系统的不断演…...

西电-算法分析-研究生课程复习笔记

24年秋的应该是张老师最后一次用卷面考试,他说以后这节课的期末考试都是在OJ上刷题了张老师上课还挺有意思的,上完之后能学会独立地思考算法设计问题了。整节课都在强调规模压缩这个概念,考试也是考个人对这些的理解,还挺好玩的哈…...

编译时找不到需要的库,如何在PyCharm中为你的项目添加需要的库

丰富的库支持是 Python 语言的一大特点,但是在使用 PyCharm 进行Python 代码编译的时候,遇到一些需要使用到的库提示不能解析时,该如何添加呢? 比如下图所示的代码,可以看到需要使用 selenium、b4、jieba 这些库&…...

ip addr 命令给Linux网络接口配置多个IP地址值

问一下Chatgpt 怎么使用ip addr 命令给Linux网络接口配置多个IP地址值 根据Chatgpt的提示执行了命令,命令执行成功,看下执行结果。 ifconfig 命令查看接口IP地址 ip addr show 命令查看接口IP地址...

C#语言的数据库编程

C#语言的数据库编程 在现代软件开发中,数据库是不可或缺的一部分。无论是企业级应用还是个人项目,数据的存储与管理都是程序的核心功能之一。C#作为一种强类型、面向对象的编程语言,广泛应用于Windows平台的开发,尤其是在构建与数…...

时频分析之S变换

S变换的提出 1996年,由R.G Stockwell 提出了S变换,和其他时频分析工具一样,通过S变换,我们可以同时从时域以及频域观察一个信号的能量分布。S变换融合了短时傅里叶变换和小波变换的优点。关于S变换,最早发表于TSP上的…...

第二十八周学习周报

目录 摘要Abstract1 GFPGAN1.1 总体结构1.2 实验研究1.3 代码分析 总结 摘要 本周主要的学习内容是GFPGAN模型。GFPGAN是一种基于生成对抗网络(GAN)的模型,其利用封装在预训练的人脸GAN中的丰富多样的先验进行人脸图像的修复。这种生成面部先验(GFP&…...

SurfaceFlinger MessageQueue原理

SurfaceFlinger MessageQueue 有2个作用: 处理SurfaceFlinger INVALIDATE、REFRESH事件管理SurfaceFlinger主线程挂起和恢复 SurfaceFlinger::run() { while (true) { mEventQueue->waitMessage(); } } waitMessage {do {IPCThreadState::self()->flushComm…...

component-动态控制 div width 的值 根据传入的变量决定width的值 vue

1.实现 根据参数的值&#xff0c;div显示不同的长度 <div class"node-line" :style"lineProgress"></div> <script>export default {name: "trainSummaryInfo",data(){return{linePercentage:200,}},computed:{lineProgress…...

C#中的常用集合

目录 一、动态数组ArrayList 二、List 三、栈&#xff08;Stack&#xff09; 四、队列&#xff08;Queue&#xff09; 五、字典&#xff08;Dictionary&#xff09;,int> 一、动态数组ArrayList ArrayList 是 C# 中提供的一种动态数组类&#xff0c;位于命名空间 Syste…...

插入实体自增主键太长,mybatis-plaus自增主键

1、问题 spring-boot整合mybtais执行insert语句时&#xff0c;主键id为长文本数据。 2、分析问题 1)数据库主键是否自增 2&#xff09;数据库主键的种子值设置的多少 3、解决问题 1&#xff09;数据库主键设置的时自增 3&#xff09;种子值是1 所以排查是数据库的问题 4、继…...

晨辉面试抽签和评分管理系统之一:考生信息管理和编排

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…...

【MySQL】MVCC详解, 图文并茂简单易懂

欢迎来到啊妮莫的学习小屋 祝读本文的朋友都天天开心呀 目录 MVCC简介快照读与当前读快照读当前读 隔离级别隐藏字段和Undo Log版本链✨MVCC原理--ReadView✨ReadView简介设计思路适用隔离级别重要内容 ReadView规则MVCC整体流程 不同隔离级别下的MVCC读已提交可重复读 总结 M…...

中国数字化发展的问题与机会

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案,帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、埃域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能,如智能化推荐、…...

【ROS2】☆ launch之Python

☆重点 ROS1和ROS2其中一个很大区别之一就是launch的编写方式。在ROS1中采用xml格式编写launch&#xff0c;而ROS2保留了XML 格式launch&#xff0c;还另外引入了Python和YAML 编写方式。选择哪种编写取决于每位开发人员的爱好&#xff0c;但是ROS2官方推荐使用Python方式编写…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...