微信小程序web-view外部引用h5页面调用摄像头录制视频配有提示音(代码片段)

哎哟哟 哎哟哟     2022-11-29     535

关键词:

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判断有点问题,你们修改吧~我懒,哈哈哈哈,

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

微信小程序web-view外部引用h5页面调用摄像头录制视频配有提示音(代码片段)

微信小程序web-view外部引用h5页面调用摄像头录制视频配有提示音1、目前的需求是什么2、都踩了那些坑1、小程序2、h5语音提示3、语音合成声音录制不进去,ios有时候是麦克风,有时候是听筒发音!4、语音合成声音录... 查看详情

微信小程序web-view外部引用h5页面调用摄像头录制视频配有提示音(代码片段)

微信小程序web-view外部引用h5页面调用摄像头录制视频配有提示音1、目前的需求是什么2、都踩了那些坑1、小程序2、h5语音提示3、语音合成声音录制不进去,ios有时候是麦克风,有时候是听筒发音!4、语音合成声音录... 查看详情

微信小程序web-view,嵌入h5页面

...嵌入先有的小程序。2、并且要实现H5支付功能解决方式:web-view1、登陆小程序管理后台a.如果是公众号。则进行双向绑定完成这一步,那么基本上就差不多成功了一大半2、在小程序里面嵌入h5web-view文档里面有的东西,就不赘述le... 查看详情

微信小程序web-view,嵌入h5页面

...嵌入先有的小程序。2、并且要实现H5支付功能解决方式:web-view1、登陆小程序管理后台a.如果是公众号。则进行双向绑定完成这一步,那么基本上就差不多成功了一大半2、在小程序里面嵌入h5web-view文档里面有的东西,就不赘述le... 查看详情

微信小程序web-view组件嵌入h5页面导致双导航栏,如何只保留其中一个?(代码片段)

...已知存在一个微信小程序,该小程序的某个页面通过web-view组件嵌套了我们app的一个h5页面,h5页面本身有自己的导航栏,就导致了双导航栏。由于uniapp的web-view组件一定有原生导航栏,pages.js中设置navigationStyle:custo... 查看详情

微信小程序web-view环境下h5跳转小程序页面方法(代码片段)

web-view页面内的H5页面跳转至小程序页面一般的,web-view组件的src属性指定的H5页面之间,可以正常的采用超级链接a标记对进行页面之间的条转。但是web-view页面要想通过手指触碰返回小程序页面,就无法使用超级链接a... 查看详情

微信小程序和h5之间互相跳转互相传值(代码片段)

...代码基本都是vue)文章目录一、微信小程序跳转H51、web-view二、H5跳微信小程序1、H5直接跳到微信小程序2、内嵌H5跳转到微信小程序三、微信小程序传值给内嵌H51、路径传参四、内嵌H5传值给微信小程序1、用postMessage2、路径传... 查看详情

微信小程序封装h5使用web-view源码

参考技术A微信小程序封装H5域名使用微信小程序web-view组件进行封装H5网页,最快的速度完成展示型小程序。注:web-view组件不支持个人小程序,只能认证过的企业小程序。··· 查看详情

微信小程序web-view组件嵌入h5页面导致双导航栏,如何只保留其中一个?(代码片段)

...已知存在一个微信小程序,该小程序的某个页面通过web-view组件嵌套了我们app的一个h5页面,h5页面本身有自己的导航栏,就导致了双导航栏。由于uniapp的web-view组件一定有原生导航栏,pages.js中设置navigationStyle:custo... 查看详情

微信小程序web-view与h5通信方式探索(代码片段)

...等)小程序WebView基本用法定义:微信小程序组件Web-view定义:承载网页的容器用法<web-view class="web-holder" src="url" bindload="bindload" binderror="binderror" bindmessage="bindGetMsg">... 查看详情

微信小程序web-view页面无法显示

参考技术A众所周知微信的WebView有很强的缓存保护机制,当你第一次访问页面报错后就算修改了线上的H5页面再去访问也是照样空白怎么解决呢?其实很简单,WebView的缓存机制都是通过链接缓存的给链接后面加一个时间戳或者其他的... 查看详情

h5跨平台能力调研

...程序、今日头条小程序等)对H5页面的支持是通过提供<web-view/>组件的方式。<web-view/>组件是一个可以用来承载H5网页的组件,会自动铺满整个小程序页面。各平台能力比较 微信小程序支付宝小程序百度小程序今日头... 查看详情

微信小程序web-view无法打开该页面不支持打开(代码片段)

...小程序开发时遇到了一个问题我在正式上线版小程序使用web-view组件测试时提示:“无法打开该页面,不支持打开https://xxxxxx,请在“小程序右上角更多->反馈与投诉”中和开发者反馈。”奇怪的是,“真机调试... 查看详情

微信小程序h5页面缓存问题处理

参考技术A微信小程序会缓存H5页面,导致页面升级之后不能及时刷新。这种情况通过配置nginx不缓存静态页面无法影响到小程序缓存。假设H5请求地址是https://xxx/h5/用户进入小程序之后生成一个数字,请求H5时把数字拼接到URL后缀... 查看详情

h5就是页面吗,还是微信小程序?

...但感觉不太对。h5到底是什么,是纯页面html+css+js,还是微信小程序,或者是微信jssdk。h5就是html5的简称,现在h5还有一个含义,因为很多人不懂h5是什么东西,但是都知道哪些炫酷的邀请函,节日卡等等是用h5技术做出来的,然... 查看详情

在微信小程序中截屏(代码片段)

...在项目文件目录中更清晰一些。<template><view><web-view:src='hUrl'></view></template>web-view就是我们的html页面。小程序还没有上线时,我们用来测试,这时hUrl是html的本地路径,我这里是用vsCode的... 查看详情

微信小程序可不可以访问外部链接

之前微信小程序是不能添加外链的,不过昨天有一款微信官方开发的小程序可以点击进入H5页面了,按到微信一贯的套路,在过阵子这个功能应该会全面开放的。参考技术A小程序可以借助联合登录,和开发者已有的App后台的用户... 查看详情

小程序web-view内的h5页面,报风险提示如何解决

参考技术A小程序web-view内的H5页面,即使设置了小程序的业务域名,在点击输入框的时候也会报风险提示:防欺诈盗号,请勿支付或输入QQ密码。这个是需要你设置你域名所绑定公众号的业务域名。就是在你的公众号后台里面将... 查看详情