IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 微信小程序web-view 外部引用h5页面调用摄像头录制视频 配有提示音 -> 正文阅读

[移动开发]微信小程序web-view 外部引用h5页面调用摄像头录制视频 配有提示音

1、目前的需求是什么

因为项目是银行审批贷款的,所以需要一个视频面签的功能,进入页面时,用户点击开始录制,会提示有第一个问题提示音,用户回答,点击下一个问题,会有第二个,没有问题时,会有结束录制按钮,结束后可以看回放,再点击上传就可以提交到后台了。

2、都踩了那些坑

1、小程序

因为之前没有做过视频录制,对这一块不是很熟悉,先用的是微信小程序页面内直接做的,用的是小程序内置的组件,功能完成后发现最长只能录制30秒,比较鸡肋,重新找解决方案。

2、h5语音提示

后来就想着web-view 外部引用一个h5点页面吧,然后就看到了 recordrtc 这个,发现可以用,挺好,就开始用这个,然后接下来就开始用语音提示,用的是h5,因为我手机是ios 的 ,我在我手机上边测试都是没有问题的,然后就用同时手机测了一下,发现没有声音,我的手机是正常的,后来发现 好像 h5的语音合成好像不支持安卓?换掉,用的是 百度提示的。

3、语音合成声音录制不进去,ios有时候是麦克风,有时候是听筒发音!

调用百度api后,安卓这边录制都是没有问题的,ios这边有时候是听筒发音,有时候是麦克风发音,就好奇怪,好气,后来我让后台这边调用百度api语音合成,暂存服务器,我直接获取就可以了,ok解决问题。

4、语音合成声音录制不进去。

这边声音都正常后,看录制回放的时候,发现语音提示音录制不进去,被降噪了!人傻了。
后来找了好久,发现了一个设置的地方(之前没做过这块,所以不是很懂,别喷),就是录制的时候可以在audio中设置

      captureCamera(callback) {
       navigator.mediaDevices.getUserMedia({
         audio: { volume: { min: 0.0, max: 1.0 }, noiseSuppression: false, echoCancellation: false },
         video: { facingMode: "user" }
       }).then((camera) => {
         callback(camera);
       }).catch(function (error) {
         alert('Unable to capture your camera. Please check console logs.');
         console.error(error);
       });
     },

这样声音就好了

5、以为这样这样就结束了码?没有!ios结束的时候 有时候会不能点击结束

因为我这边问题又很多个,最后发现,在4个问题的时候是可以点击结束的,在4个以上的时候是不能点击结束的,它也不报错,然后debugger,下载recordrtc .js 研究源文件代码,发现是因为在事实结束后,会有个回调函数的,但是这边是没有回调的,

 mediaRecorder.ondataavailable  //这个应该是会自己回调的,但是没有

我以为要凉了,后来找大神指点
因为我这个是官网例子改写的,用的是这样录制的

