语音相关-浏览器的自动播放策略研究和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.pswp.cn/web/84450.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84450.shtml

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

相关文章

Linux操作系统网络服务模块一DHCP服务概述

前言&#xff1a; 在Linux网络服务体系架构中&#xff0c;​DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;​​ 作为核心服务之一&#xff0c;承担着局域网内主机网络参数动态分配的关键任务。其设计初衷是解决传统手动配置IP地址的效率瓶颈与错误风…

FPGA基础 -- Verilog语言要素之变量类型

Verilog 变量类型&#xff08;Variable Types&#xff09; 一、什么是变量类型&#xff1f; 在 Verilog 中&#xff0c;变量类型用于保存过程赋值结果&#xff08;由 always 或 initial 块赋值&#xff09;&#xff0c;通常用于建模寄存器、状态、计数器等“带记忆”的硬件行为…

使用Haporxy搭建Web群集

目录 一、案例分析 1.案例概述 2.案例前置知识点 2.1 HTTP请求 2.2 负载均衡常用调度算法 2.3常见的Web群集调度器 3.案例环境 3.1本案例环境 二、案例实施 1.搭建两台web服务器 2.安装Haproxy 3.haproxy服务器配置 修改haproxy的配置文件 4.测试web群集 5.haproxy的日…

pikachu靶场通关笔记38 目录遍历(路径遍历)

目录 一、目录遍历 二、源码分析 三、目录遍历与文件包含 四、实战渗透 1、进入靶场 2、目录遍历 &#xff08;1&#xff09;访问ace.min.css &#xff08;2&#xff09;访问fileinclude.php 本系列为《pikachu靶场通关笔记》渗透实战&#xff0c;本文通过对目录遍历源…

现代C++:std::string全方位碾压C字符串

在 C 中引入的 std::string 是对 C 语言中 char* 和 const char* 的一种现代化封装和增强。它不仅解决了 C 字符串的许多缺陷&#xff08;如安全性、内存管理、易用性等&#xff09;&#xff0c;还提供了丰富的 API 来简化字符串操作。本文将从多个维度详细对比 std::string 与…

20250619周四:Atlassian

今天主要把conference上的A xxx的所有资料大体看了一遍&#xff0c;花了两个多小时。 公司的这个conference系统&#xff0c;共实就是一个大型的可多人在线编辑的文件系统。差不多所有的资料都共享在上面。这对于多人参与的项目管理&#xff0c;还是相当方便的。 Atlassian最特…

通过CDH安装Spark的详细指南

通过CDH安装Spark的详细指南 简介 Cloudera Distribution of Hadoop (CDH) 是一个企业级的大数据平台,它集成了多个开源组件,包括Hadoop、Spark、Hive等。本文将详细介绍如何通过CDH安装和配置Spark。 前提条件 在开始安装之前,请确保满足以下条件: 已安装CDH集群具有管…

GitLab CVE-2025-5121 安全漏洞解决方案

本分分享极狐GitLab 补丁版本 18.0.2, 17.11.4, 17.10.8 的详细内容。这几个版本包含重要的缺陷和安全修复代码&#xff0c;我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS&#xff0c;技术团队已经进行了升级&#xff0c;无需用户采取任…

【八股消消乐】Elasticsearch优化—检索Labubu

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本专栏《八股消消乐》旨在记录个人所背的八股文&#xff0c;包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点&#xff…

如何实现基于场景的接口自动化测试用例?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 自动化本身是为了提高工作效率&#xff0c;不论选择何种框架&#xff0c;何种开发语言&#xff0c;我们最终想实现的效果&#xff0c;就是让大家用最少的代码&…

FreeRTOS 任务管理学习笔记

FreeRTOS 任务管理学习笔记 引言 本文档旨在通过在STM32微控制器上使用FreeRTOS来理解和实现任务管理。实验的重点是创建和管理多个任务、处理任务同步以及通过简单的硬件接口控制任务状态。 实验概述 实验涉及创建三个任务&#xff1a; LED1_Task: 每300毫秒切换一次LED。…

c++set和pair的使用

set是C中的一种关联容器&#xff0c;具有以下特点&#xff1a; 存储唯一元素&#xff08;不允许重复&#xff09; 元素自动排序&#xff08;默认升序&#xff09; 基于红黑树实现&#xff08;平衡二叉搜索树&#xff09; 插入、删除和查找的时间复杂度为O(log n) 前言 在C…

终端命令行执行具体的方法名测试用例

你可以使用如下命令单独执行 test_mutation_login_by_email 方法:python3 manage.py test apps.login.test_client.LoginTestCase.test_mutation_login_by_email 注意事项: 路径 apps.login.test_client 要与你项目实际的 Python 包路径一致(即 test_client.py 文件所在的包…

20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统

【处理SDK】 rootrootrootroot-X99-Turbo:~/Android14$ tar zxvf rk3576-android14.0-20250217.tar.gz rootrootrootroot-X99-Turbo:~/Android14$ ll rootrootrootroot-X99-Turbo:~/Android14$ rm rk3576-android14.0-20250217.tar.gz rootrootrootroot-X99-Turbo:~/Android1…

碳中和时代的家电革命,从华为智选IAM看科技企业的环保担当

在"双碳"战略与品质消费浪潮的双重加持下&#xff0c;家电产业正经历一场前所未有的绿色革命。华为智选与空净十大品牌IAM的深度协同&#xff0c;不仅构建了智能家电领域的技术新高地&#xff0c;更通过系统性创新持续拓展着行业可持续发展的想象空间。从净水科技的突…

(C语言)Map数组的实现(数据结构)(链表)(指针)

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>// 键值对节点 typedef struct Node {char* key;int value;struct Node* next; } Node;// Map结构 typedef struct {Node* buckets[100]; // 固定大小的哈希桶&#xff08;…

Logback示例解析

<configuration><!-- 环境变量 --><springProperty scope"context" name"app.name" source"spring.application.name" defaultValue"application"/><!-- 日志存放路径 --><property name"log.path&qu…

elementui响应式数据类型变更情况

背景。vue2。data中定义的响应数据类型是[]数组。应用在el-select中&#xff08;非multiple情况&#xff09;。当发生响应数据有变更渲染视图时&#xff0c;发现定义的数组转换成了字符串。 本身不是问题。但因为疏忽引发了watch监听formData数据时产生了产生了多次监听事件。…

人机融合智能 | 人智交互语境下的设计新模态

本章旨在探讨技术与设计领域在人智交互语境下的关系及其影响,讨论通过传统设计对人智交互的优化方法。通过回顾大数据和发展趋势,以 AI技术作为重要的技术推力,我们认为 AI技术将会在未来成为设计领域不可缺少的重要环节,并能够帮助设计师更加高效、准确地开展设计工作。本章着…

C++设计模式分类(GOF-23种设计模式)

文章目录 GOF-23 设计模式分类一、从目的分类1. 创建型&#xff08;Creational&#xff09;模式2. 结构型&#xff08;Structural&#xff09;模式3. 行为型&#xff08;Behavioral&#xff09;模式 二、从范围分类1. 类模式&#xff08;Class Pattern&#xff09;2. 对象模式&…