全部產品
Search
文件中心

ApsaraVideo VOD:進階功能

更新時間:Jul 13, 2024

本文介紹Android播放器SDK進階功能的使用樣本,更多功能的支援和使用請參見API說明

播放

短視頻列表播放

針對典型的短視頻列表播放情境,Android播放器SDK提供了完善的列表播放功能,結合預先載入等機制大幅改善短視頻的起播速度。長視頻情境不建議使用該功能。

使用限制

AliListPlayer存在以下限制,推薦使用多個AliPlayer的方式來實現短視頻列表播放,詳細內容請參見沈浸式短視頻

  • AliListPlayer不支援多執行個體,要保持全域單一實例,使用多個AliListPlayer會出現視頻源混亂的問題。

  • 5.4.5.0以前版本的Android播放器SDK中,AliListPlayer不支援m3u8格式的視頻;5.4.5.0及以後版本的Android播放器SDK才支援m3u8格式的視頻(需要開啟本機快取功能)。

操作步驟

  1. 建立播放器。

    通過AliPlayerFactory類建立AliListPlayer播放器。樣本如下:

    AliListPlayer aliyunListPlayer;
    .....
    aliyunListPlayer = AliPlayerFactory.createAliListPlayer(getApplicationContext());
    aliyunListPlayer.setTraceId("traceId");  //traceId為裝置或使用者的唯一識別碼,通常為imei或idfa

  2. 可選:設定監聽器。

    建立列表播放時,監聽器為非必須配置,但如果不設定,將無法收到播放器的播放失敗、播放進度等事件通知,因此,建議您設定。其中OnPreparedListenerOnErrorListenerOnCompletionListenerOnLoadingStatusListenerOnInfoListener較為重要,建議您設定。

    展開查看代碼

    aliyunListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            //播放完成事件
        }
    });
    aliyunListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            //出錯事件
        }
    });
    aliyunListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            //準備成功事件
        }
    });
    aliyunListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            //視頻解析度變化回調
        }
    });
    aliyunListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            //首幀渲染顯示事件
        }
    });
    aliyunListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            //其他資訊的事件,type包括了:迴圈播放開始,緩衝位置,當前播放位置,自動播放開始等
        }
    });
    aliyunListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            //緩衝開始。
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            //緩衝進度
        }
        @Override
        public void onLoadingEnd() {
            //緩衝結束
        }
    });
    aliyunListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            //拖動結束
        }
    });
    aliyunListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleShow(long id, String data) {
            //顯示字幕
        }
        @Override
        public void onSubtitleHide(long id) {
            //隱藏字幕
        }
    });
    aliyunListPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
        @Override
        public void onChangedSuccess(TrackInfo trackInfo) {
            //切換音視頻流或者清晰度成功
        }
        @Override
        public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
            //切換音視頻流或者清晰度失敗
        }
    });
    aliyunListPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
        @Override
        public void onStateChanged(int newState) {
            //播放器狀態改變事件
        }
    });
    aliyunListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            //截圖事件
        }
    });
  3. 設定預先載入個數。

    合理設定預先載入個數,能夠有效提高起播的速度。樣本如下:

    //設定預先載入個數。總共載入的個數為: 1 + count*2。
    aliyunListPlayer.setPreloadCount(int count);
  4. 添加或移除多個播放源。

    列表播放支援兩種播放源:Vid播放(包括VidSts及VidPlayAuth)和UrlSource播放。Url為視頻的播放地址。樣本如下

    • Url:播放地址可以是第三方點播地址或阿里雲點播服務中的播放地址。阿里雲播放地址可以調用擷取音視頻播放地址介面擷取。建議您整合點播服務端SDK來擷取音視頻播放地址,免去自簽名的麻煩。調用介面擷取音視頻播放地址的樣本請參見開發人員門戶

    • Vid:音視頻ID,可以在音視頻上傳完成後通過控制台(路徑:媒資庫 > 音/視頻。)或服務端介面(搜尋媒體資訊)擷取。

    //添加Vid播放源
    aliyunListPlayer.addVid(String videoId, String uid);
    //添加UrlSource播放源
    aliyunListPlayer.addUrl(String url, String uid);
    //移除某個源
    aliyunListPlayer.removeSource(String uid);
    說明

    uid是視頻的唯一標誌。用於區分視頻是否一樣。如果uid一樣,則認為視頻是一樣的。如果播放出現串流的情況,請注意查看是不是在不同的介面設定了同一個uid。uid沒有格式限制,可以是任意的字串。

  5. 設定顯示View。

    播放器支援SurfaceView和TextureView,任選其中一種即可。

    • 設定SurfaceView,樣本如下:

      展開查看代碼

      SurfaceView surfaceView = findViewById(R.id.surface_view);
      surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
              aliyunListPlayer.setSurface(holder.getSurface());
          }
      
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
              aliyunListPlayer.surfaceChanged();
          }
      
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
              aliyunListPlayer.setSurface(null);
          }
      });
    • 設定TextureView,樣本如下:

      展開查看代碼

      TextureView textureView = findViewById(R.id.texture_view);
      textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
          @Override
          public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
              aliyunListPlayer.setSurface(new Surface(surface));
          }
      
          @Override
          public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
              aliyunListPlayer.surfaceChanged();
          }
      
          @Override
          public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
              aliyunListPlayer.setSurface(null);
              return false;
          }
      
          @Override
          public void onSurfaceTextureUpdated(SurfaceTexture surface) {
      
          }
      });
  6. 播放視頻源。

    添加了一個或多個播放源之後並設定自動播放,調用moveTo便可以自動播放某個視頻源。樣本如下:

    展開查看代碼

    //開啟自動播放
    aliyunListPlayer.setAutoPlay(true);
    
    //url時使用此介面
    aliyunVodPlayer.moveTo(String uid);
    //vid的時候使用此介面,需要傳遞stsInfo即STS臨時憑證和臨時AK對,需要提前擷取,擷取方式請參見建立RAM角色並進行STS臨時授權。
    aliyunVodPlayer.moveTo(String uid, StsInfo info);
    //vid的時候使用此介面,需要傳遞PlayAuthInfo,在此之前要針對每個視頻擷取PlayAuth資訊。
    aliyunVodPlayer.moveTo(String uid, PlayAuthInfo info);
  7. 播放上一個、下一個視頻。

    • 調用moveTo播放某個視頻源後,調用moveToPrevmoveToNext介面以moveTo的視頻源為錨點進行播放上一個,下一個視頻。樣本如下:

      說明

      在基於同一個view的情況下,調用moveto或者moveToNext等切換視訊源操作時,會出現閃爍黑屏的情況。此時建議在listPlayer初始化時,配置PlayerConfigmClearFrameWhenStop欄位為false,並調用setConfig使其生效。

      展開查看代碼

      //開啟自動播放
      aliyunListPlayer.setAutoPlay(true);
      
      //移動到下一個視頻。 注意:只能用於url的源。這個方法不適用於vid的播放。
      aliyunVodPlayer.moveToNext();
      //移動到上一個視頻。注意:只能用於url的源。這個方法不適用於vid的播放。
      aliyunVodPlayer.moveToPrev();
      //移動到下一個視頻。注意:只能用於vid的播放。
      aliyunVodPlayer.moveToNext(StsInfo info);
      // 移動到上一個視頻。注意:只能用於vid的播放。
      aliyunVodPlayer.moveToPrev(StsInfo info);
      //移動到下一個視頻。注意:只能用於vid且使用PlayAuth的播放。
      aliyunVodPlayer.moveToNext(PlayAuthInfo info);
      // 移動到上一個視頻。注意:只能用於vid且使用PlayAuth的播放。
      aliyunVodPlayer.moveToPrev(PlayAuthInfo info);
    • 根據vid申請PlayAuth資訊,申請成功後再進行MoveTo或MoveToNext等。

      說明

      只有VidPlayAuth播放才需要根據vid申請PlayAuth資訊。

      展開查看代碼

      requestAuth(source.getVideoId(), new OnRequestAuthResultListener() {
          @Override
          public void onResult(VidAuth vidAuth) {
              mVideoListPlayer.moveToNext(createVidAuth(vidAuth));
          }
      });
      
      private PlayAuthInfo createVidAuth(VidAuth vidAuth) {
          if (vidAuth == null) {
              return new PlayAuthInfo();
          }
          PlayAuthInfo playAuthInfo = new PlayAuthInfo();
          playAuthInfo.setPlayAuth(vidAuth.getPlayAuth());
          return playAuthInfo;
      }
  8. 可選:使用預渲染執行個體提升視頻切換的順暢度。

    說明

    Android播放器SDK 5.5.2.0及以上版本才支援本功能,並且需要開啟本機快取,開啟方法請參見本機快取

    Android播放器SDK從5.5.2.0版本開始提供getPreRenderPlayermoveToNextWithPrerendered介面,用於提升滑動切換到下一個視頻播放時的順暢度,根據您的SDK整合情境不同,其使用方法有所差異,具體如下:

    全新整合5.5.2.0及以後版本

    使用PreRenderPlayer來實現。範例程式碼如下:

    展開查看代碼

    //preRenderPlayer只能在moveToNext時使用,並且需要開啟本機快取。
    IPlayer preRenderPlayer = listPlayer.getPreRenderPlayer();
    if (preRenderPlayer != null) {
        //設定surface
        preRenderPlayer.setSurface(surface);
      preRenderPlayer.start();
      listPlayer.setSurface(null);
      //STS播放方式,將moveToNext介面替換成moveToNextWithPrerendered
      listPlayer.moveToNextWithPrerendered(createStsInfo(source));
    }

    從低版本升級至5.5.2.0及以後版本

    您需要修改低版本SDK的代碼實現,具體如下:

    1. 修改渲染View。

      低版本的Android播放器SDK全域使用一個渲染View,在每次切換播放源時,先從布局中remove前一個View,再添加下一個View到當前介面上。從5.5.2.0版本開始,支援使用多個渲染View,在RecyclerView.ViewHolder的布局中添加多個View,在切換播放源時,可以預先載入下一個播放源,以提升切換的順暢度。您需要刪除低版本的渲染View的代碼,並添加新版本添加多個渲染View的代碼,範例程式碼如下:

      展開查看代碼

      /*
      刪除如下代碼
          如下幾行代碼為低版本添加渲染View的代碼。會將渲染View添加到FrameLayout中,然後在切換播放源時,會將mPlayerViewContainer移除、添加。
      */
      private void initPlayer() {
          //...
          mPlayerViewContainer = View.inflate(getContext(), R.layout.layout_player_view, null);
          FrameLayout frameLayout = mPlayerViewContainer.findViewById(R.id.framelayout);
          FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
          FrameLayout.LayoutParams.MATCH_PARENT);
          View renderView = createRenderView(Common.RENDER_VIEW_NAME);
          frameLayout.addView(renderView, 0, params);
          //...
      }
      
      /*
      添加或修改如下代碼以添加多個渲染View
          修改RecyclerView的item布局,以及對應的ViewHolder
      */
      
      public final class MyHolder extends RecyclerView.ViewHolder {
          //...
          private Surface mSurface;
          MyHolder(@NonNull View itemView) {
              super(itemView);
              //...
              TextureView mTextureView = itemView.findViewById(R.id.texture_view);
              mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                  @Override
                  public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                      mSurface = new Surface(surface);
                  }
      
                  @Override
                  public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
      
                  @Override
                  public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                      mSurface = null;
                      return false;
                  }
      
                  @Override
                  public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
              });
          }
          //...
      
          //對外呈現擷取Surface的介面
          public Surface getSurface() {
              return mSurface;
          }
      }

      修改RecyclerView中的item布局的範例程式碼如下:

      展開查看代碼

      <?xml version="1.0" encoding="utf-8"?>
      <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:id="@+id/root_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@android:color/black">
      
          <TextureView
              android:id="@+id/texture_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
      <!-- 刪除封面圖片,如果效果不好,可以保留封面圖片的相關邏輯。 -->
      <!--    <FrameLayout-->
      <!--        android:id="@+id/player_view"-->
      <!--        android:layout_width="match_parent"-->
      <!--        android:layout_height="match_parent"-->
      <!--        android:clickable="false"-->
      <!--        android:clipChildren="false"-->
      <!--        android:focusable="false">-->
      
      <!--        <ImageView-->
      <!--            android:id="@+id/img_thumb"-->
      <!--            android:layout_width="match_parent"-->
      <!--            android:layout_height="match_parent"-->
      <!--            android:layout_gravity="center"-->
      <!--            android:adjustViewBounds="true"-->
      <!--            android:clickable="false"-->
      <!--            android:focusable="false"-->
      <!--            android:scaleType="fitXY" />-->
      
      <!--    </FrameLayout>-->
      
      </FrameLayout>
    2. 修改切換播放源的邏輯。

      從Android播放器SDK 5.5.2.0版本開始,在調用moveToNext時,會增加對preRenderPlayer的調用,因此需要單獨對渲染View(Surface)進行設定。其中,moveToNextmoveToPremoveTo的邏輯有所差異。範例程式碼如下:

      展開查看代碼

      /*
          說明:mQuickPlayer是AlivcQuickPlayer類的執行個體對象,封裝了ListPlayer的介面。
      */
      private void startPlay(int position, boolean isInitComplete) {
          //...
          //根據position擷取ViewHolder執行個體對象
          LittleVideoListAdapter.MyHolder holder = (LittleVideoListAdapter.MyHolder) recycler.findViewHolderForLayoutPosition(position);
      
          //...
      
          //1.moveToPre時,先設定Surface,再調用moveToPre
          if (holder != null) {
              mQuickPlayer.setSurface(holder.getSurface());
          }
          mQuickPlayer.moveToPrev(video, position, mVideoSourceType);
      
          //2.moveTo時,先設定Surface,再調用moveTo
          if (holder != null) {
              mQuickPlayer.setSurface(holder.getSurface());
          }
          //mQuickPlayer.startPlay()內部最終會調用moveTo()介面
          mQuickPlayer.startPlay(video, position, mVideoSourceType);
      
          //3.moveToPre時,需要增加一個參數,將Surface傳遞進去
          mQuickPlayer.moveToNext(video, position, mVideoSourceType, holder.getSurface());
      
          //...
      }

      修改AlivcQuickPlayer類的範例程式碼如下:

      展開查看代碼

      //修改moveToPre方法
      public void moveToPrev(AlivcVideoInfo.Video source, final int position, VideoSourceType videoSourceType) {
          //...
          //增加如下代碼
          mVideoListPlayer.clearScreen();
          if (videoSourceType == VideoSourceType.TYPE_STS) {
              mVideoListPlayer.moveToPrev(createStsInfo(source));
          } else {
              mVideoListPlayer.moveToPrev();
          }
      }
      
      //增加moveToNext的重載方法
      public void moveToNext(AlivcVideoInfo.Video source, int position, VideoSourceType videoSourceType, Surface surface) {
          //...
          //moveToNext時,可以擷取preRenderPlayer對象,並使用該Player播放
          IPlayer preRenderPlayer = mVideoListPlayer.getPreRenderPlayer();
          if (preRenderPlayer != null) {
              preRenderPlayer.clearScreen();
              preRenderPlayer.setSurface(surface);
              preRenderPlayer.start();
              mVideoListPlayer.setSurface(null);
          } else {
              mVideoListPlayer.clearScreen();
              mVideoListPlayer.setSurface(surface);
          }
      
          //STS播放方式
          if (videoSourceType == VideoSourceType.TYPE_STS) {
              //當preRenderPlayer不為null時候,調用moveToNextWithPrerendered進行播放
              if (preRenderPlayer != null) {
                  mVideoListPlayer.moveToNextWithPrerendered(createStsInfo(source));
              } else {
                  mVideoListPlayer.moveToNext(createStsInfo(source));
              }
          } else {
              //URL播放方式
              if (preRenderPlayer != null) {
                  mVideoListPlayer.moveToNextWithPrerendered();
              } else {
                  mVideoListPlayer.moveToNext();
              }
          }
      }
    3. 可選:修改滑動播放的邏輯。

      支援通過修改滑動播放的邏輯,實現在滑動切換視訊時,當滑動到下一個視頻的一半畫面出現時,開始播放下一個視頻。通過修改PagerLayoutManager類中的代碼實現,即當RecyclerView的item出現在螢幕一半時,切換播放源,範例程式碼如下:

      展開查看代碼

      recyclerView.addOnScrollListener(new OnScrollListener() {
          private int measuredHeight;
          private int mScrollDiff;
          @Override
          public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
              super.onScrollStateChanged(recyclerView, newState);
      
              if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                  measuredHeight = recyclerView.getMeasuredHeight();
                  mScrollDiff = 0;
              }
      
              if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                  mScrollDiff = 0;
                  View viewIdle = mPagerSnapHelper.findSnapView(PagerLayoutManager.this);
                  if (viewIdle == null) {
                      return;
                  }
                  int positionIdle = getPosition(viewIdle);
                  if (mOnViewPagerListener != null && getChildCount() == 1 && mOldPosition != positionIdle) {
                      mOnViewPagerListener.onPageSelected(positionIdle, positionIdle == getItemCount() - 1, viewIdle);
                      mOldPosition = positionIdle;
                  }
              }
          }
      
          @Override
          public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
              super.onScrolled(recyclerView, dx, dy);
              if (measuredHeight > 0 && mOnViewPagerListener != null) {
                  mScrollDiff += dy;
                  changeVideoAfterScrolled(recyclerView, dy >= 0);
              }
          }
      
          private void changeVideoAfterScrolled(RecyclerView recyclerView, boolean isNext) {
              if (Math.abs(mScrollDiff) >= measuredHeight / 2) {
                  View snapView = mPagerSnapHelper.findSnapView(PagerLayoutManager.this);
                  if (snapView != null) {
                      int position = getPosition(snapView);
                      if (mOldPosition != position) {
                          if (isNext) {
                              mOnViewPagerListener.onPageHideHalf(position - 1);
                          } else {
                              mOnViewPagerListener.onPageHideHalf(position + 1);
                          }
                          mOnViewPagerListener.onPageSelected(position, false, snapView);
                          mOldPosition = position;
                          recyclerView.smoothScrollToPosition(position);
                          mScrollDiff = 0;
                      }
                  }
              }
          }
      });

播放帶透明度視頻

功能簡介

阿里雲播放器SDK支援渲染Alpha通道,實現播放透明禮物的動態效果。在直播間等情境中,播放透明禮物動效且不會遮擋直播間內容,明顯提升使用者觀看和互動體驗。

使用限制

一體化SDK6.8.0及以後版本或播放器SDK6.9.0及以後版本支援透明渲染能力。

功能優勢

使用帶有透明度資訊的MP4視頻作為禮物特效可以提供更好的動效品質,較小的檔案體積,更高的相容性和更高的開發效率。這使得禮物特效能夠更好地展示給使用者,提升使用者體驗。

  1. 更好的動效品質:MP4視頻可以保留原始的動效品質,包括細節和顏色等,相比於其他格式,如 APN 或IXD,MP4可以更準確地還原設計師創作的動效效果。

  2. 較小的檔案體積:MP4視頻檔案相比於其他格式,如APNG或IXD,可以更有效地壓縮檔體積,提升載入速度並降低網路頻寬消耗。

  3. 更高的相容性:MP4視頻是一種通用的視頻格式,在各種裝置和瀏覽器中都得到廣泛支援,支援在主流裝置上播放和觀看禮物特效。

  4. 更高的開發效率:使用MP4視頻作為禮物特效的技術方案相對簡單,不需要開發人員去研究和實現複雜的解析和渲染邏輯,開發人員可以專註於其他功能的實現,提高開發效率。

