阿里雲移動端播放器高級功能---視頻下載

基本介紹

優酷、愛奇藝、騰訊等主流的視頻類App都有視頻離線下載的功能,主要目的是在wifi下將視頻離線在本地,然後在無網或者4G的情況下去觀看離線視頻。那麼阿里雲播放器也提供了視頻下載的功能。這個功能主要針對的是點播視頻,也就是vid播放的視頻的下載。

主要問題

  1. m3u8如何下載?我們知道m3u8是一個索引文件,真正的視頻文件是各個ts的分片,那麼如何下載成一個完成的視頻呢?

  2. 如何對視頻下載進行多線程控制?在一些app中,多個視頻同時下載被認爲是高級VIP纔有的功能。

  3. 如何實現斷點續傳?當在下載過程中突然中斷了,那麼下次再啓動的時候要能夠實現續傳。

  4. 下載過程中sts等信息過期怎麼處理?

  5. 加密的視頻下載到本地如何保障安全性呢?

實現原理

下載過程

阿里雲播放器支持mp4文件和m3u8視頻文件兩種格式下載。其下載過程基本一致。流程圖如下:


從上述流程圖中可以看到,m3u8文件的下載我們會mux成一個mp4文件,首先將各個ts文件分別下載,最後的過程中再進行mux。

多線程控制

/*
 功能:設置同時下載的數量,最大4個
 參數:count:同時下載的個數
 */
-(void)setMaxDownloadOperationCount:(int)count;

通過上述的接口,可以設置並行下載的個數。當添加到隊列中的數量多於這個設定的個數後,會在隊列中進行等待,當之前的下載完成後會自動進行下一個視頻的下載。

異常中斷

經常有的情況是:不小心將app殺掉了,或者手機沒電關機了等其他中斷的因素。這個時候下次下載的時候要能夠恢復之前的現場。我們提供了一個回調來通知app:

/*
 功能:未完成回調,異常中斷導致下載未完成,下次啓動後會接收到此回調。
 回調數據:AliyunDownloadMediaInfo數組
 */
-(void) onUnFinished:(NSArray<AliyunDataSource*>*)mediaInfos;

過期處理

通過vid的方式進行下載,同樣支持vid+playAuth,vid+sts,vid+mps的方式進行播放,將這些信息添加到隊列中,如果之前一個視頻下載時間較長,那麼後面排隊的視頻的輸入信息可能會過期。針對這種情況,我們增加了過期的回調來重新輸入信息:

/*
  功能:開始下載後收到回調,更新最新的playAuth。主要場景是開始多個下載時,等待下載的任務自動開始下載後,playAuth有可能已經過期了,需通過此回調更新
 參數:返回當前數據
 返回:使用代理方法,設置playauth來更新數據。
 備註:如通過請求數據來獲取playAuth,請使用同步方法。此代理方法在其他線程裏,不會存在卡線程問題。
  */
-(NSString*)onGetPlayAuth:(NSString*)vid format:(NSString*)format quality:(AliyunVodPlayerVideoQuality)quality;


/*
  功能:開始下載後收到回調,更新最新的stsData。主要場景是開始多個下載時,等待下載的任務自動開始下載後,stsData有可能已經過期了,需通過此回調更新
 參數:返回當前數據
 返回:使用代理方法,設置AliyunStsData來更新數據。
 備註:如通過請求數據來獲取stsData,請使用同步方法。此代理方法在其他線程裏,不會存在卡線程問題。
 */
- (AliyunStsData*)onGetAliyunStsData:(NSString *)videoID
                              format:(NSString*)format
                             quality:(AliyunVodPlayerVideoQuality)quality;

/*
  功能:開始下載後收到回調,更新最新的MtsData。主要場景是開始多個下載時,等待下載的任務自動開始下載後,MtsData有可能已經過期了,需通過此回調更新
 參數:返回當前數據
 返回:使用代理方法,設置AliyunMtsData來更新數據。
 備註:如通過請求數據來獲取mtsData,請使用同步方法。此代理方法在其他線程裏,不會存在卡線程問題。
 */
