当前位置: 首页 > 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);

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

http://www.lryc.cn/news/518161.html

相关文章:

  • 鸿蒙UI(ArkUI-方舟UI框架)
  • 常见的http状态码 + ResponseEntity
  • pikachu - Cross-Site Scripting(XSS)
  • 操作系统之文件系统的基本概念
  • 深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践
  • 西电-算法分析-研究生课程复习笔记
  • 编译时找不到需要的库,如何在PyCharm中为你的项目添加需要的库
  • ip addr 命令给Linux网络接口配置多个IP地址值
  • C#语言的数据库编程
  • 时频分析之S变换
  • 第二十八周学习周报
  • SurfaceFlinger MessageQueue原理
  • component-动态控制 div width 的值 根据传入的变量决定width的值 vue
  • C#中的常用集合
  • 插入实体自增主键太长,mybatis-plaus自增主键
  • 晨辉面试抽签和评分管理系统之一:考生信息管理和编排
  • 【MySQL】MVCC详解, 图文并茂简单易懂
  • 中国数字化发展的问题与机会
  • 【ROS2】☆ launch之Python
  • 如何稳定使用 O1 / O1 Pro,让“降智”现象不再困扰?
  • zookeeper监听机制(Watcher机制)
  • docker 启动 nacos 单机模式
  • 学习threejs,导入babylon格式的模型
  • 03.MPLS静态LSP配置实验
  • 程序血缘分析技术在工商银行软件工程中的应用
  • 计算机毕业设计Django+Tensorflow音乐推荐系统 音乐可视化 卷积神经网络CNN LSTM音乐情感分析 机器学习 深度学习 Flask 大
  • macOS 使用 FreeRDP 远程访问 Windows:完整指南20250109
  • Java agent
  • Web无障碍
  • 概率基本概念 --- 离散型随机变量实例