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

语音相关-浏览器的自动播放策略研究和websocket研究

策略详情在这里插入图片描述

媒体参与度

在这里插入图片描述

在这里插入图片描述

AudioContext音频API的实现

在这里插入图片描述

new Audio音频API的实现

在这里插入图片描述

在这里插入图片描述

相关实践

网页端

使用new Audio创建的音频对象进行音频播放的时候,如果用户没有与页面进行交互,那么会报错如下:

在这里插入图片描述
使用AudioContext创建的对象播放音频,不会报错,但是会有警告如下:

在这里插入图片描述

以上报错都是在用户与页面交互前,创建音频对象的时候报错。我们通过websocket推送的音频消息,只要用户没有与页面有交互,都不会进行播放。直到用户点击了页面,与页面进行了交互,我们后续的websocket音频消息才能正常播放。

钉钉桌面端

我们将我们的H5应用集成到钉钉桌面端,在网页端出现的无交互不播放的问题,在钉钉桌面端不存在。
但是钉钉桌面端又存在其他问题。

(1)钉钉桌面端挂后台定时任务放缓

由于收到节能机制影响,导致ws断线重连的时候延迟到2分钟后才发起重连
我们使用web worker可以绕开节能机制的影响

// timer-worker.js
let timers = {};self.onmessage = function(e) {const { type, id, delay } = e.data;switch(type) {case 'setInterval':timers[id] = setInterval(() => {postMessage({ type: 'interval', id });}, delay);break;case 'setTimeout':timers[id] = setTimeout(() => {postMessage({ type: 'timeout', id });delete timers[id];}, delay);break;case 'clearInterval':case 'clearTimeout':if (timers[id]) {clearInterval(timers[id]);clearTimeout(timers[id]);delete timers[id];}break;}
};
// timer-worker-class.js
class WorkerTimer {constructor() {this.worker = new Worker('resources/central/common/timer-worker.js');this.callbacks = {};this.currentId = 0;this.worker.onmessage = (e) => {const { type, id } = e.data;if (this.callbacks[id]) {this.callbacks[id]();if (type === 'timeout') {delete this.callbacks[id];}}};}setInterval(callback, delay) {const id = ++this.currentId;this.callbacks[id] = callback;this.worker.postMessage({ type: 'setInterval', id, delay });return id;}setTimeout(callback, delay) {const id = ++this.currentId;this.callbacks[id] = callback;this.worker.postMessage({ type: 'setTimeout', id, delay });return id;}clearInterval(id) {if (this.callbacks[id]) {this.worker.postMessage({ type: 'clearInterval', id });delete this.callbacks[id];}}clearTimeout(id) {if (this.callbacks[id]) {this.worker.postMessage({ type: 'clearTimeout', id });delete this.callbacks[id];}}}

项目代码中使用如下

   workerTimer:new WorkerTimer(),vm.workerTimer.clearInterval(vm.heartbeatTimer);vm.workerTimer.setInterval

如上确实解决了定时任务放缓的问题。

(2)钉钉桌面端挂后台声音积压和声音丢失

钉钉桌面端最小化的时候,等待2分钟后派单,无声音播报,若立马切前台,会发出语音(如果派单了多条,那么此时会同时发出多条语音)。若等待时间较久,那么语音会丢失。
在这里插入图片描述
且切换前台的时候,websocket的onmessage回调方才执行。
问题在咨询钉钉专家团队,尚未解决。

(3)钉钉桌面端挂前台websocket三分钟一断开

通过添加心跳协议解决该问题,同时保证断线重连。websocket代码如下:

 isConnecting:false,heartbeatInterval:30000,heartbeatTimer:null,reconnectInterval:300,setNoticeSocket(time){let vm = this;console.log("重连setNoticeSocket",vm.isConnecting,'new Date()',new Date(),'time-notifyConnetTime',time);if(vm.isConnecting){return;}if (typeof (WebSocket) == "undefined"){console.log("current web client is not support for websocket.")} else {let host = window.location.host;let scheme = window.location.protocol;let ws = 'ws://' + host;if (scheme.toLowerCase() == 'https:'){ws = 'wss://' + host;}let name= JSON.parse(localStorage.getItem('user')).user.replace(/\\/g,"*");let url = '/central/notify/refresh/'+name;console.log("重连newwebsocket前",new Date(),'vm.noticeSocket',vm.noticeSocket,'vm.noticeSocket.readyState',vm.noticeSocket && vm.noticeSocket.readyState)if(!vm.noticeSocket || (vm.noticeSocket && vm.noticeSocket.readyState === WebSocket.CLOSED)){console.log("重连newwebsocket",new Date(),'vm.noticeSocket.readyState',vm.noticeSocket && vm.noticeSocket.readyState,'time--notifyConnetTime',time)vm.isConnecting = true;vm.noticeSocket = new WebSocket(ws+url);vm.noticeSocket.onopen = function () {console.log("重连成功onopen",new Date())vm.isConnecting = false;vm.notifyConnetTime = 0;let data = {use:"FILTER",perspective:localStorage.getItem('perspective'),status: "0",id:'READ'};vm.noticeSocket.send(JSON.stringify(data))vm.heartbeatTimer && vm.workerTimer.clearInterval(vm.heartbeatTimer);vm.heartbeatTimer = vm.workerTimer.setInterval(() => {if (vm.noticeSocket.readyState === WebSocket.OPEN) {vm.noticeSocket.send(JSON.stringify({ type: 'heartbeat' }));}}, vm.heartbeatInterval);};vm.noticeSocket.onmessage = function (message) {let res = message.data;console.log("接收到ws消息----",res,new Date())if(!res) return;try{let data = JSON.parse(res);}catch(err){}};vm.noticeSocket.onclose = function (message) {vm.isConnecting = false;vm.heartbeatTimer && vm.workerTimer.clearInterval(vm.heartbeatTimer);vm.heartbeatTimer = null;vm.reconnetNotice('来自close');};vm.noticeSocket.onerror = function (message) {vm.isConnecting = false;vm.heartbeatTimer && vm.workerTimer.clearInterval(vm.heartbeatTimer);vm.heartbeatTimer = null;vm.noticeSocket.close();};}}},reconnetNotice(type){let vm  = this;console.log("reconnetNotice-发起重连type",type,vm.notifyConnetTime,'new Date()',new Date())// if(vm.notifyConnetTime<20){vm.workerTimer.setTimeout(()=>{vm.notifyConnetTime=vm.notifyConnetTime +1;console.log("重连执行--vm.notifyConnetTime",type,vm.notifyConnetTime,'date',new Date())vm.setNoticeSocket(vm.notifyConnetTime)},vm.reconnectInterval)// }return;},
(4)钉钉桌面端挂后台websocket五分钟一断开

问题在咨询钉钉专家团队,尚未解决。

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

相关文章:

  • RPGMZ游戏引擎 如何手动控制文字显示速度
  • 开疆智能ModbusTCP转EtherCAT网关连接IVO编码器配置案例
  • APP CPU测试--Android Profiler实操(入门版)
  • Flutter ListTile 深度解析
  • 【二进制安全作业】250617课上作业4 - start
  • springboot整合规则引擎(liteflow)使用
  • 解决Docker网络与虚拟机桥接冲突的实践指南
  • Docker环境部署
  • Dilworth 定理 学习笔记
  • html和css实现文本打断换行、自动换行
  • leetcode hot100 两数之和
  • Unity2D 街机风太空射击游戏 学习记录 #12环射道具的引入
  • C语言:实现杨辉三角的种方法
  • Linux命令合集
  • LVS负载均衡群集:Nginx+Tomcat负载均衡群集
  • 云宏信息轻量云平台:解锁金融业IT架构优化之路
  • Postman接口测试完整版
  • 《P2161 [SHOI2009] 会场预约》
  • 将无序json数据转换为excel表格形式
  • 【FineDance】vis.py 硬编码路径的修复
  • 服务器手动安装并编译R环境库包:PROJ→RGDAL
  • RenderDoc抓webgl 1
  • 科技赋能民生:中建海龙为民生改善注入新动力
  • 【CS创世SD NAND征文】STM32户外无线终端管理设备的数据存储方案
  • Logback 在java中的使用
  • 力扣-169.多数元素
  • [muduo] docs | 配置教程 | EventLoop | Thread
  • python实战项目76:51job数据采集与分析
  • 14.9 AI教学系统测试全攻略:模块化调试与5大模块实战指南
  • 服务网格安全(Istio):用零信任架构重构微服务通信安全