基於騰訊雲點播的視頻上傳和轉碼功能

  在以前的文章中提到過騰訊雲儲存上傳大文件的各類不方便,好比不能轉碼(要轉碼得先把mp4文件從雲存儲上下載下來,而後經過服務器執行ffmpeg操做,最後再把切割的ts文件上傳到騰訊雲,過程複雜且容易出錯),不能獲取實時的上傳進度等等,因此就發現騰訊雲點播這項技術。相對來講經過雲點播既能實現上傳進度的獲取,並且還能上傳完成後自動轉碼,好比自動把mp4轉換爲m3u8格式的清單文件來進行分片加載,這樣子既能大大加快加載速度,還能保護視頻連接的url,因此就記錄一下這種技術的使用原理。php

  雲點播視頻上傳Js端的sdk以下http://video.qcloud.com/sdk/upload.html,如今的官方sdk頁面作的比較挫,但願騰訊雲之後能改進,畢竟尋找一個方法還要點擊「查看網頁源代碼」讓人感受很方。css

  首先在html頭部引入雲點播的js,html

<script src="http://qzonestyle.gtimg.cn/open/qcloud/js/vod/sdk/uploaderh5.js" charset="utf-8"></script>

  而後在頁面寫上一個button由於雲點播是經過綁定一個button的方法來實現input type='file':web

<button class="btn btn-default" id="video">選擇文件</button>

  頁面長成這個樣子ajax

  

  接着在js裏定義一個初始化雲點播上傳條件的方法initUpload(),綁定後只要在頁面上拉取了文件,每隔1s騰訊服務器就會給你一個回調,你能夠根據回調裏不一樣的返回碼來寫上本身的處理方法。另外,當你在頁面選擇好一個文件後,js代碼會去計算其SHA值,在計算完後才能調用qcVideo.uploader.startUpload()進行上傳操做,不然會報錯。在上傳完成後雲點播會返回一個已上傳文件在騰訊服務器上的惟一標識args.serverFileId,其實現代碼以下:chrome

//初始化直播上傳
function initUpload() { //檢測瀏覽器是否支持
    var $ = qcVideo.get('$'); var Version = qcVideo.get('Version'); if( !qcVideo.uploader.supportBrowser() ) { if(Version.IS_MOBILE) { alert('當前瀏覽器不支持上傳,請升級系統版本或者下載最新的chrome瀏覽器'); } else { alert('當前瀏覽器不支持上傳,請升級瀏覽器或者下載最新的chrome瀏覽器'); } return; } //綁定按鈕及回調處理
    accountDone('video',‘你的雲點播secretId’,1,1,'你的轉碼成功後得回調url',null); } /** * * @param upBtnId 上傳按鈕ID * @param secretId 雲api secretId * @param isTranscode 是否轉碼 * @param isWatermark 是否設置水印 * @param [transcodeNotifyUrl] 轉碼成功後的回調 * @param [classId] 分類ID */
