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

关于前端与APP录音相关的笔记

文章目录

  • 一、前言
  • 二、内容组成
    • 1、权限获取
    • 2、针对设备兼容
    • 3、内容类型转换
    • 4、传输存储
  • 三、拓展内容
      • 自动播放部分

一、前言

主要针对前端适配录音能力的简要记录,针对默认的wav及其可能需要转换到特定的mp3之类格式以适配需求的问题。(这类通常是兼容tts或客服语音备份)
这里纠结点主要会是在 ios/android设备的兼容类型转换的问题

二、内容组成

主要围绕下面几个重要组成部分
①权限获取
②针对设备兼容
③内容类型转换
④传输存储

1、权限获取

这里首先需要确定的一点是,获取录音权限,除了通常的 localhost 之外,仅有证书存在的domain/ip 浏览器才会允许获取权限。(哪怕是自定义证书也是可以的)

针对app端部分内容嵌入适配

这里主要是考虑到app的基础配置,基于前者的情况下(截止操作时间2023.8.1)

Android:

其实根据通用的方式,就是动态设置,哪个webview使用设置哪个。

<!-- 所需权限列表 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
//伪代码部分AudioWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);}@Overridepublic void onPermissionRequest(PermissionRequest request) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){//直接无脑同意即可request.grant(request.getResources());}}});
//这里是基础链接
AudioWebView.loadUrl("{{baseUrl}}");

IOS

这里补充一点,即便webview已经允许你调用录音,某种情况下,其实也存在某些版本每次调用前询问,所以最好做好预案
Tips: ios中叫做 WKWebView

