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


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

  雲點播視頻上傳Js端的sdk如下http://video.qcloud.com/sdk/upload.html,現在的官方sdk頁面做的比較挫,希望騰訊雲以后能改進,畢竟尋找一個方法還要點擊“查看網頁源代碼”讓人感覺很方。

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

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

  然后在頁面寫上一個button因為雲點播是通過綁定一個button的方法來實現input type='file':

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

  頁面長成這個樣子

  

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

//初始化直播上傳
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:1、准備計算SHA 2、計算完SHA,准備上傳 3、SHA計算中 4、即將上傳 5、上傳進度更新 6、上傳完成 * @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為轉碼完成即可。

  js端說完了,現在來看php端,要通過后台向雲點播發請求相對來說比較復雜,首先你要定義一個方法,方法可從官網上找到實例:

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

 

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里,最后再根據其返回值作自己需要的處理即可。

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM