Cordova插件cordova-plugin-media-capture實現短視頻的錄制上傳和播放

小編:管理員 406閱讀 2022.09.13

效果圖在這里插入圖片描述寫在前面(吐槽)

1、網上的教程大部分都是虎頭蛇尾的不全的;ハ喑瓉沓フ娴母杏X就沒有一個是真正自己去寫一寫的,不然這里面這么多的坑就沒有一個人出來說說的?下面就寫寫我實現功能過程中的一些問題吧,代碼絕對完整并且按照步驟來一定可以成功!

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-transfer
cordova 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、技術水平有限,但是每一行都是自己親歷親為實現的,權當做個記錄

關聯標簽:
亚洲国产欧美图片,亚洲aⅴ在线av,日韩亚洲综合图片视频,日本av精品在线中文