关于前端与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、针对设备兼容
这里的兼容主要是针对设备部分的区分吧。
首先声明ios
与Android
的区别
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、传输存储 三、拓展内容自动播放部分 一、前言 主要针对前端适配录音能力的简要记录,针对默认的wav及其可能需要转换到特定的mp3之类格式以适配需求的问题。(这类通常是兼容tt…...
【Java】SpringBoot项目整合FreeMarker加快页面访问速度
文章目录 什么是FreeMarker?它的优点有那些?使用方式 什么是FreeMarker? Freemarker是一个模板引擎技术,它可以将数据和模板结合起来生成最终的输出。它是一种用于生成文本输出(如HTML、XML、JSON等)的通用…...
conda环境下安装opencv-python包
conda环境下安装opencv-python包 一、#查看环境 conda info --env# conda environments: # base D:\ProgramData\Anaconda3二、激活base环境 进入conda环境 conda init cmd.exe conda activate base三、根据版本号,下载对应的 python-opencv…...

JVM面试题--类加载器
什么是类加载器,类加载器有哪些 类加载子系统,当java源代码编译为class文件之后,由他将字节码装载到运行时数据区 BootStrap ClassLoader 启动类加载器或者叫做引导类加载器,是用c实现的,嵌套在jvm内部,…...
js怎么计算当前一周的日期
你可以使用 JavaScript 的 Date 对象来计算当前一周的日期。首先,你需要获取当前日期,然后使用 Date 对象的 getDay 方法获取当前是星期几(星期日是 0,星期一是 1,以此类推)。然后,你可以根据当前是星期几来计算出本周…...

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

13 springboot项目——准备数据和dao类
13.1 静态资源下载 https://download.csdn.net/download/no996yes885/88151513 13.2 静态资源位置 css样式文件放在static的css目录下;static的img下放图片;template目录下放其余的html文件。 13.3 创建两个实体类 导入依赖:lombok <!…...

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

ERROR: transport error 202: gethostbyname: unknown host报错解决方案
Java 9 syntax for remote debugger: -agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005Java 8 不适用 *:port,应该使用: -agentlib:jdwptransportdt_socket,servery,suspendn,address5005参考 https://stackoverflow.com/questions/50344957/ja…...
PyTorch高级教程:自定义模型、数据加载及设备间数据移动
在深入理解了PyTorch的核心组件之后,我们将进一步学习一些高级主题,包括如何自定义模型、加载自定义数据集,以及如何在设备(例如CPU和GPU)之间移动数据。 一、自定义模型 虽然PyTorch提供了许多预构建的模型层&#…...

JavaEE——SpringMVC中的常用注解
目录 1、RestController (1)、Controller (2)、ResponseBody 2、RequestMappping (1)、定义 (2)、使用 【1】、修饰方法 【2】、修饰类 【3】、指定方法类型 【4】、简化版…...

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

0基础学习VR全景平台篇 第75篇:多现场
多现场是指将多台设备的直播画面整合到一个直播活动链接里面,让用户自行选择切换要看哪个直播画面的功能。既可以是同一个活动的不同角度直播,也可以是异地的直播。多现场不需要导播台,并且可以同时支持平面直播和VR直播的混合切换。多现场仅…...

html:去除input/textarea标签的拼写检查
默认情况下,textarea 会启动拼写和语法检查,表现效果就是单词拼写错误会出现红色下划线提示 <textarea></textarea>效果 有时,我们并不需要拼写检查,可以通过配置属性spellcheck"false" 去除拼写和语法检…...
自然语言处理从入门到应用——LangChain:提示(Prompts)-[提示模板:创建自定义提示模板和含有Few-Shot示例的提示模板]
分类目录:《自然语言处理从入门到应用》总目录 创建自定义提示模板 假设我们希望LLM根据函数名称生成该函数的英文语言解释。为了实现这个任务,我们将创建一个自定义的提示模板,以函数名称作为输入,并格式化提示模板以提供函数的…...

d3dx9_30.dll如何修复,分享几种一键修复方法
d3dx9_30.dll是DirectX 的一个动态链接库文件,它包含了一些用于图形和游戏的函数和资源。在了解d3dx9_30.dll的解决方法和丢失原因之前,我们先来了解一下DirectX。DirectX是一套由微软开发的多媒体和游戏编程接口(API)集合。它提供…...

6.8 稀疏数组
6.8 稀疏数组 稀疏数组是一种数据结构,在程序中数据结构的思想,是非常重要的。例如 需求:编写五子棋游戏中,有存盘退出和续上盘的功能。分析问题:因为该二维数组的很多值是默认值0,因此记录了很多没有意义…...
ROS版本的ORB-SLAM3用RealSense D455相机实时运行测试
配置环境 1. C11 检查G版本,查看是否支持C11 一般g版本大于4.7即可 g -v 2. Pangolon 地址:https://github.com/stevenlovegrove/Pangolin 先安装OpenGL,Glew ### 编译orb-slam3发现pangolin编译错误排查的环境问题 sudo apt install p…...
Vue中对对象内容调用的Demo
目录 1.对象作为数据: 2.对象数组 在Vue中,你可以通过对象的键来调用对象中的各个部分的内容。下面是一些使用Vue调用对象各部分内容的示例: 1.对象作为数据: 如果你在Vue实例的数据中有一个对象,你可以使用点语法来…...

语音识别 — 特征提取 MFCC 和 PLP
一、说明 语音识别是一种技术,通过计算机和软件系统,将人们的口头语言转换为计算机可读的文本或命令。它使用语音信号处理算法来识别和理解人类语言,并将其转换为计算机可处理的格式。语音识别技术被广泛应用于许多领域,如语音助手…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...