範例程式碼

新增如下介面:設定alpha模式(alpha通道在視頻素材的方位:上、下、左、右),預設值是None。

說明
  • 素材的alpha通道的位置要與setAlphaRenderMode參數設定的一致。

  • playerview的大小要與素材的解析度成比例。

/**
 * 設定Alpha渲染模式
 *
 * @param alphaRenderMode 鏡像模式。見{@link AlphaRenderMode}。
 */
/****
 * Set a alpha render mode
 *
 * @param alphaRenderMode The specified alpha render mode. See {@link AlphaRenderMode}.
 */
abstract public void setAlphaRenderMode(AlphaRenderMode alphaRenderMode);
//--------------View用法-------------
// 對於View需要設定透明
//TextureView
TextureView aliplayerView; //用於播放的 view
aliplayerView.setOpaque(false);

//SurfaceView
SurfaceView aliplayerView; //用於播放的 view
aliplayerView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
aliplayerView.setZOrderOnTop(true); //把SurfaceView置於顯示視窗的最頂層

//-----------AliPlayer用法-----------
//設定alpha模式
aliplayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
//設定alpha模式對應的素材
UrlSource urlSource = new UrlSource();
urlSource.setUri("https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/%E4%B8%9A%E5%8A%A1%E9%9C%80%E6%B1%82%E6%A0%B7%E6%9C%AC/alpha%E9%80%9A%E9%81%93/alpha_right.mp4");
aliplayer.setDataSource(urlSource);
aliplayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
    @Override
    public void onCompletion() {
        //可選:單一實例播放完成後如果有銜接問題,可以清屏
        aliplayer.clearScreen();
    }
}
aliplayer.setAutoPlay(true);
aliplayer.prepare();

