背景:
之前项目中有个需求,需要在pc端的web页面做一套业务的开户流程,其中在开户流程中需要法人上传本人的开户视频(需要支持扫二维码在手机上录制视频上传)。pc端上传的功能比较好实现,但是扫二维码在手机上录制视频并且同步到pc页面的开户流程中就不太好做了。
一开始有想到两种方案:
a: 做一个h5的视频录制页面,然后生成链接的二维码,手机扫二维码进到h5页面录制视频。
- 优点:视频录制的时长可以控制
- 缺点:无法自定义视频拍摄的界面,只能使用相机原生的界面拍摄,可能还要适配各种机型
b: 在小程序的页面里录制视频,而且有现成的组件和api比较好实现
- 优点:视频拍摄的界面可以调整,比如在界面上添加展示文案,不需要再花精力去适配机型
- 缺点:录制时长比较短,目前有5分钟的时长限制
考虑到这个开户视频需要在录制界面上展示一段朗读的文字,h5可能暂时无法实现,刚好公司目前有一个微信小程序已经上线,所以最终选择了在小程序上开发一个录制视频的功能页面。
实现原理
要在微信小程序实现录制视频的功能要用到两个媒体组件camera和video,其中camera组件用来拍摄视频,video组件用来预览拍摄的视频。
camera
camera组件可以调用系统相机进行拍照或者视频录制,其中onCameraFrame 接口可以根据 属性frame-size 返回不同尺寸的原始帧数据,这个原始帧数据就是我们要拍摄的视频数据。
用法
html
<camera device-position="front" flash="off" binderror="error"></camera>
js
// 创建 camera 上下文 CameraContext 对象
const context = wx.createCameraContext()
// context.onCameraFrame()返回视频图像的监听器
const listener = context.onCameraFrame((frame) => {
// frame.data 就是视频数据 格式是ArrayBuffer
console.log(frame.data instanceof ArrayBuffer, frame.width, frame.height)
})
listener.start() // 开始监听帧数据
setTimeou(() => {
listener.start() // 停止监听帧数据
}, 10)
video
通过camera组件的api接口可以拿到实时的视频数据了,但是ArrayBuffer格式的数据是无法预览的。那要预览视频可以用video媒体组件,video组件中可以指定视频的src路径,即播放视频的资源地址,但是只支持网络路径、本地临时路径、云文件ID这些选项。
所以要播放录制的视频还需要拿到视频的本地临时路径,那怎么拿到呢,需要结合下面两个api
开始录像CameraContext.startRecord,可以设置视频的时长
结束录像CameraContext.stopRecord,通过成功的回调函数拿到视频的临时路径
官方给出的使用例子
<view class="page-body">
<view class="page-body-wrapper">
<camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
<view class="btn-area">
<button type="primary" bindtap="startRecord">开始录像</button>
</view>
<view class="btn-area">
<button type="primary" bindtap="stopRecord">结束录像</button>
</view>
<view class="preview-tips">预览</view>
<video