Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基于RecordRTC的安卓端上传录像优化 #28

Open
SugarTeam opened this issue Jun 16, 2020 · 0 comments
Open

基于RecordRTC的安卓端上传录像优化 #28

SugarTeam opened this issue Jun 16, 2020 · 0 comments

Comments

@SugarTeam
Copy link
Contributor

在之前的项目中遇上移动端微信h5页面上传用户录像的功能需求,在简单使用input type=file的时候发现,ios录像上传会做自动压缩,而安卓端会直接上传录制的原视频,在用户不主动设置降低分辨率的情况下导致录像体积巨大,上传缓慢,体验及其不好,便有了这次的优化之旅。

在当下浏览器的飞速发展,可以看到getUserMedia这个获取媒体功能权限的API已经有了很好的兼容性,那么我们便从浏览器端主动调用摄像头功能入手。实时音视频通信的未来是WebRTC的天下,在安卓微信浏览器(X5内核)上兼容性很好,直接使用开源的RecordRTC JS封装,交互体验好,未来可以支持实时活体审核。

在这里先给大家安利一个控件recordrtc:https://github.com/muaz-khan/RecordRTC

目前这个组件集成了录像录音录屏多种功能,本文暂以录像的应用为例,欢迎大家试验和探讨研究。

首先,调用浏览器获取流媒体权限必不可少

const mediaConstraints = { audio: true, video: true }
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(this.successCallback)
.catch(this.errorCallback)

紧接着 succuess回调(successCallback(stream))中进行video标签与摄像头的相关绑定,同时初始化recordrtc,相关常见配置大家可以去查看下文档噢(这里碰上个小坑,一开始直接使用 new RecordRTC(stream),结果发现微信里面录的视频有相当的卡顿感,改用了MediaStreamRecorder,神秘优化点...)

let recordingPlayer = this.$refs.videoRecorder
recordingPlayer.poster = ''
recordingPlayer.srcObject = stream
recordingPlayer.play()
this.recordRTC = new MediaStreamRecorder(stream, options)

在这里需要处理下麦克风与video音频相冲导致回音的问题,给video加上volume/volumevalue=0,muted=true

开始与结束

this.recordRTC.record()
//结束按钮
this.recordRTC.stop(function (blob) {  
let random = parseInt(Math.random()*1000000)  
_this.fileName = `test${random}.mp4`  
_this.videoFile = new File([recordedBlob], _this.fileName, {
    type: 'video/mp4'  
})
_this.downloadUrl = URL.createObjectURL(_this.videoFile)
upload(_this.videoFile)
//在这里 我们可以选择生成下载地址or上传服务器返回视频地址,个人还是比较建议上传服务器处理,后面也有个小坑讲解}

好了,到这里看着基本完工,浏览器调试完美美滋滋,自然是要赶紧拿起手机试一下了完整流程了,录像功能完美,生成的文件是原来录像大小的几十分之一,一般需要的验证视频大约在20秒到1分钟之间,生成的视频只有小几M。嗯哼,就在这时,产品突然想到,视频拍完,还是有个预览的功能吧,嗯?重新播放居然没有声音,这也是个大问题了。排查过程中,检查过各种相关配置没有发现什么错误,这时候想到编码格式的问题,说到这里,就要安利另一个神奇工具: ffmpeg(相关安装流程就不在这里赘述了,相关文档很多)

通过 ffmpeg -i xxx文件解析得到

对比正常视频(iphone,安卓微信客户端),用ffmpeg -i 检查,发现音频流的差异就是压缩编码格式:正常的用aac,异常的用opus,查略相关资料发现微信浏览器针对这种编码还有兼容性问题,那么我们就考虑转换视频的编码模式,在接口收到文件后做一下编码转化,把音频编码由opus转成vorbis,简单语句如下

ffmpeg -i test387081.webm -acodec vorbis -ac 2 -strict -2 test387081_new.webm

再次测试,完美,声音出来了。

后记

到这里基本上完成了产品的需求了,但是,作为一个程序员,还是决定去多测试看别处的兼容性如何。Chrome完美支持毋庸置疑,但是在safari碰上了卡壳,查看控制台可以看到报错

查看源码发现录制视频是通过浏览器提供的MediaRecorder提供的,而safari并不支持,这里发现可以考虑结合WhammyRecorder和StereoAudioRecorder录制,然后通过ffmpeg合成视频音频,嗯,暂时是目前的设想设计,等待进一步实验验证,后续会做基于控件更多的应用分享,欢迎讨论与指正。

最后,用这样的形式有什么好处呢,除了针对视频大小和编码方面的优化自定义,还能更符合如录制验证身份等特殊使用场景,相信有更多待挖掘的地方。

补充

相关查阅资料

https://zhuanlan.zhihu.com/p/46903150

https://juejin.im/post/5b32fb5cf265da598223df9e

https://www.jianshu.com/p/a4bbedb239ae

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant