Cordova插件cordova-plugin-media-capture实现短视频的录制上传和播放
小编:管理员 778阅读 2022.09.13
1、网上的教程大部分都是虎头蛇尾的不全的。互相抄来抄去真的感觉就没有一个是真正自己去写一写的,不然这里面这么多的坑就没有一个人出来说说的?下面就写写我实现功能过程中的一些问题吧,代码绝对完整并且按照步骤来一定可以成功!
2、本文主要讲在Android中的实现,IOS端目前还在适配,不少问题到时候再另外单独发一篇
实现逻辑1、客户端利用cordova-plugin-media-capture插件调用摄像机权限进行视频拍摄
2、拍摄的视频上传至服务器
3、服务端接收视频文件并转码保存删除源文件,将保存链接返回给客户端
4、客户端接收链接利用vedio插件进行显示播放
实现步骤安装cordova-plugin-media-capture插件这个没啥可说的直接上代码:
cordova plugin add cordova-plugin-media-capture复制客户端调用摄像头拍摄视频
实现的过程中第一个坑出现了,就是cordova这个插件方法navigator.device.capture.captureVideo正如网上大部分教程一样,确实能很顺利的调起摄像头进行拍摄,但是拍摄完之后总是显示失败的!原因是这个插件是需要获取手机存储权限的!然而偏偏这个插件就是没有先去获取这个存储权限!必须要自己写代码去获取权限!我就不信那些教程能不获取权限直接调用摄像头拍摄成功?要么就是他们在app中其他地方已经获取过存储权限了!比如调用图库的这个插件就会弹窗提示给权限!然后这个插件并不会,这是第一个坑!
调用方法前手动获取手机权限首先要安装权限的插件cordova-plugin-android-permissions
cordova plugin add cordova-plugin-android-permissions复制
查看客户端是否有存储权限如果没有就申请获取存储权限
//申请存储权限 var permissions = cordova.plugins.permissions; permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE, successCallback, errorCallback) var successCallback = function(s){} var errorCallback = function(r){ alert("申请权限失败请重试"); }复制调用相机进行短视频拍摄
var options = { limit: 1, duration: 10, quality: 1 }; navigator.device.capture.captureVideo(this.onSuccess, this.onError, options);复制
1、这里对参数options进行一下说明
limit:拍摄视频的数量
duration:拍摄视频的时长(单位:s)
quality:拍摄视频的质量(0:低质量 1高质量)
这里遇到了第二个坑,其实也跟Cordova官方有关,毕竟比较冷门的插件,也情有可原。但是我始终觉得比Hbuild的那个一套代码走天下(小程序,Android,ios)好用的多
这里视频拍摄我们完全不能自定义拍摄的画质,官方只给了你两个选择,0低画质,这个低画质是真的低,低到就是你完全没办法看,所以拍摄质量其实就一个选项没得选择,那就是1高画质,搞到什么程度呢?部分手机拍摄出来的居然是4K视频!!这个坑就是高画质哪怕仅仅拍摄一两秒的视频都会有好几M大,一个是上传下载的时候服务器带宽压力,还有一个是这种极度高画质的视频在获取到链接放vedio渲染到前端显示的时候基本就是1s的视频都会卡顿,哪怕你的服务器是10M的带宽也是如此,那么这个坑就直接导致了需要多进行一个步骤---服务端转码保存
所以要么就是弃用这个插件用别的办法实现,要么就是硬着头皮直接来!所以没得选择!quality必须只能选择高画质了
2、在this.onSuccess成功回调方法中我们就可以获取到视频在客户端的保存路径了
onFail(message) { //取消照相功能提示 }, onSuccess(mediaFiles) { var _this = this var i, len; for (i = 0, len = mediaFiles.length; i < len; i += 1) { _this.path = mediaFiles[i].fullPath; _this.filename = mediaFiles[i].name; } },复制
this.path就是我们需要的路径
利用文件上传插件讲拍摄的视频上传至服务器安装cordova-plugin-file-transfercordova plugin add cordova-plugin-file-transfer复制上传文件至服务器
上传方法
//fileURL就是上面步骤中文件的路径this.path upload(fileURL) { var options = new FileUploadOptions(); options.fileKey = "file1"; options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1); var params = {}; params.value1 = "test"; params.value2 = "param"; options.params = params; var ft = new FileTransfer(); //上传地址:下面步骤我会讲服务器接收文件的方法的 var SERVER = "填写自己后台的服务API地址"; ft.upload(fileURL, encodeURI(SERVER), success, fail, options); }复制
服务端接收文件的方法在下面步骤中有先别着急
success成功回调中会返回文件在服务器保存的url的
//上传成功 var success = function (r) { var strs = JSON.parse(r.response); // alert("上传成功! Code = " + JSON.parse(r.response).data.vedioShowUrl); _this.show = true; _this.uploadFlag = false; _this.playerOptions.sources[0].src = JSON.parse(r.response).data.vedioShowUrl; _this.saveVedioUrl = JSON.parse(r.response).data.saveVedioUrl; }复制
saveVedioUrl就是服务端返回的url
服务端接收视频文件并转码保存,返回URL给客户端接收视频文件move_uploaded_file($_FILES["file1"]["tmp_name"],$_SERVER["DOCUMENT_ROOT"]."/Public/vedios/" . $_FILES["file1"]["name"]); $ofile = $_SERVER["DOCUMENT_ROOT"]."/Public/vedios/" . $_FILES["file1"]["name"];复制
文件保存在服务器的路径是$_SERVER["DOCUMENT_ROOT"]."/Public/vedios/" . $_FILES["file1"]["name"];
转码1、转码我们需要使用ffmpeg来实现(本人服务器centos nginx)
这里第三个坑出现了,网上一堆的教程关于安装ffmpeg大部分都是瞎写的,全是纸上谈兵压根就是自己没有去写一写的,所以千万不要随便找一个教程就去安装,后面卸载可是个十分麻烦的事情
这里贴出来了一个用心写代码的兄弟的链接,非常好,链接上面已经贴出来了,再次非常感谢这位兄弟的教程,按照他的步骤一步步走就能成功安装了
在这里插入图片描述2、接下来我们就是利用ffmpeg命令进行转码操作了
转码命令:
ffmpeg -y -i 需要转码的文件路径 -s 720x960 -b:v 562k -c:v libx264 转码成功后文件的保存路径复制
经过此步骤之后转码后的文件就只有几百K了,视频的质量也还可以
直接贴代码:
//设置转码后的文件路径(避免重复命令我们加一个时间戳随机数) $randnum = date('His').str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); $nfile = $_SERVER["DOCUMENT_ROOT"]."/Public/vedios/" . $randnum .$_FILES["file1"]["name"]; $nfile2 = "/Public/vedios/" . $randnum .$_FILES["file1"]["name"]; //exec函数执行ffmpeg终端转码命令 $str = "ffmpeg -y -i ". $ofile. " -s 720x960 -b:v 562k -c:v libx264 " . $nfile; exec("$str", $output,$status);//$status为0即表示转码成功 //unlink($ofile)方法删除源文件 if(!$status && unlink($ofile)){ $VedioStr = C('URL').$nfile2; $VedioUrl = $nfile2; $vedioData = array( 'vedioShowUrl'=>$VedioStr, 'saveVedioUrl'=>$VedioUrl ); $this->res['code'] = 200; $this->res['msg'] = '上传转码成功'; $this->res['data'] = $vedioData; $this->response($this->res,'json'); }else{ $this->res['code'] = 101; $this->res['msg'] = '转码错误请重试!'; $this->res['data'] = $output; $this->response($this->res,'json'); }复制客户端拿到返回的视频URL利用vedio插件进行显示安装vue-video-player插件
1、vue项目中执行:
npm install vue-video-player --save复制
2、在main.js入口文件中引入:
import VideoPlayer from 'vue-video-player' require('video.js/dist/video-js.css') require('vue-video-player/src/custom-theme.css') Vue.use(VideoPlayer)复制
3、在使用的页面中引用:
import { videoPlayer } from 'vue-video-player' import 'video.js/dist/video-js.css'复制
4、构建播放器容器:
复制
options参数:
playerOptions: { controls:false, autoplay: false, // 如果为true,浏览器准备好时开始回放。 muted: false, // 默认情况下将会消除任何音频。 loop: false, // 是否视频一结束就重新开始。 preload: 'auto', // 建议浏览器在复制修改播放器默认样式实现点击屏幕暂停和播放
这里默认的播放器样式很丑的,我们需要自定义样式实现点击视频屏幕播放和暂停功能
贴出来自定义的css
/*播放按钮设置成宽高一致,圆形,居中*/ .vjs-custom-skin > .video-js .vjs-big-play-button { background: url("../../assets/img/pause.png"); background-color: rgba(255, 255, 255, 0.4); margin-left: -1em !important; width: 2em !important; background-size: cover; border: none; width: 100px; height: 100px; } .video-js .vjs-big-play-button .vjs-icon-placeholder:before { position: absolute; left: 0; width: 100%; height: 100%; } /* 去掉中间的播放箭头 */ .vjs-big-play-button .vjs-icon-placeholder { font-size: 0em; } /* 加载圆圈 */ .vjs-loading-spinner { font-size: 2.5em; width: 2em; height: 2em; border-radius: 1em; margin-top: -1em; margin-left: -1.5em; } /*control-bar布局时flex,通过order调整剩余时间的位置到进度条右边*/ .vjs-custom-skin > .video-js .vjs-control-bar .vjs-remaining-time{ order:3 !important; } /*进度条背景轨道*/ .video-js .vjs-slider{ border-radius: 1em; } /*进度条进度*/ .vjs-custom-skin > .video-js .vjs-play-progress, .vjs-custom-skin > .video-js .vjs-volume-level{ border-radius: 1em; } /*鼠标进入播放器后,播放按钮颜色会变*/ .video-js:hover .vjs-big-play-button, .vjs-custom-skin>.video-js .vjs-big-play-button:active, .vjs-custom-skin>.video-js .vjs-big-play-button:focus{ background-color: rgba(0,0,0,0.4) !important; } /*control bar*/ .video-js .vjs-control-bar{ background-color: rgba(0,0,0,0.2) !important; } /*点击按钮时不显示蓝色边框*/ .video-js .vjs-control-bar button{ outline: none; }复制
在上面步骤的main.js文件中引入我们刚刚创建的自定义css
import './assets/css/vediocommon.css'复制
js方法
@pause="onPlayerPause($event)"@play="onPlayerPlay($event)"@ended="onPlayerEnded($event)" onPlayerClick
onPlayerPause($event) { this.isPlay = false; }, onPlayerPlay($event) { this.isPlay = true; }, onPlayerEnded($event) {}, onPlayerClick() { if (this.isPlay) { this.player.pause(); } else { this.player.play(); } },复制源码文件
由于项目中很多地方可能涉及到引用的本地的一些icon文件导致你们复制粘贴后不能正常运行,所以将此视频上传封装成了一个组件方便大家在项目中直接引用
总结(永远记得做一个有灵魂的人)1、一部分人写CSDN是为了自己记个笔记所以别人看不懂正常,可以理解
2、复制粘贴纸上谈兵别人的东西就没有什么意思了
3、技术水平有限,但是每一行都是自己亲历亲为实现的,权当做个记录
相关推荐
- Cordova 什么是Cordova? Cordova是用于使用HTML,CSS和JS构建移动应用的平台。我们可以认为Cordova是一个容器,用于将我们的网络应用程序与本机移动功能连接。默认情况下,Web应用程序不能使用本机移动功能。这就是Cordova进来的地方。它为网络应用和移动设备之间的连…
- 3DMAX提示和技巧 本主题标识使用 Civil View 的一些重要提示和技巧。常规使用屏幕分辨率至少为 1280x1024 的 Civil View。低于此分辨率时,一些面板将占用过多屏幕空间。 将视口设置为线框显示以达到最佳性能。 要尽可能简化用户界面,请在单个视口中工作并关闭 3ds Max 命令面…