简单的语音广播功能方案

news2024/11/15 4:58:58

方案介绍:

1)前端可以复用如下播放器的方案 (或自行实现)

其中,rtp封装过程中,额外增加了2字节的长度信息,后端服务接收之后,做好校验之后,需要剔除2个字节的数据头

2)后端的java业务服务启动websocket并管理websocket服务,多台广播问题

3)对于收到的流通过调用ffplay直接播放,进程间通信通过管道进行交互

4)音频的,编码格式,采样率,通道数等音频的关键参数,第一个版本建议直接约定写死即可~!

5)关于独占式以及和别的音频直接的关系,java的业务服务知悉控制优先级逻辑即可,多个客户需要操作广播的问题,以及报警语音和人工广播

6)关于ws地址,建议通过信令服务获取,信令服务请求中可以传递音频传递的参数

7)浏览器安全限制,若是通过http协议传递音频的话,需要https才能访问音频输入设备,需要整个网站是https才有访问麦克风的权限

1.前端代码

在前端页面中,您可以使用JavaScript WebSocket API连接WebSocket服务器并获取实时音频流数据,然后通过WebSocket客户端将数据发送到Java服务端。例如:

var ws = new WebSocket('wss://my-websocket-server.com');
var mediaSource = new MediaSource();
var audio = document.querySelector('audio');

ws.onopen = function() {
console.log('WebSocket connected.');
};

ws.onmessage = function(event) {
var data = event.data;
if (mediaSource.readyState === 'open') {
var sourceBuffer = mediaSource.sourceBuffers[0];
sourceBuffer.appendBuffer(data);
}
};

mediaSource.addEventListener('sourceopen', function() {
var sourceBuffer = mediaSource.addSourceBuffer('audio/webm; codecs="opus"');
sourceBuffer.addEventListener('updateend', function() {
if (!sourceBuffer.updating) {
mediaSource.endOfStream();
}
});
});

audio.src = URL.createObjectURL(mediaSource);

上述代码中,我们首先用WebSocket API连接到指定的WebSocket服务器;然后使用MediaSource创建一个新的媒体源,并指定音频编码格式为Opus;接着,当从WebSocket服务器接收到音频流数据时,我们将数据追加到sourceBuffer中,最后将MediaSource对象的状态设置为结束。

2.Java服务端代码

用于在Java服务端通过WebSocket接收RTP音频数据并直接播放:

​
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;