外掛字幕

Android播放器SDK支援添加和切換外掛字幕,現已支援SRT、SSA、ASS、VTT這4種格式的字幕。樣本如下:

  1. 建立顯示字幕的View。

    根據不同的字幕格式建立不同的View。

    展開查看代碼

    //用於顯示SRT和VTT字幕
    SubtitleView subtitleView = new SubtitleView(getContext());
    //用於顯示ASS和SSA字幕
    AssSubtitleView assSubtitleView = new AssSubtitleView(getContext());
    //將字幕View添加到布局視圖中
    viewGroup.addView(assSubtitleView);
  2. 設定字幕相關監聽。

    展開查看代碼

    mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleExtAdded(int trackIndex, String url) { }
    
        @Override
        public void onSubtitleShow(int trackIndex, long id, String data) {
                // ass 字幕
            assSubtitleView.show(id,data);
    
            // srt 字幕
            SubtitleView.Subtitle subtitle = new SubtitleView.Subtitle();
            subtitle.id = id + "";
            subtitle.content = data;
            subtitleView.show(subtitle);
    
        }
    
        @Override
        public void onSubtitleHide(int trackIndex, long id) {
                // ass 字幕
                assSubtitleView.dismiss(id);
    
            // srt 字幕
            subtitleView.dismiss(id + "");
        }
    
        @Override
        public void onSubtitleHeader(int trackIndex, String header) { }
    });
  3. 添加字幕。

    mAliPlayer.addExtSubtitle(url);
  4. 顯示或隱藏字幕。

    在收到onSubtitleExtAdded回調後,可通過如下方法進行顯示或隱藏字幕:

    //trackIndex:傳入字幕索引;true:表示顯示傳入的字幕;false:表示隱藏傳入的字幕
    mAliPlayer.selectExtSubtitle(trackIndex, true);

純音頻播放

通過禁用視頻播放,達到純音頻播放的效果。在prepare之前配置PlayerConfig。

PlayerConfig config = mAliPlayer.getConfig();
config.mDisableVideo = true;  //設定開啟純音頻播放
mAliPlayer.setConfig(config);

軟硬解切換

說明

解碼方式需要在播放前切換,播放中切換解碼方式將不會生效。

Android播放器SDK提供了H.264、H.265的硬解碼能力,同時提供了enableHardwareDecoder提供開關。預設開,並且在硬解初始化失敗時,自動切換為軟解,保證視頻的正常播放。樣本如下:

//開啟硬解。預設開啟
mAliyunVodPlayer.enableHardwareDecoder(true);

如果從硬解自動切換為軟解,將會通過onInfo回調,樣本如下:

mApsaraPlayerActivity.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if (infoBean.getCode() == InfoCode.SwitchToSoftwareVideoDecoder) {
            //切換到軟解
        }
    }
});

網路自適應切換視訊清晰度

說明
  • HLS的多碼率自適應視頻流可以在ApsaraVideo for VOD中經過視頻打包轉碼模板組進行轉碼處理後產生,詳細操作請參見點播多碼率自適應配置

  • 經過ApsaraVideo for VOD轉碼產生的自適應流,如果使用Vid方式播放,則需要指定預設播放清晰度列表為DEFINITION_AUTO,才會擷取並播放自適應的視頻流;否則將按照預設邏輯選擇低清晰度的視頻流進行播放,預設清晰播放順序請參見清晰度相關問題。以VidAuth播放方式為例,指定清晰度列表的樣本如下:

    VidAuth vidAuth = new VidAuth();
    List<Definition> list = new ArrayList<>();
    list.add(Definition.DEFINITION_AUTO);
    vidAuth.setDefinition(list);

Android播放器SDK支援多碼率自適應HLS、DASH視頻流。在prepare成功之後,通過getMediaInfo可以擷取到各個碼流的資訊,即TrackInfo。樣本如下:

List<TrackInfo> trackInfos  = aliyunVodPlayer.getMediaInfo().getTrackInfos();

在播放過程中,可以通過調用播放器的selectTrack方法切換播放的碼流,取值為AUTO_SELECT_INDEX時,為多碼率自適應。樣本如下:

int index = trackInfo.getIndex();
//多碼率切換
aliyunVodPlayer.selectTrack(index);
//多碼率切換並自適應
aliyunVodPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);

切換的結果會在OnTrackChangedListener監聽之後會回調(在調用selectTrack之前設定)。樣本如下:

aliyunVodPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
    @Override
    public void onChangedSuccess(TrackInfo trackInfo) {
        //切換成功
    }
    @Override
    public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
        //切換失敗。失敗原因通過errorInfo.getMsg()擷取
    }
});

截圖

Android播放器SDK提供了對當前視頻截圖的功能,由snapshot介面實現。截取的是原始的資料,並轉為bitmap返回。回調介面為OnSnapShotListener。樣本如下:

//設定截圖回調
aliyunVodPlayer.setOnSnapShotListener(new OnSnapShotListener(){
    @Override
    public void onSnapShot(Bitmap bm, int with, int height){
        //擷取到的bitmap以及圖片的寬高。
    }
});
//截取當前播放的畫面
aliyunVodPlayer.snapshot();

試看

Android播放器SDK通過配合點播服務配置,可以實現試看功能,支援VidSts和VidAuth(ApsaraVideo for VOD推薦使用此方式)兩種播放方式。如何配置和使用試看功能,請參見試看視頻

配置試看功能之後,通過VidPlayerConfigGen.setPreviewTime()方法設定播放器的試看時間長度。以VidSts播放方式為例,樣本如下:

VidSts vidSts = new VidSts;
....
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
configGen.setPreviewTime(20);//20秒試看
vidSts.setPlayConfig(configGen);//設定給播放源
...

當設定試看的時間長度,通過Android播放器SDK播放視頻時,服務端將不會返回完整的視頻內容,而是返回試看時間段的內容。

說明
  • VidPlayerConfigGen支援設定服務端支援的請求參數。請參見請求參數說明

  • FLV和MP3格式視頻暫時不支援試看。

設定黑名單

Android播放器SDK提供了硬解的黑名單機制。對於明確不能使用硬解播放的機器,可以直接使用軟解,避免了無效的操作。樣本如下:

DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.model="Lenovo K320t";
AliPlayerFactory.addBlackDevice(BlackType.HW_Decode_H264 ,deviceInfo );
說明

退出App之後,黑名單自動失效。

設定Referer

Android播放器SDK支援設定Referer,配合控制台的黑白名單Referer,可以控制存取權限,由PlayerConfig方法佈建要求Referer。播放器SDK的設定樣本如下:

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//設定referer,樣本:http://example.aliyundoc.com。(注意:設定referer時,需要加上前面的協議部分。)
config.mReferrer = referrer;
....//其他設定
  //設定配置給播放器
mAliyunVodPlayer.setConfig(config);

設定UserAgent

Android播放器SDK提供了PlayerConfig用來佈建要求UA。設定之後,播放器請求的過程中將會帶上UA資訊。樣本如下:

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//設定UA
config.mUserAgent = "需要設定的UserAgent";
....//其他設定
  //設定配置給播放器
mAliyunVodPlayer.setConfig(config);

配置網路重試時間和次數

支援設定Android播放器SDK的網路逾時的時間和重試次數,由PlayerConfig方法實現。樣本如下:

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//設定網路逾時時間,單位:毫秒
config.mNetworkTimeout = 5000;
//設定逾時重試次數。每次稍候再試為networkTimeout。networkRetryCount=0則表示不重試,重試策略app決定,預設值為2
config.mNetworkRetryCount=2;
....//其他設定
  //設定配置給播放器
mAliyunVodPlayer.setConfig(config);
說明
  • 如果設定了NetworkRetryCount,若此時發生網路問題,導致出現loading後,那麼將會重試NetworkRetryCount次,每次的間隔時間為mNetworkTimeout。

  • 如果重試多次之後,還是loading的狀態,那麼就會回調onError事件,此時,ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT。

  • 如果NetworkRetryCount設定為0,當網路重試逾時的時候,播放器就會回調onInfo事件,事件的InfoBean.getCode()=InfoCode.NetworkRetry。 此時,可以調用播放器的reload方法進行重新載入網路,或者進行其他的處理。

配置緩衝和延遲控制

Android播放器SDK通過PlayerConfig提供了設定緩衝和延遲的控制介面。樣本如下:

展開查看代碼

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//最大延遲。注意:直播有效。當延時比較大時,播放器sdk內部會追幀等,保證播放器的延時在這個範圍內。
config.mMaxDelayTime = 5000;
// 最大緩衝區時間長度。單位ms。播放器每次最多載入這麼長時間的緩衝資料。
config.mMaxBufferDuration = 50000;
//高緩衝時間長度。單位ms。當網路不好導致載入資料時,如果載入的緩衝時間長度到達這個值,結束載入狀態。
config.mHighBufferDuration = 3000;
// 起播緩衝區時間長度。單位ms。這個時間設定越短,起播越快。也可能會導致播放之後很快就會進入載入狀態。
config.mStartBufferDuration = 500;
....//其他設定
//往前緩衝的最大時間長度。單位ms。預設為0。
config.mMaxBackwardBufferDurationMs = 0;

//設定配置給播放器
mAliyunVodPlayer.setConfig(config);

重要
  • 三個緩衝區時間長度的大小關係必須為:mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration。

  • 當最大緩衝區時間長度(mMaxBufferDuration)大於5分鐘時,為防止因為緩衝區過大導致的記憶體異常,系統將預設按5分鐘生效。當mMaxBufferDuration設定超過50000 ms(即50s)時,可以啟用大緩衝,來降低記憶體佔用,進一步提高播放效能,如有需要,請參見大緩衝

設定HTTP Header

通過PlayerConfig方法,可以給播放器中的請求加上HTTP的header參數。樣本如下:

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//定義header
String[] headers = new String[1];
headers[0]="Host:example.com";//比如需要設定Host到header中。
//設定header
config.setCustomHeaders(headers);
....//其他設定
  //設定配置給播放器
mAliyunVodPlayer.setConfig(config);

RTS降級播放

在使用超低延時直播RTS地址播放的情境下,通過設定RTS的降級地址(如HLS地址或FLV地址),當RTS拉流失敗時,會自動降級到該地址播放。樣本如下:

PlayerConfig config = player.getConfig();
//可選,配置config其他項
UrlSource urlSource = new UrlSource();
urlSource.setUri(downgradeUrl);
//設定降級URL
player.enableDowngrade(urlSource, config);

切換左右聲道

Android播放器SDK通過player.setOutputAudioChannel方法設定輸出聲道,如果輸入源是雙聲道,則支援通過下述方法切換為左聲道或右聲道;如果輸入源是單聲道,則設定無效。

說明

下述輸出聲道的設定會同時影響音頻渲染及PCM資料回調。

/*
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT 切換到左聲道播放,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT 切換到右聲道播放,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE 不切換聲道,保持輸入源聲道播放
*/
player.setOutputAudioChannel();

解析音頻流

設定監聽,可擷取音視頻流資料。音視頻不能是加密流,加密流無法解析。

展開查看代碼

//可選配置1:是否返回底層資料的地址
IPlayer.RenderFrameCallbackConfig config = new IPlayer.RenderFrameCallbackConfig();
config.mVideoDataAddr = true;//是否只返回底層視頻資料地址
config.mAudioDataAddr = true;//是否只返回底層音頻資料地址
player.setRenderFrameCallbackConfig(config);

//可選配置2:硬解時,RenderFrame返回 texture_oes_id,軟解時,RenderFrame返回來源資料
player.enableHardwareDecoder(true);
//設定監聽,擷取音視頻資料
player.setOnRenderFrameCallback(frameInfo -> {
    if (frameInfo.frameType == FrameInfo.FrameType_video) {
        //視頻資料
    } else {
        //音頻資料
    }
    return false;
});

設定視頻背景色

Android播放器SDK支援設定播放器渲染的背景色。介面和用法說明如下:

介面樣本

/**
 * 設定視頻的背景色
 *
 * @param color  ARGB
 *
 */
/****
 * Set video background color
 * @param color  ARGB
 */
abstract public void setVideoBackgroundColor(int color);

用法說明

//參數為8位16進位資料,8位元據兩兩為一組,按照順序分別表示R(red) G(green) B(blue) A(alpha 透明度)
//例如0x00ff00ff,表示綠色
player.setVideoBackgroundColor(0x00ff00ff);

vidAuth設定指定播放網域名稱

通過vidAuth方式可以指定vid對應的網域名稱等欄位,支援的欄位詳情請參見GetPlayInfo請求參數。介面及用法說明如下:

介面樣本

/**
 * 設定播放參數
 *
 * @param playConfig 播放參數
 */
public void setPlayConfig(VidPlayerConfigGen playConfig);

用法說明

通過其中的VidPlayerConfigGen介面的addPlayerConfig添加playDomain欄位。

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
//增加playDomain欄位,可以添加的欄位參考
//https://www.alibabacloud.com/help/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);

效能

本機快取

Android播放器SDK提供了本機快取的功能,能夠讓使用者重複播放視頻時,提高起播速度、提高seek速度、減少卡頓,也能達到節省流量的目的。

開啟本機快取

本機快取功能預設關閉,如需使用,需要手動開啟。通過AliPlayerGlobalSettings中的enableLocalCache控制。樣本如下:

展開查看代碼

/**
 *  開啟本機快取,開啟之後,會緩衝到本地檔案中。
 *
 *  @param enable - 本機快取功能開關。true:開啟本機快取,false:關閉,預設關閉。
 *  @param maxBufferMemoryKB - 5.4.7.1及以後版本已廢棄,暫無作用
 *  @param localCacheDir - 本機快取的檔案目錄,為絕對路徑。
 */
public static void enableLocalCache(boolean enable,
                                    int maxBufferMemoryKB,
                                    java.lang.String localCacheDir)

 /**
  * 本機快取檔案清理相關配置。
  *
  * @param expireMin - 5.4.7.1及以後版本已廢棄,暫無作用。
  * @param maxCapacityMB - 最大緩衝容量。單位:兆,預設值20GB,在清理時,如果緩衝總容量超過此大小,則會以cacheItem為粒度,按緩衝的最後時間排序,一個一個的刪除最舊的快取檔案,直到小於等於最大緩衝容量。
  * @param freeStorageMB - 磁碟最小空餘容量。單位:兆,預設值0,在清理時,同最大緩衝容量,如果當前磁碟容量小於該值,也會按規則一個一個的刪除快取檔案,直到freeStorage大於等於該值或者所有緩衝都被清理掉。
  */
 public static void setCacheFileClearConfig(long expireMin,
                                           long maxCapacityMB,
                                           long freeStorageMB)

  /**
   * 設定載入url的hash值回調。如果不設定,SDK使用md5演算法。
   */
  public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
說明
  • 如果視頻播放URL帶有鑒權參數,本機快取和播放時鑒權參數會變化,為提高相同URL在不同鑒權下的快取命中率,可以將URL的鑒權參數去掉後再通過setCacheUrlHashCallback介面計算Hash值(例如MD5)。例如:帶有鑒權參數的視頻播放URL為http://****.mp4?aaa,則載入時使用http://****.mp4計算Hash值。但如果視頻為經過加密後的m3u8視頻,其keyURL若按照去掉鑒權參數再計算Hash值的方式處理,會導致不同視頻的快取命中同一個key導致播放失敗。解決方案:您可以在setCacheUrlHashCallback的回調裡進行網域名稱判斷,僅對播放網域名稱(http(s)://xxxxx.m3u8?aaaa)做去掉鑒權參數的處理,而keyURL對應的網域名稱(http(s)://yyyyy?bbbb)不做去掉鑒權參數的處理。進階功能-本機快取.png

  • 如果伺服器同時支援HTTP和HTTPS協議,但是不同的協議指向的媒體檔案是同一個,則可以將要求標頭去掉或者統一後再計算Hash值。例如:

    • 視頻播放URL為https://****.mp4http://****.mp4,則載入時使用****.mp4計算hash值。

    • 視頻播放URL為https://****.mp4,載入時統一為http://****.mp4後再計算Hash值。

  • 針對5.5.4.0及以後版本的播放器SDK,如果視頻播放URL帶有鑒權參數且播放協議為HLS,可以通過設定PlayerConfig.mEnableStrictAuthMode欄位,進行不同鑒權模式的選擇(預設值為false):

    • 非嚴格鑒權(false):鑒權也緩衝,若上一次只緩衝了部分媒體,下次播放至非緩衝部分時,播放器會用緩衝的鑒權發起請求,如果URL鑒權設定的有效期間很短,會導致播放異常。

    • 嚴格鑒權(true):鑒權不緩衝,每次起播都進行鑒權,無網路下會導致起播失敗。

開啟或關閉單個URL的本機快取

如果想要針對單個URL開啟或關閉本機快取功能,可以在player config中設定。

//先擷取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//是否針對播放的URL開啟本機快取,預設值為true。當AliPlayerGlobalSettings處的本地緩開啟時,且同時開啟此處的本機快取,即設定為true,該URL的本機快取才會生效;若此處設定為false,則關閉該URL的本機快取。
config.mEnableLocalCache = false;
....//其他設定

//設定配置給播放器
mAliyunVodPlayer.setConfig(config);

大緩衝

通過設定資料的最大緩衝區時間長度可以在播放視頻時通過緩衝視頻資料到記憶體中,從而提高播放效能和觀看體驗。當最大緩衝區時間長度設定過大時,會造成緩衝區對記憶體的消耗。通過啟用大緩衝,可以將視頻資料緩衝到檔案中,從而降低記憶體的佔用,進一步提高播放器效能。

當mMaxBufferDuration設定超過50000 ms時,通過開啟本機快取觸發大緩衝功能自動啟用。操作流程如下:

  1. 開啟全域本機快取。

    本機快取功能預設關閉,如需使用,需要手動開啟。通過AliPlayerGlobalSettings中的enableLocalCache控制。程式碼範例請參見本機快取中的開啟本機快取

  2. 開啟URL的本機快取。

    程式碼範例請參見本機快取中的開啟或關閉單個URL的本機快取

預先載入

Android播放器SDK提供預先載入功能,是對本機快取功能的升級,通過設定視頻緩衝的記憶體佔用大小,更能提升視頻的起播速度。