that.recorder = RecordRTC(camera, {
            //   type: 'video'
            // })

大神将这串代码改成了

           var config = {
              mimeType: 'video/webm', // vp8, vp9, h264, mkv, opus/vorbis
              audioBitsPerSecond : 256 * 8 * 1024,
              videoBitsPerSecond : 256 * 8 * 1024,
              bitsPerSecond: 256 * 8 * 1024,  // if this is provided, skip above two
              checkForInactiveTracks: true,
              timeSlice: 1000, // concatenate intervals based blobs
              ondataavailable: function() {} // get intervals based blobs
            }
            that.recorder = new MediaStreamRecorder(camera, config);

功能就可以使用了!

因为最近都是在用vue 开发,原生的都不是很熟练,所以虽然是一个单页面应用,我用的还是vue axios…别喷
上全套代码

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.bootcdn.net/ajax/libs/RecordRTC/5.6.2/RecordRTC.js"></script>
<script crossorigin="anonymous"
 integrity="sha512-qRXBGtdrMm3Vdv+YXYud0bixlSfZuGz+FmD+vfXuezWYfw4m5Ov0O4liA6UAlKw2rh9MOYULxbhSFrQCsF1hgg=="
 src="https://lib.baomitu.com/vue/2.6.14/vue.common.dev.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
<style type="text/css">
   .demo {
   width: 80%;
   height: 20px;
   position: absolute;
   top: 480px;
   left: 6%;
   border: 2px solid #BBDEFB;
   border-radius: 8px;
 }

 .shixin {
   width: 0;
   height: 0;
   border: 8px solid transparent;
   border-bottom-color: #BBDEFB;
   position: relative;
   top: -39px;
   left: 9%;
 }

 .kongxin {
   width: 0;
   height: 0;
   border: 8px solid transparent;
   border-bottom-color: #fff;
   position: relative;
   top: -52px;
   left: 9%;
 }
 .center {
   display: flex;
   justify-content: center;
 }

 audio {
   display: none;
 }

 button {
   width: 70%;
   padding: 3px;
   background-color: #428bca;
   border-color: #357ebd;
   color: #fff;
   -moz-border-radius: 10px;
   -webkit-border-radius: 10px;
   border-radius: 15px;
   /* future proofing */
   -khtml-border-radius: 10px;
   /* for old Konqueror browsers */
   text-align: center;
   vertical-align: middle;
   border: 1px solid transparent;
   font-weight: 900;
   font-size: 125%
 }
</style>
<title></title>
</head>

<body>
<div id="app">
 <h4 class="center">视频认证</h4>
 <hr>
 <video controls autoplay playsinline ref="video" width="100%" height="400px"></video>
 <div  v-if="showIos" class="demo" style="text-align: center;">
   <span > 请点击开始按钮</span>
   <div class="shixin"></div>
   <div class="kongxin"></div>
 </div>
 <span class="center"  style="margin-top: 30px;" v-show="nextQuestion">{{value}}</span>
 <div class="center" style="margin-top: 30px;">
   <button @click="StartRecording" v-if="startRecording" size="small">开始视频认证</button>
   <button @click="StopRecording" v-else-if="stopRecording" size="small" id="btn-stop-recording">结束视频认证
   </button>
   <button @click="question(problem)" v-else-if="nextQuestion">{{nameButton}}</button>
   <button v-else>上传视频</button>
   </button>
 </div>
</div>
<script>
 new Vue({
   el: '#app',
   //model
   data: {
     nameButton: "开始提问",
     startRecording: true,
     stopRecording: false,
     nextQuestion: false,
     index: 0,
     video: null,
     value: "",
     equipmentType:"",
     videoStart: false,
     recorder: null,
     blob: "",
     showIos:false,
     problem: [
       "请问您是李先生或女士吗?您的身份证号码是11111111122吗?",
       "您此次购买的车型是奔驰E300吗?",
       "您的家人是否知晓并同意您办理的此笔个人汽车金融贷款业务?",
       "您对此笔个人汽车金融贷款业务是否仍存有异议?",
       "如您未按时足额偿还每期月供,将会产生逾期,影响您的央行征信,是否已知晓?",
       "办理此笔汽车金额贷款是您本人的真实意识表达,承诺提供资料均真实有效,若存在欺诈行为,xxxx有权以合同诈骗提报公安机关立案侦查并追究相应的法律责任,您是否已知晓?",
     ]
   },
   //函数
   mounted() {
     this.video = document.querySelector('video');
     this. detect()
   },
   methods: {
     detect() {
       var agent = navigator.userAgent.toLowerCase();
       var android = agent.indexOf("android");
       var iphone = agent.indexOf("iphone");
       var ipad = agent.indexOf("ipad");
       if (android != -1) {
         this.equipmentType = "android";
       }
       if (iphone != -1 || ipad != -1) {
         this.equipmentType = "ios";
       }
       return this.equipmentType;
     },
     question(problem) {
       this.nameButton = "下一个问题"
       this.value = problem[this.index]

       this.baiduToken(this.value)
       if (this.index < (problem.length - 1)) {
         this.index = this.index + 1
       } else {
         this.nextQuestion = false
         this.stopRecording = true
       }
     },
     baiduToken(value) {
       axios.get(`xxxxx?text=${value}`   //向后台调用获取音频路径 ,如果是测试的可以先写一个固定的本地因为路径
       ).then(response => {
         if (response.status === 200) {
           // this.src = response.data.msg
           this.Audio(response.data.msg)
         } else {
           alert(response)
         }
       })

     },
 
     Audio(src) {
       console.log("111", src)
       var audio = document.createElement('audio');
       audio.autoplay = true;
       audio.preload = true;
       audio.controls = true;
       audio.src = src;
       // this.src =
       audio.addEventListener('ended', function () {
         // 设置则播放完后移除audio的dom对象
         document.body.removeChild(audio);
       }, false);
       audio.addEventListener('error', function () {
         document.body.removeChild(audio);
         console.log('合成出错url:' + this.src + '\nAudio错误码:' + audio.error.code);
       }, false);
       audio.loop = false;
       audio.volume = 1;
       // 在body元素下apppend音频控件
       document.body.append(audio);
     },
     stopRecordingCallback() {

       this.video.src = this.video.srcObject = null;
       this.video.muted = false;
       this.video.volume = 1;
       // let Blob = this.recorder.getBlob()
       console.log("let ", this.blob)
       this.video.src = URL.createObjectURL(this.blob);
       this.recorder.camera.stop();
       this.recorder.destroy();
       this.recorder = null;
       this.stopRecording = false
       // alert("点击了3")
     },
     StartRecording() {
       if(this.equipmentType ==="ios" ){
         this.showIos = true
       }
       let that = this
       this.startRecording = false
       this.nextQuestion = true
       this.captureCamera((camera) => {
         that.video.muted = true;
         that.video.volume = 0;
         that.video.srcObject = camera;
         var config = {
           mimeType: 'video/webm', // vp8, vp9, h264, mkv, opus/vorbis
           audioBitsPerSecond : 256 * 8 * 1024,
           videoBitsPerSecond : 256 * 8 * 1024,
           bitsPerSecond: 256 * 8 * 1024,  // if this is provided, skip above two
           checkForInactiveTracks: true,
           timeSlice: 1000, // concatenate intervals based blobs
           ondataavailable: function() {} // get intervals based blobs
         }
         that.recorder = new MediaStreamRecorder(camera, config);

         that.recorder.record();
         // release camera on stopRecording
         that.recorder.camera = camera;
       });
     },
     StopRecording() {
       let that = this
       // console.log("this", this.blob)
       // console.log("1111".this.recorder.stopRecording())
       this.recorder.stop(
         function (blob) {
           // alert("222")
           console.log("this", this)
           that.blob = blob;
           // that.stopRecordingCallback()
           that.video.src = that.video.srcObject = null;
           console.log("this.video.srcObject", that.video.srcObject)
           that.video.muted = false;
           that.video.volume = 1;
           // let Blob = this.recorder.getBlob()
           console.log("let ", that.blob)
           that.video.src = URL.createObjectURL(that.blob);
           that.recorder.camera.stop();
           //that.recorder.destroy();
           that.recorder = null;
           that.stopRecording = false
         }
       )
     },

     captureCamera(callback) {
       navigator.mediaDevices.getUserMedia({
         audio: { volume: { min: 0.0, max: 1.0 }, noiseSuppression: false, echoCancellation: false },
         video: { facingMode: "user" }
       }).then((camera) => {
         callback(camera);
       }).catch(function (error) {
         alert('Unable to capture your camera. Please check console logs.');
         console.error(error);
       });
     },

   }
 })
</script>
</body>

</html>

对了,有个小bug,最后一个问题是没有显示的,有语音播报,v-if判断有点问题,你们修改吧~我懒,哈哈哈哈,

如若又描述不清楚、代码不规范之处 ,请指出,

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章           查看所有文章
加:2021-07-28 16:33:51  更:2021-07-28 16:34:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 3:17:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码