//伪代码部分
import AVFoundation// 请求录音权限
func requestRecordPermission() {AVAudioSession.sharedInstance().requestRecordPermission { granted inif granted {// 用户授权了录音权限,可以加载WebView了self.loadWebView()} else {// 用户拒绝了录音权限,处理相应逻辑// 例如给出提示或者禁用录音功能}}
}// 加载WebView
func loadWebView() {// 在此处加载WebView,调用录音的网页功能
}

2、针对设备兼容

这里的兼容主要是针对设备部分的区分吧。
首先声明 iosAndroid 的区别
android : 在对应的webview中当且通常仅需首次获取权限即可。(高版本会有选项永久还是单次)
ios: 通常在 wkwebvie 中,每次都需要获取录音权限(这个是兼容低版本ios考虑)

建议解决方案:

android

针对安卓的内容可以采取默认仅请求一次,然后利用本地缓存来保存标记。
当标记失效,则可以通过其他方式让其重新授权即可

ios

针对苹果的内容,不可排除新版本已经解决这个问题,但是出于兼容考虑
还是预先做好 调用权限 的处理,避免需要的时候不存在权限。

3、内容类型转换

这里主要是考虑到可能存在的调用 asr接口 ,会需要适配不同的音频类型。
可以简单参考 语音厂商参数对比

默认来说,浏览器部分,我们通常采用 window.AudioContext || window.webkitAudioContext 的模式来获取录音内容。

如果需要切换类型,我们可以采用 lame.js 来转换所需的MP3类型 。

Tip: 其他类型,目前暂未需要,如有建议,感谢提供

4、传输存储

整个过程中,其实最好使用blob格式传输,附加文件类型
示例 :let blob = new Blob(mp3Data, { type: "audio/mp3" });

例如websock中传递的时候,实际上大都需要我们重新加载一下格式,如果直接blob可能存在无法识别的问题

// 伪代码
// 其中 res 为传递过程中的blob内容
if (suffix == ".mp3" || suffix == ".wav") {let newBlob = new Blob([res.blob], {type: "audio/" + types,});console.log("image types:" + types);console.log("and the new blob is:" + newBlob);let originSrc = (window.URL || window.webkitURL).createObjectURL(newBlob);attachmentDom ='<audio controls="controls" src="' +originSrc +'"></audio>';suffixHandler = true;}

三、拓展内容

自动播放部分

这里其实android 很容易实现,直接通过controls即可控制auto 自动播放
主要是 ios 部分, 由于ios的一些机制问题,不能直接去自动播放可以参考如下的方式

其实就是模拟用户交互来达成


/*** 初始化录音*/
function forceSafariPlayAudio() {if (trys == 0) {audio.src = 'https://www.runoob.com/try/demo_source/horse.mp3'audio.load(); // iOS 9   还需要额外的 load 一下, 否则直接 play 无效audio.play(); // iOS 7/8 仅需要 play 一下trys = 1audioType = 1}}$(function () {function log(info) {console.log(info);}audio = document.getElementById('bgmusic');audio.loop = falseaudio.muted = true// 可以自动播放时正确的事件顺序是// loadstart --> loadedmetadata --> loadeddata -->canplay -->play --> playing// 不能自动播放时触发的事件是// iPhone5  iOS 7.0.6 loadstart// iPhone6s iOS 9.1   loadstart -> loadedmetadata -> loadeddata -> canplayaudio.addEventListener('loadstart', function () {log('loadstart');}, false);audio.addEventListener('loadeddata', function () {log('loadeddata');}, false);audio.addEventListener('loadedmetadata', function () {log('loadedmetadata');}, false);audio.addEventListener('canplay', function () {log('canplay');}, false);audio.addEventListener('play', function () {log('play');// 当 audio 能够播放后, 移除这个事件console.log("初始化成功")window.removeEventListener('touchstart', forceSafariPlayAudio, false);}, false);audio.addEventListener('playing', function () {log('playing');}, false);audio.addEventListener('pause', function () {log('pause');}, false);audio.addEventListener('ended', function () {audioType = 0;}, false);// 由于 iOS Safari 限制不允许 audio autoplay, 必须用户主动交互(例如 click)后才能播放 audio,// 因此我们通过一个用户交互事件来主动 play 一下 audio.window.addEventListener('touchstart', forceSafariPlayAudio, false);audio.src = 'https://www.runoob.com/try/demo_source/horse.mp3'})

相关文章:

关于前端与APP录音相关的笔记

文章目录 一、前言二、内容组成1、权限获取2、针对设备兼容3、内容类型转换4、传输存储 三、拓展内容自动播放部分 一、前言 主要针对前端适配录音能力的简要记录&#xff0c;针对默认的wav及其可能需要转换到特定的mp3之类格式以适配需求的问题。&#xff08;这类通常是兼容tt…...

【Java】SpringBoot项目整合FreeMarker加快页面访问速度

文章目录 什么是FreeMarker&#xff1f;它的优点有那些&#xff1f;使用方式 什么是FreeMarker&#xff1f; Freemarker是一个模板引擎技术&#xff0c;它可以将数据和模板结合起来生成最终的输出。它是一种用于生成文本输出&#xff08;如HTML、XML、JSON等&#xff09;的通用…...

conda环境下安装opencv-python包

conda环境下安装opencv-python包 一、#查看环境 conda info --env# conda environments: # base D:\ProgramData\Anaconda3二、激活base环境 进入conda环境 conda init cmd.exe conda activate base三、根据版本号&#xff0c;下载对应的 python-opencv…...

JVM面试题--类加载器

什么是类加载器&#xff0c;类加载器有哪些 类加载子系统&#xff0c;当java源代码编译为class文件之后&#xff0c;由他将字节码装载到运行时数据区 BootStrap ClassLoader 启动类加载器或者叫做引导类加载器&#xff0c;是用c实现的&#xff0c;嵌套在jvm内部&#xff0c;…...

js怎么计算当前一周的日期

你可以使用 JavaScript 的 Date 对象来计算当前一周的日期。首先&#xff0c;你需要获取当前日期&#xff0c;然后使用 Date 对象的 getDay 方法获取当前是星期几(星期日是 0&#xff0c;星期一是 1&#xff0c;以此类推)。然后&#xff0c;你可以根据当前是星期几来计算出本周…...

【图论】差分约束

一.情景导入 x1-x0<9 ; x2-x0<14 ; x3-x0<15 ; x2-x1<10 ; x3-x2<9; 求x3-x0的最大值&#xff1b; 二.数学解法 联立式子2和5&#xff0c;可得x3-x0<23;但式子3可得x3-x0<15。所以最大值为15&#xff1b; 三.图论 但式子多了我们就不好解了&#xff0…...

13 springboot项目——准备数据和dao类

13.1 静态资源下载 https://download.csdn.net/download/no996yes885/88151513 13.2 静态资源位置 css样式文件放在static的css目录下&#xff1b;static的img下放图片&#xff1b;template目录下放其余的html文件。 13.3 创建两个实体类 导入依赖&#xff1a;lombok <!…...

Java 基础进阶总结(一)反射机制学习总结

文章目录 一、初识反射机制1.1 反射机制概述1.2 反射机制概念1.3 Java反射机制提供的功能1.4 反射机制的优点和缺点 二、反射机制相关的 API 一、初识反射机制 1.1 反射机制概述 JAVA 语言是一门静态语言&#xff0c;对象的各种信息在程序运行时便已经确认下来了&#xff0c;内…...

ERROR: transport error 202: gethostbyname: unknown host报错解决方案

Java 9 syntax for remote debugger: -agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005Java 8 不适用 *:port&#xff0c;应该使用: -agentlib:jdwptransportdt_socket,servery,suspendn,address5005参考 https://stackoverflow.com/questions/50344957/ja…...

PyTorch高级教程:自定义模型、数据加载及设备间数据移动

在深入理解了PyTorch的核心组件之后&#xff0c;我们将进一步学习一些高级主题&#xff0c;包括如何自定义模型、加载自定义数据集&#xff0c;以及如何在设备&#xff08;例如CPU和GPU&#xff09;之间移动数据。 一、自定义模型 虽然PyTorch提供了许多预构建的模型层&#…...

JavaEE——SpringMVC中的常用注解

目录 1、RestController &#xff08;1&#xff09;、Controller &#xff08;2&#xff09;、ResponseBody 2、RequestMappping &#xff08;1&#xff09;、定义 &#xff08;2&#xff09;、使用 【1】、修饰方法 【2】、修饰类 【3】、指定方法类型 【4】、简化版…...

【严重】Metabase 基于H2引擎的远程代码执行漏洞

漏洞描述 Metabase 是一个开源的数据分析和可视化工具。 由于 CVE-2023-38646 的补丁(从H2 JDBC连接字符串中删除INIT脚本以防止命令注入)修复不完全&#xff0c;Metabase 仍受到命令注入的影响。攻击者可使用 H2 作为数据库引擎&#xff0c;通过 /api/setup/validate 端点发…...

0基础学习VR全景平台篇 第75篇:多现场

多现场是指将多台设备的直播画面整合到一个直播活动链接里面&#xff0c;让用户自行选择切换要看哪个直播画面的功能。既可以是同一个活动的不同角度直播&#xff0c;也可以是异地的直播。多现场不需要导播台&#xff0c;并且可以同时支持平面直播和VR直播的混合切换。多现场仅…...

html:去除input/textarea标签的拼写检查

默认情况下&#xff0c;textarea 会启动拼写和语法检查&#xff0c;表现效果就是单词拼写错误会出现红色下划线提示 <textarea></textarea>效果 有时&#xff0c;我们并不需要拼写检查&#xff0c;可以通过配置属性spellcheck"false" 去除拼写和语法检…...

自然语言处理从入门到应用——LangChain:提示(Prompts)-[提示模板:创建自定义提示模板和含有Few-Shot示例的提示模板]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 创建自定义提示模板 假设我们希望LLM根据函数名称生成该函数的英文语言解释。为了实现这个任务&#xff0c;我们将创建一个自定义的提示模板&#xff0c;以函数名称作为输入&#xff0c;并格式化提示模板以提供函数的…...

d3dx9_30.dll如何修复,分享几种一键修复方法

d3dx9_30.dll是DirectX 的一个动态链接库文件&#xff0c;它包含了一些用于图形和游戏的函数和资源。在了解d3dx9_30.dll的解决方法和丢失原因之前&#xff0c;我们先来了解一下DirectX。DirectX是一套由微软开发的多媒体和游戏编程接口&#xff08;API&#xff09;集合。它提供…...

6.8 稀疏数组

6.8 稀疏数组 稀疏数组是一种数据结构&#xff0c;在程序中数据结构的思想&#xff0c;是非常重要的。例如 需求&#xff1a;编写五子棋游戏中&#xff0c;有存盘退出和续上盘的功能。分析问题&#xff1a;因为该二维数组的很多值是默认值0&#xff0c;因此记录了很多没有意义…...

ROS版本的ORB-SLAM3用RealSense D455相机实时运行测试

配置环境 1. C11 检查G版本&#xff0c;查看是否支持C11 一般g版本大于4.7即可 g -v 2. Pangolon 地址&#xff1a;https://github.com/stevenlovegrove/Pangolin 先安装OpenGL&#xff0c;Glew ### 编译orb-slam3发现pangolin编译错误排查的环境问题 sudo apt install p…...

Vue中对对象内容调用的Demo

目录 1.对象作为数据&#xff1a; 2.对象数组 在Vue中&#xff0c;你可以通过对象的键来调用对象中的各个部分的内容。下面是一些使用Vue调用对象各部分内容的示例&#xff1a; 1.对象作为数据&#xff1a; 如果你在Vue实例的数据中有一个对象&#xff0c;你可以使用点语法来…...

语音识别 — 特征提取 MFCC 和 PLP

一、说明 语音识别是一种技术&#xff0c;通过计算机和软件系统&#xff0c;将人们的口头语言转换为计算机可读的文本或命令。它使用语音信号处理算法来识别和理解人类语言&#xff0c;并将其转换为计算机可处理的格式。语音识别技术被广泛应用于许多领域&#xff0c;如语音助手…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...