public class FFplayWebSocketServer extends WebSocketServer {
private Process ffplayProcess;
private FileOutputStream outputStream;

public FFplayWebSocketServer(int port) {
super(port);
}

@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
System.out.println("WebSocket connected.");
try {
String command = "ffplay -vn -sync ext -f rtp -acodec " + codecName + " -i pipe:0"; // 命令行参数
ffplayProcess = Runtime.getRuntime().exec(command);
outputStream = new FileOutputStream("/path/to/file.raw"); // 保存路径
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
System.out.println("WebSocket closed.");
if (ffplayProcess != null) {
ffplayProcess.destroy();
}
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public void onMessage(WebSocket conn, byte[] message) {
try {
outputStream.write(message); // 将音频数据写入文件
ffplayProcess.getOutputStream().write(message); // 将RTP音频数据写入FFplay进程标准输入流中
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
}

public static void main(String[] args) {
WebSocketServer server = new FFplayWebSocketServer(8080);
server.start();
System.out.println("Server started.");
}
}

​

在上述代码中,我们添加了一个FileOutputStream对象用于将音频数据写入到文件中,同时在WebSocketServer关闭时关闭该输出流并刷新缓冲区,确保文件写入完整的音频数据。需要注意的是,在实际应用中,需要在每次接收到音频数据时调用outputStream.write()方法将其写入文件中,以保证完整保存音频数据。

3.音频质量问题

一般的pc或者mac都会带响应的音频处理算法,若是所在终端的音频质量不佳,可以考虑调用speex.js或者自行封装webrtc音频处理算法的噪声抑制和音量增益算法,来提升音频的品质问题。

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

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

相关文章

.Net Core依赖注入

.Net Core依赖注入 往期文章: .ner Core实现接口限流.net Core程序发布到IIS(Window Server 2019) 文章目录 .Net Core依赖注入前言一、ICO 和DI和DLICO [控制反转]DI [依赖注入]DL [依赖查找] 二、.net Core 中的依赖注入【Autofac】瞬时模式作用域模式单例模式尝…

Android Dalvik 虚拟机(详细版)

经典好文推荐,通过阅读本文,您将收获以下知识点: 1.Java 语言在Android 上运行流程 2.虚拟机发展过程 3.Android Dalvik 模式 4.Android N 中dex2oat 原理以及模式 5.如何判断dex2oat 采用的相关参数 6.如何查看dex2oat 的log 7.什么时候进行dex2oat 8.手机反应慢的原因 9.解…

再获权威认可!MIAOYUN荣获中国信通院一云多芯优秀案例,荣登《云管理产品与服务图谱》

2023年7月25日,以“云领创新,算启新篇”为主题的2023可信云大会在北京国际会议中心顺利召开。会上中国信息通信研究院发布了一云多芯稳定安全运行优秀案例和业界首个《云管理产品与服务图谱(2023)》。成都元来云志科技有限公司&am…

QEMU源码全解析12 —— QOM介绍(1)

接前一篇文章:QEMU源码全解析11 —— 定义一个QEMU模块(3) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 特此致谢! 前几…

springboot创建并配置环境(一) - 创建环境

文章目录 一、介绍二、启动环境Environment的分析三、进入源码四、创建环境1. 如何确定应用类型2. 测试 一、介绍 在springboot的启动流程中,启动环境Environment是可以说是除了应用上下文ApplicationContext之外最重要的一个组件了,而且启动环境为应用…

5点搞透电阻选型

一提到电阻,大家肯定会想到一个人:欧姆。 欧姆(Georg Simon 0hm,1787~1854年)是德国物理学家。生于巴伐利亚埃尔兰根城。欧姆定律及其公式的发现,给电学的计算,带来了很大的方便。 人们为了纪念他,将电阻的…

前端css--导航栏效果

效果如下&#xff1a; <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>导航栏动态效果</title><link rel"stylesheet" href"./style/style.css"> </head> &…

51单片机:数码管和矩阵按键

目录 一:动态数码管模块 1:介绍 2:共阴极和共阳极 A:共阴极 B:共阳极 C:转化表 3:74HC138译码器 4:74HC138译码器控制动态数码管 5:数码管显示完整代码 二:矩阵按键模块 1:介绍 2:原理图 3:矩阵按键代码 一:动态数码管模块 1:介绍 LED数码管&#xff1a;数码管是一种…

【数字IC】芯片产业链

芯片产业链 FoundaryFablessEDADesign ServiceIP供应商IDM就业岗位 Foundary Fabless 无晶圆厂 IC design house EDA Design Service Veri Silicon &#xff1a; 芯原微 Alchip&#xff1a;世芯&#xff08;上海&#xff09; Brite&#xff1a;灿芯&#xff08;上海&…

Vue+ElementUI操作确认框及提示框的使用

在进行数据增删改查操作中为保证用户的使用体验&#xff0c;通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现&#xff0c;点击下载以及删除按钮&#xff0c;会出现对相关信息的提示&#xff0c;操作结果如下所示。 点击…

“数字化员工”,正在占领厂区

劳动力规模逐年降低、劳动生产率增速被平均工资增速超越——中国企业正在面临用工难题。为了应对这一困境&#xff0c;唯一的解决方案就是全面转向“第四种用工模式”——“数字化劳动力”&#xff0c;它可以全力激活人效潜能&#xff0c;并助力企业行稳致远。 智能中央立库中的…

放射组学增强的深度多任务学习用于头颈癌预后预测

文章目录 Radiomics-enhanced Deep Multi-task Learning for Outcome Prediction in Head and Neck Cancer摘要本文方法实验结果 Predicting Regions of Local Recurrence in Glioblastomas Using Voxel-Based Radiomic Features of Multiparametric Postoperative MRI摘要方法…

猿人学第二题—混淆 动态cookie检测

猿人学第二题—混淆 动态cookie检测 1、代码格式化检测2、检测global和navigator.vendorSub3、检测setInterval思考 4、console.log输出检测补环境 简单的document.cookie&#xff0c;location.reload等就不写了 1、代码格式化检测 这里应该是利用了字符串正则匹配性能低的特点…

管理类联考——写作——素材篇——论说文——可持续发展——食蚁兽

巴西热带雨林中的食蚁兽在捕食时&#xff0c;使用带粘液的长舌伸进蚁穴捕获白蚁&#xff0c;但不管捕获多少&#xff0c;每次捕食都不超过3分钟&#xff0c;然后去寻找下一个目标&#xff0c;从来不摧毁整个蚁穴。而那些没有被食蚁兽捕获的工蚁就会修复蚁穴&#xff0c;蚁后也会…

【C++进阶之路】继承篇

文章目录 前言一、概念二、性质1.赋值转换2.作用域——隐藏/重定义3.默认成员函数①构造函数②拷贝构造③析构函数④赋值重载 4.友元函数5.多继承①单继承—— "一脉单传"②多继承——"一父多子"③菱形继承—— "一子多父"④菱形虚拟继承 三、总…

【数据分享】1999—2021年地级市固定资产投资和对外经济贸易数据(Shp/Excel格式)

在之前的文章中&#xff0c;我们分享过基于2000-2022年《中国城市统计年鉴》整理的1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额、地方一般公共预算收支状…

第二十章 原理篇:CLIP

参考教程&#xff1a; 【PDF】Learning Transferable Visual Models From Natural Language Supervision https://github.com/openai/CLIP 文章目录 概述方法自然语言监督创建一个足够大的数据集选择高效的预训练方法代码解读 选择和缩放模型训练使用 代码解读model load rel…

软件测试:单点登录之—单点流程

用户认证中心采用票据传递的方式进行用户信息共享&#xff0c;保证登录会话在不同的站点进行创建。用户访问目标站点时通过当前登录的站点创建票据&#xff0c;传递票据到目标站点&#xff0c;目标站点接收到票据之后调用用户中心认证系统接口进行票据认证&#xff0c;认证成功…

【C语言15】单链表,(对于二级指针与一级指针应用的详细讲述)

文章目录 单链表1.单链表的介绍2.单链表的实现2.1.1单链表结点的创建与销毁2.1.2单链表尾插2.1.3单链表打印2.1.4尾删2.1.5头插2.1.6头删2.1.7查找2.1.8在pos位置之后插入数据2.1.9删除pos位置 单链表 1.单链表的介绍 链表是一种物理存储结构上非连续、非顺序的存储结构&#…

科学家用ChatGPT写完1篇论文仅用1小时!多所高校撤销禁令

自2022年11月发布以来&#xff0c;许多人都在使用ChatGPT来帮助他们完成工作&#xff0c;各行各业的人都在使用&#xff0c;从撰写营销材料&#xff0c;到起草电子邮件&#xff0c;再到生成报告。 ChatGPT作为一种人工智能工具&#xff0c;在科研中也显示非常大的应用潜力&…