預先載入功能的使用限制如下:

  • 目前支援MP4、MP3、FLV、HLS(單碼率視頻流)等單個媒體檔案的載入。

  • 僅支援UrlSource播放方式播放視頻的預先載入,暫不支援VidAuth、VidSts方式播放視頻的預先載入。

說明

Android播放器SDK預設提供預先載入時網路資源自動調度能力,以減少預先載入的網路請求對現正播放視頻的網路請求的影響。自動調度的策略是:僅當現正播放的視頻緩衝到達一定閾值後,才會允許預先載入進行請求。若您需要自行控制預先載入的即時請求,可以通過以下方法將此策略關閉:

AliPlayerGlobalSettings.enableNetworkBalance(false);
  1. 開啟本機快取功能,詳細操作請參見本機快取

  2. 擷取AliMediaLoader執行個體。

    AliMediaLoader執行個體為單例,即無論擷取多少次,建立的都是同一個執行個體。

    MediaLoader mediaLoader = MediaLoader.getInstance();
  3. 配置AliMediaLoader。

    配置回調,並開始載入。

    說明

    playerprepare時刻與mediaLoader.load的調用時刻一致,由雩都需要遍曆本地檔案,則可能導致出現ANR的問題。建議設定為當playeronPrepared回調中時,才開始載入。

    展開查看代碼

    /**
     * 設定載入狀態回調
     */
    mediaLoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
        @Override
        public void onError(String url, int code, String msg) {
            //載入出錯
        }
    
        @Override
        public void onCompleted(String s) {
            //載入完成
        }
    
        @Override
        public void onCanceled(String s) {
            //載入取消
        }
    });
    /**
     * 開始負載檔案。非同步載入。可以同時載入多個視頻檔案。
     * @param url - 視頻檔案地址。
     * @param duration - 載入的時間長度大小,單位:毫秒。
     */
    mediaLoader.load("url","duration");
  4. 可選:刪除負載檔案。

    可按需刪除負載檔案,以節省空間的。Android播放器SDK不提供刪除介面,需要在App刪除載入目錄下的檔案。

動態預先載入

動態預先載入策略,支援整合方既可以控制當前現正播放視頻的緩衝,又可以控制預先載入的個數和緩衝,滿足業務方對播放體驗與成本開銷之間取得平衡的訴求。

展開查看代碼

// 開啟推薦配置和動態預先載入
ListPlayer.setPreloadScene(IListPlayer.SceneType.SCENE_SHORT);

// 配置基準預先載入時間長度
// 設定預先載入時間長度為1000ms
PreloadConfig config = new PreloadConfig();
config.mPreloadDuration = 1000;
ListPlayer.updatePreloadConfig(config);

// 配置預先載入的數量,支援雙向
// 1為向前預先載入的數量,3為向後預先載入的數量
ListPlayer.setPreloadCount(1, 3);

// 配置動態預先載入的遞減的offset
ListPlayer.enablePreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, true);
ListPlayer.setPreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, "{\"algorithm\": \"sub\",\"offset\": \"200\"}");

多碼率HLS視頻預先載入

listPlayer+多碼率HLS視頻播放情境下,支援整合方預先載入與當前播放清晰度一致的流,並且可以根據業務情況選擇預先載入模式。

展開查看支援的預先載入模式

  /**
   * 預設配置,播放和預先載入預設碼率
   */
  /****
   * default mode, play and preload default bitrate of a stream
   */
  MultiBitratesMode_Default(0),

  /**
   * 首幀優先配置,起播視頻預設播放已完成預先載入的碼率
   */
  /****
   * First frame cost (FC) priority, decrease first frame cost. only play bitrate of the hls stream which has been preloaded.
   */
  MultiBitratesMode_FCPrio(1),

  /**
   * 兼顧首幀和播放平滑,切換前後(moveToNext)的視頻碼率一致,且兼顧首幀效能
   */
  /****
   * First frame and play smooth, play the same bitrate before and after moveToNext
   */
  MultiBitratesMode_FC_AND_SMOOTH(2),

  /**
   * 播放平滑優先配置,起播視頻預設播放前一個視頻的碼率
   */
  /****
   * Play Smooth priority, play the same bitrate before and after moveToNext.
   */
  MultiBitratesMode_SmoothPrio(3);

展開查看整合代碼

//選擇多碼率載入模式
mVideoListPlayer.SetMultiBitratesMode(preLoadMode);


//(可選)選擇起播碼率
mVideoListPlayer.setDefaultBandWidth(defaultBandWidth)


//(可選)在onPrepared回調中,選擇abr模式
mVideoListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
    @Override
    public void onPrepared() {
        //abr only effect on multiBitrate m3u8
        mVideoListPlayer.selectTrack(-1);
    }
});

擷取下載速度

擷取當前播放視頻的下載速度,在onInfo回調中擷取,由getExtraValue介面實現。樣本如下:

mAliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if(infoBean.getCode() == InfoCode.CurrentDownloadSpeed){
            //當前下載速度
            long extraValue = infoBean.getExtraValue();
        }
    }
});

網路特性

HTTPDNS

HTTPDNS是通過DNS解析技術將網域名稱解析請求發送到特定的HTTPDNS伺服器,以擷取更快、更穩定的網域名稱解析結果,降低DNS劫持風險。

阿里雲播放器SDK提供增強型HTTPDNS功能,專為阿里雲CDN網域名稱提供HTTPDNS服務,支援阿里雲CDN網路精準調度、即時解析生效,有效提高網路效能。

說明

播放器SDK從6.7.0版本開始支援增強型HTTPDNS。6.7.0~6.11.0版本播放器SDK,請先提交工單或聯絡阿里雲商務經理申請開通;6.12.0及以後版本無需申請,預設開啟。

增強型HTTPDNS使用樣本

增強型HTTPDNS僅為阿里雲CDN網域名稱提供HTTPDNS服務,請確保您配置的網域名稱為阿里雲CDN網域名稱且已完成網域名稱配置可正常使用。ApsaraVideo for VOD中添加和配置CDN網域名稱請參見添加加速網域名稱。更多有關CDN網域名稱的資訊請參見阿里雲CDN

//開啟增強型httpdns
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
//可選,增加httpdns預解析網域名稱
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");

HTTP/2

說明

Android播放器SDK自5.5.0.0版本開始預設開啟使用HTTP/2。

Android播放器SDK支援使用HTTP/2協議,該協議通過多工,避免隊頭阻塞,以改善播放效能。樣本如下:

AliPlayerGlobalSettings.setUseHttp2(true);

HTTP預建連TCP

針對HTTP的視頻播放請求(非HTTPS),通過提前建立TCP串連能夠顯著改善使用者體驗,降低網路連接耗時,確保播放的即時性與連續性,同時最佳化網路和系統資源的使用效率。使用方式如下:

// domain格式為host[:port],port可選,用分號(;)隔開多個網域名稱
// 全域設定
// 全量介面每次設定後使用當前的字串為準(多-新增,少-刪除),字串空為停止預建連
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");

視頻下載

Android播放器SDK提供了點播服務視頻的下載功能,允許使用者通過阿里雲播放器將視頻緩衝至本地觀看。同時,提供了普通下載和安全下載兩種下載方式。

  • 普通下載

    下載後的視頻資料未經過阿里雲加密,使用者可以用第三方播放器播放。

  • 安全下載

    下載後的視頻資料經過阿里雲加密。第三方播放器無法播放。僅支援使用阿里雲的播放器進行播放。

使用說明

  • 僅VidSts和VidAuth方式可使用視訊下載功能。

  • 使用播放器的視頻下載功能,需要在點播控制台開啟並配置下載模式,詳細操作請參見下載設定

  • 視頻下載支援斷點續傳。

操作步驟

  1. 可選:配置安全下載的加密校正檔案。僅安全下載需要配置,普通下載無需配置。

    說明

    請確保配置的加密校正檔案與App資訊一致,否則會導致視頻下載失敗。

    如果設定為安全下載方式,則需要將在點播控制台產生的密鑰檔案配置到播放器SDK中,用於視頻下載和播放的解密驗證,密鑰檔案的產生請參見安全下載

    建議在Application中配置一次即可,樣本如下:

    PrivateService.initService(getApplicationContext(),  "encryptedApp.dat所在的檔案路徑"); //建議將encryptedApp.dat加密校正檔案存放到手機中後,此處設定加密校正檔案的手機本地檔案路徑
  2. 建立並設定下載器。

    建立下載器,通過AliDownloaderFactory建立。樣本如下:

    AliMediaDownloader mAliDownloader = null;
    ......
    //建立下載器
    mAliDownloader = AliDownloaderFactory.create(getApplicationContext());
    //配置下載儲存的路徑
    mAliDownloader.setSaveDir("儲存的檔案夾地址");
  3. 設定監聽事件。

    下載器提供了多個事件監聽。樣本如下:

    展開查看代碼

    mAliDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
       @Override
       public void onPrepared(MediaInfo mediaInfo) {
           //準備下載項成功
       }
    });
    mAliDownloader.setOnProgressListener(new AliMediaDownloader.OnProgressListener() {
       @Override
       public void onDownloadingProgress(int percent) {
           //下載進度百分比
       }
       @Override
       public void onProcessingProgress(int percent) {
           //處理進度百分比
       }
    });
    mAliDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
       @Override
       public void onError(ErrorInfo errorInfo) {
           //下載出錯
       }
    });
    mAliDownloader.setOnCompletionListener(new AliMediaDownloader.OnCompletionListener() {
       @Override
       public void onCompletion() {
           //下載成功
       }
    });
  4. 準備下載源。

    通過prepare方法準備下載源。下載源支援VidSts和VidAuth兩種方式。樣本如下:

    • VidSts

      //建立VidSts
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("Vid資訊");// 視頻ID(VideoId)。
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>");// STS臨時AK對的存取金鑰ID,需要調用STS服務的AssumeRole介面產生。
      aliyunVidSts.setAccessKeySecret"<yourAccessKeySecret>");// STS臨時AK對的存取金鑰,需要調用STS服務的AssumeRole介面產生。
      aliyunVidSts.setSecurityToken("<yourSecurityToken>");// STS安全性權杖,需要調用STS服務的AssumeRole介面產生。
      aliyunVidSts.setRegion("接入地區");// 點播服務的接入地區,預設為cn-shanghai。
      //準備下載源
      mAliDownloader.prepare(aliyunVidSts)
    • VidAuth

      //建立VidAuth
      VidAuth vidAuth = new VidAuth();
      vidAuth.setVid("Vid資訊");// 視頻ID(VideoId)。
      vidAuth.setPlayAuth("<yourPlayAuth>");// 播放憑證,需要調用點播服務的GetVideoPlayAuth介面產生。
      vidAuth.setRegion("接入地區");// 5.5.5.0及之後版本播放器SDK,本參數已棄用,無需設定region,播放器會自動解析region;5.5.5.0之前版本播放器SDK,本參數必選,點播服務的接入地區,預設為cn-shanghai。
      //準備下載源
      mAliDownloader.prepare(vidAuth);
    說明

    源檔案格式與輸出的下載檔案格式保持一致,不支援更改。

  5. 準備成功後,選擇下載項並開始下載。

    準備成功後,會回調OnPreparedListener方法。返回的TrackInfo中會包含各視頻流的清晰度等資訊,請選擇一個Track進行下載,樣本如下:

    public void onPrepared(MediaInfo mediaInfo) {
        //準備下載項成功
        List<TrackInfo> trackInfos = mediaInfo.getTrackInfos();
        //比如:下載第一個TrackInfo
        mAliDownloader.selectItem(trackInfos.get(0).getIndex());
        //開始下載
        mAliDownloader.start();
    }
  6. (可選)更新下載源。

    為了防止VidSts和VidAuth到期,您也可以更新下載源的資訊後開始下載。樣本如下:

    //更新下載源
    mAliDownloader.updateSource(VidSts);
    //開始下載
    mAliDownloader.start();
  7. 下載成功或失敗後,釋放下載器。

    下載成功後,在onCompletion或者onError回調中調用release釋放下載器。樣本如下:

    mAliDownloader.stop();
    mAliDownloader.release();
  8. 可選:刪除下載的檔案。

    下載過程中,或者下載完成後,可以刪除下載的檔案。樣本如下:

    //通過對象刪除檔案
    mAliDownloader.deleteFile();
    //通過靜態方法刪除,若刪除成功則返回0
    AliDownloaderFactory.deleteFile("待刪除的下載檔案夾路徑","視頻ID","視頻格式","下載的視頻索引");

後續操作

下載的視頻可以使用阿里雲播放器進行播放。具體方法如下:

  1. 下載完成後擷取視頻檔案的絕對路徑。

    String path = mAliDownloader.getFilePath();
  2. 通過點播UrlSource方式設定絕對路徑進行播放。

     UrlSource urlSource = new UrlSource();
            urlSource.setUri("播放地址");//設定下載視頻的絕對路徑。
            aliPlayer.setDataSource(urlSource);

視頻加密播放

點播視訊支援HLS標準加密、阿里雲私人加密和DRM加密,直播視頻僅支援DRM加密。加密播放請參見視頻加密播放

Native RTS播放

Android播放器SDK整合Native RTS SDK實現Native端低延時直播功能,詳情請參見阿里雲播放器SDK整合Native RTS SDK實現說明(Android端)

相關文檔