webscoket+webrtc实现语音通话
1.项目方案
前端采用webrtc创建音频上下文,后创建音频源输入和音频处理器,连接音频输入与处理器,处理器再连接到音频输出(扬声器),再通过事件获取音频数据,把音频数据转换成字节数据通过webscoket发送给后端。
注意
1.前端使用的创建音频源api createScriptProcessor onaudioprocess 已经开始废弃使用,但是浏览器依然适配。
2.因为前端使用websocket实时传输录音数据,后端开发需要多线程接受处理数据,给每个数据包提供index坐标,然后处理后保存,再通过单线程发送,可以降低延迟
2.前端代码
// AudioManager.js
export default class AudioManager {/*** 构造函数* @param {string} url - WebSocket服务器的地址* @param {function} onMessageCallback - 当WebSocket接收到消息时的回调函数*/constructor(url, onMessageCallback) {this.url = url; // WebSocket服务器的完整URLthis.websocket = null; // WebSocket连接实例this.audioContext = null; // 音频上下文this.audioStream = null; // 流媒体对象this.audioProcessor = null; // 音频处理器this.onMessageCallback = onMessageCallback; // WebSocket消息的回调函数}/*** 初始化WebSocket连接并设置消息监听器*/initWs() {console.log(this.url,';this.url');// 创建WebSocket实例this.websocket = new WebSocket(this.url);// 设置WebSocket接收消息时的回调函数this.websocket.onmessage = (e) => {if (this.onMessageCallback) {// 调用通过构造函数传入的回调函数处理接收到的消息this.onMessageCallback(e.data);}};// 请求用户的麦克风权限并开始处理音频流this.queryHttp();}/*** 停止录音并关闭所有资源*/stopRecording() {// 关闭所有音频轨道if (this.audioStream) {this.audioStream.getTracks().forEach((track) => track.stop());}// 断开音频处理器的连接if (this.audioProcessor) {this.audioProcessor.disconnect();}// 关闭音频上下文if (this.audioContext) {this.audioContext.close();}// 关闭WebSocket连接if (this.websocket) {this.websocket.close();}}/*** 请求麦克风资源,并在成功后处理音频流*/queryHttp() {navigator.mediaDevices.getUserMedia({audio: {echoCancellation: true, // 开启回声消除noiseSuppression: true, // 开启噪声抑制autoGainControl: true, // 开启自动增益控制},}).then((stream) => {// 处理成功获取的音频流this.handleStream(stream);}).catch((error) => {// 处理获取音频流失败的情况console.error("Error accessing microphone:", error);});}/*** 处理音频流,连接音频输入和处理器,并设置音频处理事件* @param {MediaStream} stream - 从麦克风获取的音频流*/handleStream(stream) {this.audioContext = new AudioContext({sampleRate: 16000, // 设置采样率latencyHint: "interactive", // 延迟模式为交互式channels: 1, // 单声道frameRate: 60, // 帧率sampleType: "int16", // 采样类型numberOfOutputs: 1, // 输出数量});// 创建音频源输入let audioInput = this.audioContext.createMediaStreamSource(stream);// 创建音频处理器this.audioProcessor = this.audioContext.createScriptProcessor(4096, 1, 1);// 设置音频处理事件this.audioProcessor.onaudioprocess = (event) => {// 获取音频数据const inputData = event.inputBuffer.getChannelData(0);// 转换音频数据为字节数据const byteData = this.convertToByteData(inputData);// 通过WebSocket发送字节数据this.websocket.send(byteData);};// 连接音频输入与处理器,处理器再连接到音频输出(扬声器)audioInput.connect(this.audioProcessor);this.audioProcessor.connect(this.audioContext.destination);// 保存音频流引用this.audioStream = stream;}/*** 将浮点数组的音频数据转换为字节数据* @param {Float32Array} inputData - 浮点数组格式的原始音频数据* @return {Uint8Array} 字节数据*/convertToByteData(inputData) {// 创建Int16Array,由于原始的音频数据是Float32Array类型,需要转换const intData = new Int16Array(inputData.map((item) => item * 32767));// 创建Uint8Array来保存字节数据const byteData = new Uint8Array(intData.length * 2);// 将Int16Array的数据转换为字节数据并填充到Uint8ArrayintData.forEach((value, index) => {byteData[index * 2] = value & 0xff; // 存储低位字节byteData[index * 2 + 1] = (value >> 8) & 0xff; // 存储高位字节});return byteData;}
}/*使用方法
<template><audio style="display: none" ref="audio" controls="controls" autoplay><source :src="audioUrl" type="audio/wav" /></audio>
</template><script>
import AudioManager from './AudioManager.js';export default {data() {return {audioManager: null,};},methods: {handleWsMessage(data) {let message = JSON.parse(data);this.$refs.audio.src = message.url; },startRecording() {this.audioManager = new AudioManager('your-server-url',this.handleWsMessage // 回调函数用于接受通话后获取的信息这里我用于播放接受的音频);this.audioManager.initWs();},},
};
</script> */
相关文章:
webscoket+webrtc实现语音通话
1.项目方案 前端采用webrtc创建音频上下文,后创建音频源输入和音频处理器,连接音频输入与处理器,处理器再连接到音频输出(扬声器),再通过事件获取音频数据,把音频数据转换成字节数据通过webscok…...

PHP源码_众筹商城
众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹 前端是编译后的,后端PHP,带商城 运行截图 源码贡献 https://githubs.xyz/boot?app39 部分数据库表 CREATE TABLE ti_shopro_store (id int(11) NOT NULL AUTO_INCREMENT COMMENT ID,nam…...
智能小程序 Ray 开发——表单组件 Button 和 Checkbox 实操讲解
Button 多端按钮基础组件,可用于进行强交互的操作。 导入 import { Button } from ray-js/ray; 属性说明 属性类型默认值必填说明支持平台sizekeyof Sizedefault否按钮的大小涂鸦、微信typekeyof Typedefault否按钮的样式类型涂鸦、微信plainbooleanfalse否按钮…...

渗透之sql注入联合查询的注入
sql注入产生的原因: 由于程序过滤不严谨,导致用户有一些异常输入,最终触发数据库的查询。所以会出现sql注入这个问题。有些恶意的人就会利用这些信息导致数据库泄露。 注意:一般我们存在注入点我们会查询管理员的账号和密码&#…...

NLP transformers - 文本分类
Text classification 文章目录 Text classification加载 IMDb 数据集Preprocess 预处理EvaluateTrainInference 本文翻译自:Text classification https://huggingface.co/docs/transformers/tasks/sequence_classification notebook : https://colab.research.googl…...

QT 开发COM(ActiveX)组件基础介绍和方案验证
一、COM简介 1.1 COM是什么? COM,Component Object Model,即组件对象模型,是一种以组件为发布单元的对象模型,这种模型使各软件组件可以用一种统一的方式进行交互。COM 既提供了组件之间进行交互的规范,也…...

[1673]jsp在线考试管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 在线考试管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…...
每日一算法
问题 等待登机的你看着眼前有老有小长长的队伍十分无聊,你突然 想要知道,是否存在两个年龄相仿的乘客。每个乘客的年龄用 1个0 到 36500 的整数表示,两个乘客的年龄相差 365 以内 就认为是相仿的。 具体来说,你有一个长度为 n 的…...
Spring Cloud Gateway直接管理Vue.js的静态资源
1. 构建Vue.js应用 像之前一样,构建你的Vue.js应用,并将生成的静态资源(位于dist目录)复制到Spring Boot项目的某个目录,比如src/main/resources/static。 2. 配置Spring Boot静态资源处理 Spring Boot默认会处理sr…...

14.集合、常见的数据结构
集合 概念 Java中的集合就是一个容器,用来存放Java对象。 集合在存放对象的时候,不同的容器,存放的方法实现是不一样的, Java中将这些不同实现的容器,往上抽取就形成了Java的集合体系。 Java集合中的根接口&#x…...
NLP从入门到实战——命名实体识别
1. 命名实体识别 1.1 概念 中文命名实体识别(Named Entity Recognition,NER是指识别中文文本中实体的边界和类别。命名实体识别是文本处理中的基础技术,广泛应用在自然语言处理、推荐系统、知识图谱等领域,比如推荐系统中的基于…...
接口测试工具-postman介绍
一、介绍 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。 作用:常用于进行接口测试。 它可以模拟浏览器发起任何形式的HTTP请求...
日志中看到来自User Agent go-http-client / 1.1的大量请求(go-http-client 1.1)服务器爆了
在日志中看到来自User Agent go-http-client / 1.1的大量请求 The go-http-client/1.1 User Agent 是Google的Bot / Crawler 这不是真的。这可能是指Go库(根据您提到的来源,由Google开发,但是我找不到可靠的信息)。 之前写过“G…...

yolov8 区域声光报警+计数
yolov8 区域报警计数 1. 基础2. 报警功能2. 1声音报警代码2. 2画面显示报警代码 3. 完整代码4. 源码 1. 基础 本项目是在 yolov8 区域多类别计数 的基础上实现的,具体区域计数原理可见上边文章 2. 报警功能 设置一个区域region_points,当行人这一类别…...

《QT实用小工具·五十五》带有标签、下划线的Material Design风格输入框
1、概述 源码放在文章末尾 该项目实现了一个带有标签动画、焦点动画、正确提示、错误警告的单行输入框控件。下面是demo演示: 项目部分代码如下所示: #ifndef LABELEDEDIT_H #define LABELEDEDIT_H#include <QObject> #include <QWidget>…...

用Go实现一个无界资源池
写在文章开头 我们希望通过go语言实现一个简单的资源池,而这个资源池的资源包括但不限于: 数据库连接池线程池协程池网络连接池 只要这些资源实现我们指定的关闭方法,则都可以通过我们封装的资源池进行统一管理,需要简单说明一下这个资源池…...

Apache Seata基于改良版雪花算法的分布式UUID生成器分析2
title: 关于新版雪花算法的答疑 author: selfishlover keywords: [Seata, snowflake, UUID, page split] date: 2021/06/21 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 关于新版雪花算法的答疑 在上一篇关于新版雪花算法的解析中…...

13、揭秘JVM垃圾回收器:面试必备知识,你掌握了吗?
13.1、前文回顾 在上一篇文章中,我们详细分析了触发Minor GC的时机,以及对象何时会从新生代迁移到老年代。我们还讨论了为了确保新生代向老年代的内存迁移安全,需要在Minor GC之前如何检查老年代的内存空间,以及在什么情况下会触发老年代的Full GC,以及老年代的垃圾回收算…...

治疗耳鸣患者案例分享第二期
“患者耳鸣20年了,目前耳朵没有堵或者胀的感觉,但是偶尔有点痒,平时会有头晕头胀这种情况,然后头晕是稍微晕炫一下。然后头疼是经常有的,头胀不经常。” 患者耳鸣持续20年,虽然耳朵没有堵或胀的感觉&#x…...
数据加密的方法
这些方法可以单独或结合使用,以提高数据的安全性和保护隐私。 对称加密:使用相同的密钥对数据进行加密和解密。常见的对称加密算法包括DES、AES和RC4。 非对称加密:使用一对密钥(公钥和私钥)对数据进行加密和解密。发…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...