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

一、前言

主要针对前端适配录音能力的简要记录,针对默认的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() {
       @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }

        @Override
        public 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 in
        if 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 = 1
        audioType = 1
    }

}

$(function () {
    function log(info) {
        console.log(info);
    }

    audio = document.getElementById('bgmusic');
    audio.loop = false
    audio.muted = true

    // 可以自动播放时正确的事件顺序是
    // loadstart --> loadedmetadata --> loadeddata -->canplay -->play --> playing
    // 不能自动播放时触发的事件是
    // iPhone5  iOS 7.0.6 loadstart
    // iPhone6s iOS 9.1   loadstart -> loadedmetadata -> loadeddata -> canplay
    audio.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'

})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值