webscoket+webrtc实现语音通话

devtools/2024/11/14 12:54:30/

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> */


http://www.ppmy.cn/devtools/28872.html

相关文章

【stomp 实战】spring websocket用户消息发送源码分析

这一节&#xff0c;我们学习用户消息是如何发送的。 消息的分类 spring websocket将消息分为两种&#xff0c;一种是给指定的用户发送&#xff08;用户消息&#xff09;&#xff0c;一种是广播消息&#xff0c;即给所有用户发送消息。那怎么区分这两种消息呢?那就是用前缀了…

Rust Rocket创建第一个hello world的Web程序 Rust Rocket开发常用网址和Rust常用命令

一、Rust Rocket简介 Rust Rocket 是一个用 Rust 语言编写的 Web 应用框架&#xff0c;它结合了 Rust 的安全性和性能优势&#xff0c;以及 Web 开发的便利性。以下是 Rust Rocket 框架的一些优点&#xff1a; 安全性&#xff1a;Rust 是一种注重安全性的编程语言&#xff0c;…

OpenHarmony实战开发-使用通用事件、触屏事件

触屏事件指当手指/手写笔在组件上按下、滑动、抬起时触发的回调事件。包括点击事件、拖拽事件和触摸事件。 图1 触摸事件原理 点击事件 点击事件是指通过手指或手写笔做出一次完整的按下和抬起动作。当发生点击事件时&#xff0c;会触发以下回调函数&#xff1a; onClick(ev…

竞赛 基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉

文章目录 0 简介1 二维码检测2 算法实现流程3 特征提取4 特征分类5 后处理6 代码实现5 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉 该项目较为新颖&#xff0c;适合作为竞赛课…

无人机+集群组网+单兵图传:空地一体化组网技术详解

空地一体化组网技术是一种结合了无人机、集群自组网和单兵图传等多种技术的先进通信解决方案。这种技术方案的主要目的是在前线事故现场和后方指挥中心之间建立一个高效、稳定的通信链路&#xff0c;以确保信息的实时传输和指挥的顺畅进行。 首先&#xff0c;前端视频采集部分&…

[PS小技能学习]抠图和切图

详情见视频教程&#xff1a;PS小技巧--抠图与切图 今天我们来学习如何使用PS对表情包合辑进行抠图和裁剪保存 1、首先&#xff0c;将图片导入&#xff0c;双击图层新建一个图层 2、然后点击工具栏的魔棒工具&#xff0c;再点击顶部菜单栏的添加到选区 3、点击图片的空白区域即…

pkpmbs 建设工程质量监督系统 Ajax_operaFile.aspx 文件读取漏洞复现

0x01 产品简介 pkpmbs 建设工程质量监督系统是湖南建研信息技术股份有限公司一个与工程质量检测管理系统相结合的,B/S架构的检测信息监管系统。 0x02 漏洞概述 pkpmbs 建设工程质量监督系统 Ajax_operaFile.aspx接口处存在文件读取漏洞,未经身份认证的攻击者可以利用漏洞读…

https网站安全证书的作用与免费申请办法

HTTPS网站安全证书&#xff0c;也称为SSL证书&#xff0c;网站通过申请SSL证书将http协议升级到https协议 HTTPS网站安全证书的作用 1 增强用户信任&#xff1a;未使用https协议的网站&#xff0c;用户访问时浏览器会有“不安全”弹窗提示 2 提升SEO排名&#xff1a;搜索引擎…