webSokect安卓和web适配的Bug 适用实时语音场景

❌BUG:

javascript 复制代码
Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'https' is not allowed.

WebSocket 协议在创建连接时,规定其 URL 的协议头(scheme)必须是 ws(用于非加密的普通 WebSocket 连接,类似 HTTP 之于 HTTPS)或者 wss(用于加密的 WebSocket 连接,类似 HTTPS 之于 HTTP)

  • 在 Web 端,浏览器(如 Chrome、Firefox 等)有比较频繁的自动更新机制。这些更新通常会包含对各种网络协议包括 WebSocket 和常规 HTTP/HTTPS 链接兼容性的改进。当出现新的网络协议标准或者安全要求时,浏览器会快速更新以适应这些变化。所以,对于一些不符合严格规范但在实际使用中可能不会产生严重安全问题的情况(如某些对常规链接的模糊处理),浏览器可能会进行内部的兼容处理,而不要求开发者显式地去处理。

    只能接受 (wss://..., https://...)

  • 相比之下,手机端的应用更新(无论是系统应用还是第三方应用)相对没有那么及时。而且,手机操作系统为了确保安全性和稳定性,对应用的网络连接要求更加严格,不太可能自动对不符合规范的链接进行兼容处理。

    只能接受(wss://... )

    ❌BUG

javascript 复制代码
recorder.ts:42 Uncaught (in promise) InvalidStateError: Cannot close a closed AudioContext

不能关闭一段已经关闭的音频,关闭前作判断

javascript 复制代码
stop() {//停止音频录制过程并释放相关资源。
    if (this.mediaStream) {
      this.mediaStream.getTracks().forEach((track) => track.stop());
    }
    if (this.audioContext && !this.audioContextClosed) {
      this.audioContext.close();
      this.audioContextClosed = true
    }
  }

这种方式关闭音频录制,会导致:同一时间段如果有其它音频播放,声音会变小

缺点:

  • 资源释放的程度和方式

    • 你的方法会完全停止媒体流(mediaStream)中的所有音频轨道,通过调用每个轨道的stop方法来实现。这是一种比较彻底的停止方式,它会立即中断音频的录制过程,并且释放与媒体流相关的资源。
    • 同时,对于AudioContext,如果它存在且尚未关闭(通过audioContextClosed标志判断),会关闭AudioContext。关闭AudioContext会释放与之相关的所有音频节点、处理器以及连接等资源,包括可能正在处理或缓存的音频数据。这是一种比较 "重量级" 的资源释放操作,适用于完全结束音频相关的任务,并且在之后可能不会很快再次使用音频功能的场景。
  • 对其他音频的潜在影响

    • 由于这种方式会停止媒体流和关闭AudioContext,如果在同一环境下有其他音频正在播放或者依赖于这个AudioContext进行音频处理(例如混音、音频效果处理等 ),这些音频活动很可能会受到影响。例如,其他音频可能会突然停止播放 ,或者因为AudioContext被关闭而丢失一些音频处理状态,需要重新初始化才能继续正常工作

优化:

  • 暂时关闭麦克风音频输入

    可以通过获取媒体流中的音频轨道(MediaStreamTrack)并设置其enabled属性为false来暂时关闭麦克风。媒体流中的每个音频轨道对应麦克风的输入通道。例如:

js 复制代码
       function disableMicrophone() {
         if (mediaStream && mediaStream.getAudioTracks().length > 0) {
           const audioTrack = mediaStream.getAudioTracks()[0];
           audioTrack.enabled = false;
         }
       }
  • 原理及为何不影响其他音频播放
    • 这种方式只是暂停了麦克风音频流进入AudioContext的通道,不会干扰已经在AudioContext或者其他独立音频播放系统中的其他音频。AudioContext中的其他音频节点(如用于播放背景音乐等的BufferSourceNode)以及外部独立的音频播放(例如通过<audio>标签或者其他AudioContext实例播放的音频)会继续正常工作,因为关闭麦克风音频轨道只是切断了这一个特定的输入源,而没有改变整个音频环境的其他部分。
  • 重新开启麦克风音频输入
    • 当需要重新开启麦克风时,将音频轨道的enabled属性设置回true即可。例如:
js 复制代码
       function enableMicrophone() {
         if (mediaStream && mediaStream.getAudioTracks().length > 0) {
           const audioTrack = mediaStream.getAudioTracks()[0];
           audioTrack.enabled = true;
         }
       }

❌在http环境会出现一些录音权限不存在情况

javascript 复制代码
this.audioContext.audioWorklet.addModule(moduleUrl);  // 报错addmodule不存在

为了用户的隐私,一般许多API(包括录音权限访问),只能在https才能够访问。为什么http://localhost可以访问原因是因为chrome对于localhost管理较松

参考文章:https://modstart.com/p/r13f9t7tpnsuqbss

相关推荐
Epicurus1 分钟前
JavaScript无阻塞加载的方式
前端·javascript
1024小神3 分钟前
tauri程序使用github action发布linux中arm架构
前端·javascript
ahhdfjfdf5 分钟前
最全的`Map` 和 `WeakMap`的区别
前端
JYeontu10 分钟前
实现一个带@功能的输入框组件
前端·javascript·vue.js
一颗奇趣蛋26 分钟前
vue-router的query和params的区别(附实际用法)
前端·vue.js
孤城28631 分钟前
MAC电脑常用操作
前端·macos·快捷键·新手·电脑使用
木亦Sam31 分钟前
Vue DevTools逆向工程:自己实现一个组件热更新调试器
前端
酷酷的阿云32 分钟前
动画与过渡效果:UnoCSS内置动画库的实战应用
前端·css·typescript
dleei32 分钟前
使用docker创建gitlab仓库
前端·docker·gitlab
勤劳的代码小蜜蜂33 分钟前
大文件上传:告别传统传输瓶颈,让数据流转更高效
前端