微信小程序web-view 外部引用h5页面调用摄像头录制视频 配有提示音
Posted 哎哟哟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序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判断有点问题,你们修改吧~我懒,哈哈哈哈,
如若又描述不清楚、代码不规范之处 ,请指出,
以上是关于微信小程序web-view 外部引用h5页面调用摄像头录制视频 配有提示音的主要内容,如果未能解决你的问题,请参考以下文章
微信小程序web-view 外部引用h5页面调用摄像头录制视频 配有提示音