function accountDone(upBtnId,secretId, isTranscode, isWatermark,transcodeNotifyUrl,classId) { var $ = qcVideo.get('$'), ErrorCode = qcVideo.get('ErrorCode'), Log = qcVideo.get('Log'), JSON = qcVideo.get('JSON'), util = qcVideo.get('util'), Code = qcVideo.get('Code'), Version = qcVideo.get('Version'); qcVideo.uploader.init( { web_upload_url: 'http://vod.qcloud.com/v2/index.php', secretId: secretId, // 雲api secretId
 getSignature: function (argStr, done) {//注意:出於安全考慮, 服務端接收argStr這個參數後,須要校驗其中的Action參數是否爲 "MultipartUploadVodFile",用來證實該參數標識上傳請求
 $.ajax({ 'dataType': 'json', 'url': '你的簽名路徑' + encodeURIComponent(argStr), 'success': function (d) { done(d['result']); } }); }, upBtnId: upBtnId, //上傳按鈕ID(任意頁面元素ID)
            isTranscode: isTranscode,//是否轉碼
            isWatermark: isWatermark,//是否設置水印
            after_sha_start_upload: false,//sha計算完成後,開始上傳 (默認關閉當即上傳)
            sha1js_path: '/calculator_worker_sha1.js', //計算sha1的位置
            disable_multi_selection: false, //禁用多選 ,默認爲false
            transcodeNotifyUrl: transcodeNotifyUrl,//(轉碼成功後的回調地址)isTranscode==true,時開啓; 回調url的返回數據格式參考 http://www.qcloud.com/wiki/v2/MultipartUploadVodFile
 classId: classId, // mime_types, 默認是經常使用的視頻和音頻文件擴展名,如MP4, MKV, MP3等, video_only 默認爲false,可容許音頻文件上傳
            filters: {max_file_size: '8gb', mime_types: [], video_only: true} } //2: 回調
 , { /** * 更新文件狀態和進度 code:一、準備計算SHA 二、計算完SHA,準備上傳 三、SHA計算中 四、即將上傳 五、上傳進度更新 六、上傳完成 * @param args { id: 文件ID, size: 文件大小, name: 文件名稱, status: 狀態, percent: 進度 speed: 速度, errorCode: 錯誤碼,serverFileId: 後端文件ID } */ onFileUpdate: function (args) { if(args.code == 1 || args.code == 3)//計算SHA中
 { //你的邏輯,好比顯示文件名等信息 } else if(args.code == 2) //計算完SHA
 { //計算完SHA值,準備開始上傳,這步執行完以後才能執行qcVideo.uploader.startUpload()即上傳操做
  
}
elseif(args.code == 5 )//上傳中
{
//獲取實時進度
var percent=args.percent+'%';
$(
".progress-bar").css({'width':percent});
}
elseif(args.code == 6 )//上傳完成
{
$(
".progress-bar").css({'width':'100%'}); //取得回調的視頻serverFileId,用於後面更新字段用
var file_id=
args.serverFileId; console.log(params);
}
},

/** * 文件狀態發生變化,暫時不用 * @param info { done: 完成數量 , fail: 失敗數量 , sha: 計算SHA或者等待計算SHA中的數量 , wait: 等待上傳數量 , uploading: 上傳中的數量 } */
onFileStatus:
function (info)
{
$(
'#count').text('各狀態總數-->' + JSON.stringify(info));
},

/** * 上傳時錯誤文件過濾提示,暫時不用 * @param args {code:{-1: 文件類型異常,-2: 文件名異常} , message: 錯誤緣由 , solution: 解決方法} */
onFilterError:
function (args)
{
var msg = 'message:' + args.message + (args.solution ? (';solution==' + args.solution) : ''); console.log(msg);
}
} );
}

  在文件上傳完成後若是選擇了轉碼,騰訊雲點播會去對文件轉碼,並在成功後給你設置的回調url發請求,根據回調裏的$_POST['file_id']來更新DB爲轉碼完成便可。json

  js端說完了,如今來看php端,要經過後臺向雲點播發請求相對來講比較複雜,首先你要定義一個方法,方法可從官網上找到實例:後端

https://www.qcloud.com/doc/api/257/1976,簡易修改後方法以下:api

 

public function CreateRequest($HttpUrl, $HttpMethod, $COMMON_PARAMS, $secretKey, $PRIVATE_PARAMS, $isHttps) { $FullHttpUrl = $HttpUrl . "/v2/index.php"; /***************對請求參數 按參數名 作字典序升序排列,注意此排序區分大小寫*************/
        $ReqParaArray = array_merge($COMMON_PARAMS, $PRIVATE_PARAMS); ksort($ReqParaArray); /**********************************生成簽名原文********************************** * 將 請求方法, URI地址,及排序好的請求參數 按照下面格式 拼接在一塊兒, 生成簽名原文,此請求中的原文爲 * GETcvm.api.qcloud.com/v2/index.php?Action=DescribeInstances&Nonce=345122&Region=gz * &SecretId=AKIDz8krbsJ5yKBZQ ·1pn74WFkmLPx3gnPhESA&Timestamp=1408704141 * &instanceIds.0=qcvm12345&instanceIds.1=qcvm56789 * ****************************************************************************/
        $SigTxt = $HttpMethod . $FullHttpUrl . "?"; $isFirst = true; foreach ($ReqParaArray as $key => $value) { if (!$isFirst) { $SigTxt = $SigTxt . "&"; } $isFirst = false; /*拼接簽名原文時,若是參數名稱中攜帶_,須要替換成.*/
            if (strpos($key, '_')) { $key = str_replace('_', '.', $key); } $SigTxt = $SigTxt . $key . "=" . $value; } /*********************根據簽名原文字符串 $SigTxt,生成簽名 Signature******************/
        $Signature = base64_encode(hash_hmac('sha1', $SigTxt, $secretKey, true)); /***************拼接請求串,對於請求參數及簽名,須要進行urlencode編碼********************/
        $Req = "Signature=" . urlencode($Signature); foreach ($ReqParaArray as $key => $value) { $Req = $Req . "&" . $key . "=" . urlencode($value); } /*********************************發送請求********************************/
        if ($HttpMethod === 'GET') { if ($isHttps === true) { $Req = "https://" . $FullHttpUrl . "?" . $Req; } else { $Req = "http://" . $FullHttpUrl . "?" . $Req; } $Rsp = file_get_contents($Req); } // var_export(json_decode($Rsp,true)) ;
        return json_decode($Rsp, true); }

 

同時再寫一個通用的調用API的方法,把API的名稱以及參數傳過去便可:瀏覽器

 public function videoApi($action, $private_params) { /*DescribeInstances 接口的 URL地址爲 cvm.api.qcloud.com,可從對應的接口說明 「1.接口描述」 章節獲取該接口的地址*/
        $HttpUrl = "vod.api.qcloud.com"; /*除非有特殊說明,如MultipartUploadVodFile,其它接口都支持GET及POST*/
        $HttpMethod = "GET"; /*是否https協議,大部分接口都必須爲https,只有少部分接口除外(如MultipartUploadVodFile)*/
        $isHttps = true; /*須要填寫你的密鑰,可從 https://console.qcloud.com/capi 獲取 SecretId 及 $secretKey*/
        $secretKey = '你的SecretKey'; /*下面這五個參數爲全部接口的 公共參數;對於某些接口沒有地域概念,則不用傳遞Region(如DescribeDeals)*/
        $COMMON_PARAMS = array( 'Nonce' => rand(),
            'Timestamp' => time(NULL),
            'Action' => $action,
            'SecretId' => '你的secretId',
            'Region' => 'gz', ); /*下面這兩個參數爲 DescribeInstances 接口的私有參數,用於查詢特定的虛擬機列表*/
// $PRIVATE_PARAMS = array( // 'pullset.0.fileId'=> '14651978969383094681', // 'width'=>200, // 'height'=>200 // );

        $PRIVATE_PARAMS = $private_params; /***********************************************************************************/


        return $this->CreateRequest($HttpUrl, $HttpMethod, $COMMON_PARAMS, $secretKey, $PRIVATE_PARAMS, $isHttps); }

具體調用以下:

$getParams = array('fileId' => $fileId); $resultArray = $this->videoApi('DescribeVodPlayUrls', $getParams);

這樣就經過後臺發了一個請求,並把返回結果寫在$resultArray裏,最後再根據其返回值做本身須要的處理便可。

相關文章
相關標籤/搜索