当前位置: 首页 > 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五分钟一断开

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

相关文章:

  • Kafka线上集群部署方案:从环境选型到资源规划思考
  • C#学习日记
  • 基于存储过程的MySQL自动化DDL同步系统设计
  • GNU Octave 基础教程(2):第一个 Octave 程序
  • 作为运营,需要在账号中给用户提供什么?
  • 文件管理总结
  • HCIP-数据通信基础
  • python高校运动会数据分析管理系统
  • LINUX620 NFS
  • 空壳V3.0,免费10开!
  • PAI推理重磅发布模型权重服务,大幅降低冷启动与扩容时长
  • Qi无线充电:车载充电的便捷与安全之选
  • 多相机三维人脸扫描仪:超写实数字人模型制作“加速器”
  • vue3组件式开发示例
  • Node.js 在前端开发中的作用与 npm 的核心理解
  • 【AI时代速通QT】第二节:Qt SDK 的目录介绍和第一个Qt Creator项目
  • 测试夹选购及使用笔记
  • Flutter Hero 组件详解及应用
  • 如何正确处理音频数据:16位整数与32位浮点数
  • 如何自建服务器并开启公网IP:本地内网网址让外网访问详细教学
  • 做垃圾网站怎么赚钱/不死鸟分享友情链接
  • 吉林省建设标准化网站/关键词优化方法有什么步骤
  • 做网站卖机械/网络营销七个步骤
  • 怎么样才能把网站关键词做有排名靠前/营销策划思路
  • wordpress计数器/专业seo网站
  • 施工企业资质查询官网/windows优化大师卸载不掉