- (AliyunMtsData*)onGetAliyunMtsData:(NSString *)videoID
                              format:(NSString*)format
                             quality:(NSString *)quality;

加密下載

加密下載到本地,如何保證安全呢?有幾個問題就是下載後我們需要重新加密,防止密鑰泄露。同時另外一個就是要防止視頻被拷貝到其他app中進行播放。比如存在下面的場景。


所以我們通過將用戶密鑰和用戶app綁定的方式來保證安全性。
那麼如何來做呢?

控制檯配置

如果希望實現加密下載,需要在阿里雲控制檯配置下載選項爲安全下載。同時,填寫校驗及加密相關信息。截圖如下:


填寫完成之後,控制檯將會生成一個dat校驗文件。這個校驗文件需要配置到阿里雲下載模塊中,供校驗使用。

使用dat文件

有了dat文件後,我們將文件設置到播放器中,通過如下接口:

/*
  功能:設置加密文件
  參數:encrptyFile爲加密文件路徑
  */
-(void)setEncrptyFile:(NSString*)encrptyFile;

下載功能示例

以Android爲例,Android 提供了AliyunDownloadManager這個單例類實現下載功能。

配置AliyunDownloadConfig

下載之前,需要配置AliyunDownloadConfig。AliyunDownloadConfig中需要配置如下幾個參數:

  • setMaxNums: 設置最大同時下載的個數。

  • setDownloadDir: 設置下載的文件保存的位置。

  • setSecretImagePath: 設置校驗文件的路徑。 其中:setSecretImagePath只需要在加密下載的時候設置。其餘兩個參數均需要設置。

獲取視頻信息並下載

阿里雲播放器支持 STS ,AUTH,MPS 等多種方式下載。以STS舉例。
1. 通過sts信息,調用prepare接口,獲取可以下載的視頻項:

//1.設置下載監聽
  downloadManager = AliyunDownloadManager.getInstance(getContext());
  downloadInfoListener = new MyDownloadInfoListener(this);
  downloadManager.addDownloadInfoListener(downloadInfoListener);
  //2.使用vidsts準備下載資源。
   AliyunVidSts adb = new AliyunVidSts();
        adb.setVid(mVid);
        adb.setAcId(akid);
        adb.setAkSceret(akSecret);
        adb.setSecurityToken(token);
        downloadManager.prepareDownloadMedia(adb);
  1. prepare成功後,添加某一項到AliyunDownloadManager中,並開始下載:

@Override
  void onPrepared(List<AliyunDownloadMediaInfo> infos) {
        //準備結束
        downloadManager.addDownloadMedia(infos.get(0));
        downloadManager.startDownloadMedia(info);
    }
  1. 接受下載回調,更新界面:

@Override
        public void onPrepared(List<AliyunDownloadMediaInfo> infos) {
          //準備完成
        }

        @Override
        public void onStart(AliyunDownloadMediaInfo info) {
          //下載開始
        }

        @Override
        public void onProgress(AliyunDownloadMediaInfo info, int percent) {
            //下載進度
        }

        @Override
        public void onStop(AliyunDownloadMediaInfo info) {
          //下載停止
        }

        @Override
        public void onCompletion(AliyunDownloadMediaInfo info) {
            DemoDownloadActivity downloadActivity = weakActivity.get();
            if (downloadActivity != null) {
                downloadActivity.onCompletion(info);
            }
        }

        @Override
        public void onError(AliyunDownloadMediaInfo info, int code, String msg, String reuqestId) {
            //下載出錯
        }

        @Override
        public void onWait(AliyunDownloadMediaInfo outMediaInfo) {
            //等待下載
        }

移除下載項

AliyunDownloadManager提供了移除接口,用來從下載管理中移除下載。移除之後,下載的文件將也會被刪除。

downloadManager.removeDownloadMedia(info);

原文鏈接

本文爲雲棲社區原創內容,未經允許不得轉載。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章