日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

進(jìn)階功能

更新時(shí)間:

本文介紹Android播放器SDK進(jìn)階功能的使用示例,更多功能的支持和使用請(qǐng)參見API說明

播放

列表播放

針對(duì)典型的列表播放場(chǎng)景,Android播放器SDK提供了完善的列表播放功能,結(jié)合預(yù)加載等機(jī)制大幅改善短視頻的起播速度。

操作步驟

  1. 創(chuàng)建播放器。

    通過AliPlayerFactory類創(chuàng)建AliListPlayer播放器。示例如下:

    AliListPlayer aliyunListPlayer;
    .....
    aliyunListPlayer = AliPlayerFactory.createAliListPlayer(getApplicationContext());
    aliyunListPlayer.setTraceId("traceId");  //traceId為設(shè)備或用戶的唯一標(biāo)識(shí)符,通常為imei或idfa
  2. 可選:設(shè)置監(jiān)聽器。

    創(chuàng)建列表播放時(shí),監(jiān)聽器為非必須配置,但如果不設(shè)置,將無法收到播放器的播放失敗、播放進(jìn)度等事件通知,因此,建議您設(shè)置。其中OnPreparedListenerOnErrorListenerOnCompletionListenerOnLoadingStatusListenerOnInfoListener較為重要,建議您設(shè)置。

    展開查看代碼

    aliyunListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            //播放完成事件
        }
    });
    aliyunListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            //出錯(cuò)事件
        }
    });
    aliyunListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            //準(zhǔn)備成功事件
        }
    });
    aliyunListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            //視頻分辨率變化回調(diào)
        }
    });
    aliyunListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            //首幀渲染顯示事件
        }
    });
    aliyunListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            //其他信息的事件,type包括了:循環(huán)播放開始,緩沖位置,當(dāng)前播放位置,自動(dòng)播放開始等
        }
    });
    aliyunListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            //緩沖開始。
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            //緩沖進(jìn)度
        }
        @Override
        public void onLoadingEnd() {
            //緩沖結(jié)束
        }
    });
    aliyunListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            //拖動(dòng)結(jié)束
        }
    });
    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) {
            //播放器狀態(tài)改變事件
        }
    });
    aliyunListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            //截圖事件
        }
    });
  3. 設(shè)置預(yù)加載個(gè)數(shù)。

    合理設(shè)置預(yù)加載個(gè)數(shù),能夠有效的提高起播的速度。示例如下:

    //設(shè)置預(yù)加載個(gè)數(shù)。總共加載的個(gè)數(shù)為: 1 + count*2。
    aliyunListPlayer.setPreloadCount(int count);
  4. 添加或移除多個(gè)播放源。

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

    • Url:播放地址可以是第三方點(diǎn)播地址或阿里云點(diǎn)播服務(wù)中的播放地址。阿里云播放地址可以調(diào)用獲取音視頻播放地址接口獲取。建議您集成點(diǎn)播服務(wù)端SDK來獲取音視頻播放地址,免去自簽名的麻煩。調(diào)用接口獲取音視頻播放地址的示例請(qǐng)參見開發(fā)者門戶

    • Vid:音視頻ID,可以在音視頻上傳完成后通過控制臺(tái)(路徑:媒資庫 > 音/視頻。)或服務(wù)端接口(搜索媒體信息)獲取。

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

    uid是視頻的唯一標(biāo)志。用于區(qū)分視頻是否一樣。如果uid一樣,則認(rèn)為視頻是一樣的。如果播放出現(xiàn)串流的情況,請(qǐng)注意查看是不是在不同的界面設(shè)置了同一個(gè)uid。uid沒有格式限制,可以是任意的字符串。

  5. 設(shè)置顯示View。

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

    • 設(shè)置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);
          }
      });
    • 設(shè)置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. 播放視頻源。

    添加了一個(gè)或多個(gè)播放源之后并設(shè)置自動(dòng)播放,調(diào)用moveTo便可以自動(dòng)播放某個(gè)視頻源。示例如下:

    展開查看代碼

    //開啟自動(dòng)播放
    aliyunListPlayer.setAutoPlay(true);
    
    //url時(shí)使用此接口
    aliyunVodPlayer.moveTo(String uid);
    //vid的時(shí)候使用此接口,需要傳遞stsInfo即STS臨時(shí)憑證和臨時(shí)AK對(duì),需要提前獲取,獲取方式請(qǐng)參見創(chuàng)建RAM角色并進(jìn)行STS臨時(shí)授權(quán)。
    aliyunVodPlayer.moveTo(String uid, StsInfo info);
    //vid的時(shí)候使用此接口,需要傳遞PlayAuthInfo,在此之前要針對(duì)每個(gè)視頻獲取PlayAuth信息。
    aliyunVodPlayer.moveTo(String uid, PlayAuthInfo info);
  7. 播放上一個(gè)、下一個(gè)視頻。

    • 調(diào)用moveTo播放某個(gè)視頻源后,調(diào)用moveToPrevmoveToNext接口以moveTo的視頻源為錨點(diǎn)進(jìn)行播放上一個(gè),下一個(gè)視頻。示例如下:

      說明

      在基于同一個(gè)view的情況下,調(diào)用moveto或者moveToNext等切換視頻源操作時(shí),會(huì)出現(xiàn)閃爍黑屏的情況。此時(shí)建議在listPlayer初始化時(shí),配置PlayerConfigmClearFrameWhenStop字段為false,并調(diào)用setConfig使其生效。

      展開查看代碼

      //開啟自動(dòng)播放
      aliyunListPlayer.setAutoPlay(true);
      
      //移動(dòng)到下一個(gè)視頻。 注意:只能用于url的源。這個(gè)方法不適用于vid的播放。
      aliyunVodPlayer.moveToNext();
      //移動(dòng)到上一個(gè)視頻。注意:只能用于url的源。這個(gè)方法不適用于vid的播放。
      aliyunVodPlayer.moveToPrev();
      //移動(dòng)到下一個(gè)視頻。注意:只能用于vid的播放。
      aliyunVodPlayer.moveToNext(StsInfo info);
      // 移動(dòng)到上一個(gè)視頻。注意:只能用于vid的播放。
      aliyunVodPlayer.moveToPrev(StsInfo info);
      //移動(dòng)到下一個(gè)視頻。注意:只能用于vid且使用PlayAuth的播放。
      aliyunVodPlayer.moveToNext(PlayAuthInfo info);
      // 移動(dòng)到上一個(gè)視頻。注意:只能用于vid且使用PlayAuth的播放。
      aliyunVodPlayer.moveToPrev(PlayAuthInfo info);
    • 根據(jù)vid申請(qǐng)PlayAuth信息,申請(qǐng)成功后再進(jìn)行MoveTo或MoveToNext等。

      說明

      只有VidPlayAuth播放才需要根據(jù)vid申請(qǐng)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. 可選:使用預(yù)渲染實(shí)例提升視頻切換的順暢度。

    說明

    Android播放器SDK 5.5.2.0及以上版本才支持本功能,并且需要開啟本地緩存,開啟方法請(qǐng)參見本地緩存

    Android播放器SDK從5.5.2.0版本開始提供getPreRenderPlayermoveToNextWithPrerendered接口,用于提升滑動(dòng)切換到下一個(gè)視頻播放時(shí)的順暢度,根據(jù)您的SDK集成場(chǎng)景不同,其使用方法有所差異,具體如下:

    全新集成5.5.2.0及以后版本

    使用PreRenderPlayer來實(shí)現(xiàn)。示例代碼如下:

    展開查看代碼

    //preRenderPlayer只能在moveToNext時(shí)使用,并且需要開啟本地緩存。
    IPlayer preRenderPlayer = listPlayer.getPreRenderPlayer();
    if (preRenderPlayer != null) {
        //設(shè)置surface
        preRenderPlayer.setSurface(surface);
      preRenderPlayer.start();
      listPlayer.setSurface(null);
      //STS播放方式,將moveToNext接口替換成moveToNextWithPrerendered
      listPlayer.moveToNextWithPrerendered(createStsInfo(source));
    }

    從低版本升級(jí)至5.5.2.0及以后版本

    您需要修改低版本SDK的代碼實(shí)現(xiàn),具體如下:

    1. 修改渲染View。

      低版本的Android播放器SDK全局使用一個(gè)渲染View,在每次切換播放源時(shí),先從布局中remove前一個(gè)View,再添加下一個(gè)View到當(dāng)前界面上。從5.5.2.0版本開始,支持使用多個(gè)渲染View,在RecyclerView.ViewHolder的布局中添加多個(gè)View,在切換播放源時(shí),可以預(yù)加載下一個(gè)播放源,以提升切換的順暢度。您需要?jiǎng)h除低版本的渲染View的代碼,并添加新版本添加多個(gè)渲染View的代碼,示例代碼如下:

      展開查看代碼

      /*
      刪除如下代碼
          如下幾行代碼為低版本添加渲染View的代碼。會(huì)將渲染View添加到FrameLayout中,然后在切換播放源時(shí),會(huì)將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);
          //...
      }
      
      /*
      添加或修改如下代碼以添加多個(gè)渲染View
          修改RecyclerView的item布局,以及對(duì)應(yīng)的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) {}
              });
          }
          //...
      
          //對(duì)外呈現(xiàn)獲取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" />
      
      <!-- 刪除封面圖片,如果效果不好,可以保留封面圖片的相關(guān)邏輯。 -->
      <!--    <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版本開始,在調(diào)用moveToNext時(shí),會(huì)增加對(duì)preRenderPlayer的調(diào)用,因此需要單獨(dú)對(duì)渲染View(Surface)進(jìn)行設(shè)置。其中,moveToNextmoveToPremoveTo的邏輯有所差異。示例代碼如下:

      展開查看代碼

      /*
          說明:mQuickPlayer是AlivcQuickPlayer類的實(shí)例對(duì)象,封裝了ListPlayer的接口。
      */
      private void startPlay(int position, boolean isInitComplete) {
          //...
          //根據(jù)position獲取ViewHolder實(shí)例對(duì)象
          LittleVideoListAdapter.MyHolder holder = (LittleVideoListAdapter.MyHolder) recycler.findViewHolderForLayoutPosition(position);
      
          //...
      
          //1.moveToPre時(shí),先設(shè)置Surface,再調(diào)用moveToPre
          if (holder != null) {
              mQuickPlayer.setSurface(holder.getSurface());
          }
          mQuickPlayer.moveToPrev(video, position, mVideoSourceType);
      
          //2.moveTo時(shí),先設(shè)置Surface,再調(diào)用moveTo
          if (holder != null) {
              mQuickPlayer.setSurface(holder.getSurface());
          }
          //mQuickPlayer.startPlay()內(nèi)部最終會(huì)調(diào)用moveTo()接口
          mQuickPlayer.startPlay(video, position, mVideoSourceType);
      
          //3.moveToPre時(shí),需要增加一個(gè)參數(shù),將Surface傳遞進(jìn)去
          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時(shí),可以獲取preRenderPlayer對(duì)象,并使用該P(yáng)layer播放
          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) {
              //當(dāng)preRenderPlayer不為null時(shí)候,調(diào)用moveToNextWithPrerendered進(jìn)行播放
              if (preRenderPlayer != null) {
                  mVideoListPlayer.moveToNextWithPrerendered(createStsInfo(source));
              } else {
                  mVideoListPlayer.moveToNext(createStsInfo(source));
              }
          } else {
              //URL播放方式
              if (preRenderPlayer != null) {
                  mVideoListPlayer.moveToNextWithPrerendered();
              } else {
                  mVideoListPlayer.moveToNext();
              }
          }
      }
    3. 可選:修改滑動(dòng)播放的邏輯。

      支持通過修改滑動(dòng)播放的邏輯,實(shí)現(xiàn)在滑動(dòng)切換視頻時(shí),當(dāng)滑動(dòng)到下一個(gè)視頻的一半畫面出現(xiàn)時(shí),開始播放下一個(gè)視頻。通過修改PagerLayoutManager類中的代碼實(shí)現(xiàn),即當(dāng)RecyclerView的item出現(xiàn)在屏幕一半時(shí),切換播放源,示例代碼如下:

      展開查看代碼

      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;
                      }
                  }
              }
          }
      });
說明

如果您想要擁有更好的列表播放操作體驗(yàn),推薦使用我們的微短劇解決方案,詳細(xì)內(nèi)容請(qǐng)查看微短劇AUIKit

播放帶透明度視頻

功能簡(jiǎn)介

阿里云播放器SDK支持渲染Alpha通道,實(shí)現(xiàn)播放透明禮物的動(dòng)態(tài)效果。在直播間等場(chǎng)景中,播放透明禮物動(dòng)效且不會(huì)遮擋直播間內(nèi)容,明顯提升用戶觀看和互動(dòng)體驗(yàn)。

使用限制

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

功能優(yōu)勢(shì)

使用帶有透明度信息的MP4視頻作為禮物特效可以提供更好的動(dòng)效質(zhì)量,較小的文件體積,更高的兼容性和更高的開發(fā)效率。這使得禮物特效能夠更好地展示給用戶,提升用戶體驗(yàn)。

  1. 更好的動(dòng)效質(zhì)量:MP4視頻可以保留原始的動(dòng)效質(zhì)量,包括細(xì)節(jié)和顏色等,相比于其他格式,如 APN 或IXD,MP4可以更準(zhǔn)確地還原設(shè)計(jì)師創(chuàng)作的動(dòng)效效果。

  2. 較小的文件體積:MP4視頻文件相比于其他格式,如APNG或IXD,可以更有效地壓縮文件體積,提升加載速度并降低網(wǎng)絡(luò)帶寬消耗。

  3. 更高的兼容性:MP4視頻是一種通用的視頻格式,在各種設(shè)備和瀏覽器中都得到廣泛支持,支持在主流設(shè)備上播放和觀看禮物特效。

  4. 更高的開發(fā)效率:使用MP4視頻作為禮物特效的技術(shù)方案相對(duì)簡(jiǎn)單,不需要開發(fā)人員去研究和實(shí)現(xiàn)復(fù)雜的解析和渲染邏輯,開發(fā)人員可以專注于其他功能的實(shí)現(xiàn),提高開發(fā)效率。

示例代碼

新增如下接口:設(shè)置alpha模式(alpha通道在視頻素材的方位:上、下、左、右),默認(rèn)值是None。

說明
  • 素材的alpha通道的位置要與setAlphaRenderMode參數(shù)設(shè)置的一致。

  • playerview的大小要與素材的分辨率成比例。

/**
 * 設(shè)置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用法-------------
// 對(duì)于View需要設(shè)置透明
//TextureView
TextureView aliplayerView; //用于播放的 view
aliplayerView.setOpaque(false);

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

//-----------AliPlayer用法-----------
//設(shè)置alpha模式
aliplayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
//設(shè)置alpha模式對(duì)應(yīng)的素材
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() {
        //可選:?jiǎn)螌?shí)例播放完成后如果有銜接問題,可以清屏
        aliplayer.clearScreen();
    }
}
aliplayer.setAutoPlay(true);
aliplayer.prepare();

外掛字幕

Android播放器SDK支持添加和切換外掛字幕,現(xiàn)已支持SRT、SSA、ASS、VTT這4種格式的字幕。示例如下:

  1. 創(chuàng)建顯示字幕的View。

    根據(jù)不同的字幕格式創(chuàng)建不同的View。

    展開查看代碼

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

    展開查看代碼

    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回調(diào)后,可通過如下方法進(jìn)行顯示或隱藏字幕:

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

純音頻播放

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

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

軟硬解切換

說明

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

Android播放器SDK提供了H.264、H.265的硬解碼能力,同時(shí)提供了enableHardwareDecoder提供開關(guān)。默認(rèn)開,并且在硬解初始化失敗時(shí),自動(dòng)切換為軟解,保證視頻的正常播放。示例如下:

//開啟硬解。默認(rèn)開啟
mAliyunVodPlayer.enableHardwareDecoder(true);

如果從硬解自動(dòng)切換為軟解,將會(huì)通過onInfo回調(diào),示例如下:

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

H265自適應(yīng)播放

當(dāng)播放H265流硬解失敗且已設(shè)置H264備流時(shí),實(shí)現(xiàn)自動(dòng)降級(jí)播放H264備流;若未設(shè)置H264備流,則自動(dòng)降級(jí)為H265軟解播放。

說明
  • 該功能只有在開通端云結(jié)合自適應(yīng)解碼增值服務(wù)后才會(huì)開啟。您需要提交宜搭表單申請(qǐng)License授權(quán)

  • 端云結(jié)合自適應(yīng)解碼增值服務(wù)主要包含:1、云端硬解兼容性數(shù)據(jù)動(dòng)態(tài)下發(fā);2、H265流自適應(yīng)降級(jí)H264流。

  • SDK依然具備硬解失敗自動(dòng)轉(zhuǎn)換為軟解的功能,即便未開啟增值服務(wù)。

設(shè)置備流示例如下:

// 應(yīng)用層維護(hù)一個(gè)Map,存儲(chǔ)所有原URL-備URL的鍵值對(duì),切換時(shí)根據(jù)原URL在Map中查詢備URL
 AliPlayerGlobalSettings.setAdaptiveDecoderGetBackupURLCallback(new AliPlayerGlobalSettings.OnGetBackupUrlCallback() {
    @Override
    public String getBackupUrlCallback(int oriBizScene, int oriCodecType, String original_url) {
        String kurl = original_url;
        if (!H265toH264Map.get(kurl).isEmpty()) {
            return H265toH264Map.get(kurl);
        } else {
            return "";
        }
    }
});

網(wǎng)絡(luò)自適應(yīng)切換視頻清晰度

說明
  • HLS的多碼率自適應(yīng)視頻流可以在視頻點(diǎn)播中經(jīng)過視頻打包轉(zhuǎn)碼模板組進(jìn)行轉(zhuǎn)碼處理后生成,詳細(xì)操作請(qǐng)參見點(diǎn)播多碼率自適應(yīng)配置

  • 經(jīng)過視頻點(diǎn)播轉(zhuǎn)碼生成的自適應(yīng)流,如果使用Vid方式播放,則需要指定默認(rèn)播放清晰度列表為DEFINITION_AUTO,才會(huì)獲取并播放自適應(yīng)的視頻流;否則將按照默認(rèn)邏輯選擇低清晰度的視頻流進(jìn)行播放,默認(rèn)清晰播放順序請(qǐng)參見清晰度相關(guān)問題。以VidAuth播放方式為例,指定清晰度列表的示例如下:

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

Android播放器SDK支持多碼率自適應(yīng)HLS、DASH視頻流。在prepare成功之后,通過getMediaInfo可以獲取到各個(gè)碼流的信息,即TrackInfo。示例如下:

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

在播放過程中,可以通過調(diào)用播放器的selectTrack方法切換播放的碼流,取值為AUTO_SELECT_INDEX時(shí),為多碼率自適應(yīng)。示例如下:

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

切換的結(jié)果會(huì)在OnTrackChangedListener監(jiān)聽之后會(huì)回調(diào)(在調(diào)用selectTrack之前設(shè)置)。示例如下:

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

可選:在調(diào)用播放器selectTrack方法切換播放碼流為多碼率自適應(yīng)前,可以通過config設(shè)置自適應(yīng)碼率(ABR)切換的清晰度上限,以避免自動(dòng)切換到預(yù)期之外的碼率。示例如下:(建議在播放器調(diào)用prepare方法,或者列表播放器調(diào)用moveTo方法前調(diào)用下述代碼,使其生效。)

PlayerConfig config = mAliyunVodPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; //設(shè)置abr清晰度上限對(duì)應(yīng)的像素?cái)?shù)量為921600(長(zhǎng) * 寬 = 1280 * 720),使得abr允許切換的清晰度對(duì)應(yīng)的像素?cái)?shù)量 <= 該值
mAliyunVodPlayer.setConfig(config);

截圖

Android播放器SDK提供了對(duì)當(dāng)前視頻截圖的功能,由snapshot接口實(shí)現(xiàn)。截取的是原始的數(shù)據(jù),并轉(zhuǎn)為bitmap返回。回調(diào)接口為OnSnapShotListener。示例如下:

//設(shè)置截圖回調(diào)
aliyunVodPlayer.setOnSnapShotListener(new OnSnapShotListener(){
    @Override
    public void onSnapShot(Bitmap bm, int with, int height){
        //獲取到的bitmap以及圖片的寬高。
    }
});
//截取當(dāng)前播放的畫面
aliyunVodPlayer.snapshot();

試看

Android播放器SDK通過配合點(diǎn)播服務(wù)配置,可以實(shí)現(xiàn)試看功能,支持VidSts和VidAuth(視頻點(diǎn)播推薦使用此方式)兩種播放方式。如何配置和使用試看功能,請(qǐng)參見試看視頻

配置試看功能之后,通過VidPlayerConfigGen.setPreviewTime()方法設(shè)置播放器的試看時(shí)長(zhǎng)。以VidSts播放方式為例,示例如下:

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

當(dāng)設(shè)置試看的時(shí)長(zhǎng),通過Android播放器SDK播放視頻時(shí),服務(wù)端將不會(huì)返回完整的視頻內(nèi)容,而是返回試看時(shí)間段的內(nèi)容。

說明
  • VidPlayerConfigGen支持設(shè)置服務(wù)端支持的請(qǐng)求參數(shù)。請(qǐng)參見請(qǐng)求參數(shù)說明

  • FLV和MP3格式視頻暫時(shí)不支持試看。

設(shè)置黑名單

Android播放器SDK提供了硬解的黑名單機(jī)制。對(duì)于明確不能使用硬解播放的機(jī)器,可以直接使用軟解,避免了無效的操作。示例如下:

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

退出App之后,黑名單自動(dòng)失效。

設(shè)置Referer

Android播放器SDK支持設(shè)置Referer,配合控制臺(tái)的黑白名單Referer,可以控制訪問權(quán)限,由PlayerConfig方法設(shè)置請(qǐng)求Referer。播放器SDK的設(shè)置示例如下:

//先獲取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//設(shè)置referer,示例:http://example.aliyundoc.com。(注意:設(shè)置referer時(shí),需要加上前面的協(xié)議部分。)
config.mReferrer = referrer;
....//其他設(shè)置
  //設(shè)置配置給播放器
mAliyunVodPlayer.setConfig(config);

設(shè)置UserAgent

Android播放器SDK提供了PlayerConfig用來設(shè)置請(qǐng)求UA。設(shè)置之后,播放器請(qǐng)求的過程中將會(huì)帶上UA信息。示例如下:

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

配置網(wǎng)絡(luò)重試時(shí)間和次數(shù)

支持設(shè)置Android播放器SDK的網(wǎng)絡(luò)超時(shí)的時(shí)間和重試次數(shù),由PlayerConfig方法實(shí)現(xiàn)。示例如下:

//先獲取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//設(shè)置網(wǎng)絡(luò)超時(shí)時(shí)間,單位:毫秒
config.mNetworkTimeout = 5000;
//設(shè)置超時(shí)重試次數(shù)。每次重試間隔為networkTimeout。networkRetryCount=0則表示不重試,重試策略app決定,默認(rèn)值為2
config.mNetworkRetryCount=2;
....//其他設(shè)置
  //設(shè)置配置給播放器
mAliyunVodPlayer.setConfig(config);
說明
  • 如果設(shè)置了NetworkRetryCount,若此時(shí)發(fā)生網(wǎng)絡(luò)問題,導(dǎo)致出現(xiàn)loading后,那么將會(huì)重試NetworkRetryCount次,每次的間隔時(shí)間為mNetworkTimeout。

  • 如果重試多次之后,還是loading的狀態(tài),那么就會(huì)回調(diào)onError事件,此時(shí),ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT。

  • 如果NetworkRetryCount設(shè)置為0,當(dāng)網(wǎng)絡(luò)重試超時(shí)的時(shí)候,播放器就會(huì)回調(diào)onInfo事件,事件的InfoBean.getCode()=InfoCode.NetworkRetry。 此時(shí),可以調(diào)用播放器的reload方法進(jìn)行重新加載網(wǎng)絡(luò),或者進(jìn)行其他的處理。

配置緩存和延遲控制

Android播放器SDK通過PlayerConfig提供了設(shè)置緩存和延遲的控制接口。示例如下:

展開查看代碼

//先獲取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//最大延遲。注意:直播有效。當(dāng)延時(shí)比較大時(shí),播放器sdk內(nèi)部會(huì)追幀等,保證播放器的延時(shí)在這個(gè)范圍內(nèi)。
config.mMaxDelayTime = 5000;
// 最大緩沖區(qū)時(shí)長(zhǎng)。單位ms。播放器每次最多加載這么長(zhǎng)時(shí)間的緩沖數(shù)據(jù)。
config.mMaxBufferDuration = 50000;
//高緩沖時(shí)長(zhǎng)。單位ms。當(dāng)網(wǎng)絡(luò)不好導(dǎo)致加載數(shù)據(jù)時(shí),如果加載的緩沖時(shí)長(zhǎng)到達(dá)這個(gè)值,結(jié)束加載狀態(tài)。
config.mHighBufferDuration = 3000;
// 起播緩沖區(qū)時(shí)長(zhǎng)。單位ms。這個(gè)時(shí)間設(shè)置越短,起播越快。也可能會(huì)導(dǎo)致播放之后很快就會(huì)進(jìn)入加載狀態(tài)。
config.mStartBufferDuration = 500;
....//其他設(shè)置
//往前緩存的最大時(shí)長(zhǎng)。單位ms。默認(rèn)為0。
config.mMaxBackwardBufferDurationMs = 0;

//設(shè)置配置給播放器
mAliyunVodPlayer.setConfig(config);
重要
  • 三個(gè)緩沖區(qū)時(shí)長(zhǎng)的大小關(guān)系必須為:mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration。

  • 當(dāng)最大緩沖區(qū)時(shí)長(zhǎng)(mMaxBufferDuration)大于5分鐘時(shí),為防止因?yàn)榫彌_區(qū)過大導(dǎo)致的內(nèi)存異常,系統(tǒng)將默認(rèn)按5分鐘生效。當(dāng)mMaxBufferDuration設(shè)置超過50000 ms(即50s)時(shí),可以啟用大緩存,來降低內(nèi)存占用,進(jìn)一步提高播放性能,如有需要,請(qǐng)參見大緩存

設(shè)置HTTP Header

通過PlayerConfig方法,可以給播放器中的請(qǐng)求加上HTTP的header參數(shù)。示例如下:

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

直播RTS降級(jí)

RTS自動(dòng)降級(jí)

在使用超低延時(shí)直播RTS地址播放的場(chǎng)景下,當(dāng)不設(shè)置RTS降級(jí)地址且RTS拉流失敗時(shí),會(huì)自動(dòng)降級(jí)到RTS對(duì)應(yīng)的默認(rèn)flv地址進(jìn)行播放。示例如下:

// 1表示開啟,0表示關(guān)閉。默認(rèn)開啟
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.ALLOW_RTS_DEGRADE, 1);

RTS自定義降級(jí)

在使用超低延時(shí)直播RTS地址播放的場(chǎng)景下,通過設(shè)置RTS的降級(jí)地址(如HLS地址或FLV地址),當(dāng)RTS拉流失敗時(shí),會(huì)自動(dòng)降級(jí)到該地址播放。示例如下:

PlayerConfig config = player.getConfig();
//可選,配置config其他項(xiàng)
UrlSource urlSource = new UrlSource();
urlSource.setUri(downgradeUrl);
//設(shè)置降級(jí)URL
player.enableDowngrade(urlSource, config);

切換左右聲道

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

說明

下述輸出聲道的設(shè)置會(huì)同時(shí)影響音頻渲染及PCM數(shù)據(jù)回調(diào)。

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

解析音頻流

設(shè)置監(jiān)聽,可獲取音視頻流數(shù)據(jù)。音視頻不能是加密流,加密流無法解析。

展開查看代碼

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

//可選配置2:硬解時(shí),RenderFrame返回 texture_oes_id,軟解時(shí),RenderFrame返回源數(shù)據(jù)
player.enableHardwareDecoder(true);
//設(shè)置監(jiān)聽,獲取音視頻數(shù)據(jù)
player.setOnRenderFrameCallback(frameInfo -> {
    if (frameInfo.frameType == FrameInfo.FrameType_video) {
        //視頻數(shù)據(jù)
    } else {
        //音頻數(shù)據(jù)
    }
    return false;
});

設(shè)置視頻背景色

Android播放器SDK支持設(shè)置播放器渲染的背景色。接口和用法說明如下:

接口示例

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

用法說明

//參數(shù)為8位16進(jìn)制數(shù)據(jù),8位數(shù)據(jù)兩兩為一組,按照順序分別表示A(alpha 透明度) R(red) G(green) B(blue)
//例如0x0000ff00,表示綠色
player.setVideoBackgroundColor(0x0000ff00);

vidAuth設(shè)置指定播放域名

通過vidAuth方式可以指定vid對(duì)應(yīng)的域名等字段,支持的字段詳情請(qǐng)參見GetPlayInfo請(qǐng)求參數(shù)。接口及用法說明如下:

接口示例

/**
 * 設(shè)置播放參數(shù)
 *
 * @param playConfig 播放參數(shù)
 */
public void setPlayConfig(VidPlayerConfigGen playConfig);

用法說明

通過其中的VidPlayerConfigGen接口的addPlayerConfig添加playDomain字段。

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
//增加playDomain字段,可以添加的字段參考
//http://bestwisewords.com/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo?spm=a2c4g.11186623.0.0.2bec2e44eqeDgx#api-detail-35
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);

性能

預(yù)渲染

Android播放器SDK支持在起播之前快速渲染第一幀。示例如下:

player.setOption(ALLOW_PRE_RENDER, 1);

本地緩存

Android播放器SDK提供了本地緩存的功能,能夠讓用戶重復(fù)播放視頻時(shí),提高起播速度、提高seek速度、減少卡頓,也能達(dá)到節(jié)省流量的目的。

開啟本地緩存

本地緩存功能默認(rèn)關(guān)閉,如需使用,需要手動(dòng)開啟。通過AliPlayerGlobalSettings中的enableLocalCache控制。示例如下:

展開查看代碼

/**
 *  開啟本地緩存,開啟之后,會(huì)緩存到本地文件中。
 *
 *  @param enable - 本地緩存功能開關(guān)。true:開啟本地緩存,false:關(guān)閉,默認(rèn)關(guān)閉。
 *  @param maxBufferMemoryKB - 5.4.7.1及以后版本已廢棄,暫無作用
 *  @param localCacheDir - 本地緩存的文件目錄,為絕對(duì)路徑。
 */
public static void enableLocalCache(boolean enable,
                                    int maxBufferMemoryKB,
                                    java.lang.String localCacheDir)

 /**
  * 本地緩存文件清理相關(guān)配置。
  *
  * @param expireMin - 5.4.7.1及以后版本已廢棄,暫無作用。
  * @param maxCapacityMB - 最大緩存容量。單位:兆,默認(rèn)值20GB,在清理時(shí),如果緩存總?cè)萘砍^此大小,則會(huì)以cacheItem為粒度,按緩存的最后時(shí)間排序,一個(gè)一個(gè)的刪除最舊的緩存文件,直到小于等于最大緩存容量。
  * @param freeStorageMB - 磁盤最小空余容量。單位:兆,默認(rèn)值0,在清理時(shí),同最大緩存容量,如果當(dāng)前磁盤容量小于該值,也會(huì)按規(guī)則一個(gè)一個(gè)的刪除緩存文件,直到freeStorage大于等于該值或者所有緩存都被清理掉。
  */
 public static void setCacheFileClearConfig(long expireMin,
                                           long maxCapacityMB,
                                           long freeStorageMB)

  /**
   * 設(shè)置加載url的hash值回調(diào)。如果不設(shè)置,SDK使用md5算法。
   */
  public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
說明
  • 如果視頻播放URL帶有鑒權(quán)參數(shù),本地緩存和播放時(shí)鑒權(quán)參數(shù)會(huì)變化,為提高相同URL在不同鑒權(quán)下的緩存命中率,可以將URL的鑒權(quán)參數(shù)去掉后再通過setCacheUrlHashCallback接口計(jì)算Hash值(例如MD5)。例如:帶有鑒權(quán)參數(shù)的視頻播放URL為http://****.mp4?aaa,則加載時(shí)使用http://****.mp4計(jì)算Hash值。但如果視頻為經(jīng)過加密后的m3u8視頻,其keyURL若按照去掉鑒權(quán)參數(shù)再計(jì)算Hash值的方式處理,會(huì)導(dǎo)致不同視頻的緩存命中同一個(gè)key導(dǎo)致播放失敗。解決方案:您可以在setCacheUrlHashCallback的回調(diào)里進(jìn)行域名判斷,僅對(duì)播放域名(http(s)://xxxxx.m3u8?aaaa)做去掉鑒權(quán)參數(shù)的處理,而keyURL對(duì)應(yīng)的域名(http(s)://yyyyy?bbbb)不做去掉鑒權(quán)參數(shù)的處理。進(jìn)階功能-本地緩存.png

  • 如果服務(wù)器同時(shí)支持HTTP和HTTPS協(xié)議,但是不同的協(xié)議指向的媒體文件是同一個(gè),則可以將請(qǐng)求頭去掉或者統(tǒng)一后再計(jì)算Hash值。例如:

    • 視頻播放URL為https://****.mp4http://****.mp4,則加載時(shí)使用****.mp4計(jì)算hash值。

    • 視頻播放URL為https://****.mp4,加載時(shí)統(tǒng)一為http://****.mp4后再計(jì)算Hash值。

  • 針對(duì)5.5.4.0及以后版本的播放器SDK,如果視頻播放URL帶有鑒權(quán)參數(shù)且播放協(xié)議為HLS,可以通過設(shè)置PlayerConfig.mEnableStrictAuthMode字段,進(jìn)行不同鑒權(quán)模式的選擇(默認(rèn)值為false):

    • 非嚴(yán)格鑒權(quán)(false):鑒權(quán)也緩存,若上一次只緩存了部分媒體,下次播放至非緩存部分時(shí),播放器會(huì)用緩存的鑒權(quán)發(fā)起請(qǐng)求,如果URL鑒權(quán)設(shè)置的有效期很短,會(huì)導(dǎo)致播放異常。

    • 嚴(yán)格鑒權(quán)(true):鑒權(quán)不緩存,每次起播都進(jìn)行鑒權(quán),無網(wǎng)絡(luò)下會(huì)導(dǎo)致起播失敗。

開啟或關(guān)閉單個(gè)URL的本地緩存

如果想要針對(duì)單個(gè)URL開啟或關(guān)閉本地緩存功能,可以在player config中設(shè)置。

//先獲取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//是否針對(duì)播放的URL開啟本地緩存,默認(rèn)值為true。當(dāng)AliPlayerGlobalSettings處的本地緩開啟時(shí),且同時(shí)開啟此處的本地緩存,即設(shè)置為true,該URL的本地緩存才會(huì)生效;若此處設(shè)置為false,則關(guān)閉該URL的本地緩存。
config.mEnableLocalCache = false;
....//其他設(shè)置

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

使用默認(rèn)緩存路徑

如果想要使用默認(rèn)路徑進(jìn)行緩存,可以通過AliPlayerGlobalSettings進(jìn)行如下設(shè)置。

/**
 * 開啟本地緩存,開啟之后,就會(huì)緩存到本地文件中。
 * @param enable true:開啟本地緩存。false:關(guān)閉。默認(rèn)關(guān)閉。
 */
/****
 * Enable local cache. When enabled, it will be cached in local files.
 * @param enable true: enables the local cache. false: disable. This function is disabled by default.
 * @param context The context.
 */
public static String enableLocalCache(boolean enable, Context context)

大緩存

通過設(shè)置數(shù)據(jù)的最大緩沖區(qū)時(shí)長(zhǎng)可以在播放視頻時(shí)通過緩存視頻數(shù)據(jù)到內(nèi)存中,從而提高播放性能和觀看體驗(yàn)。當(dāng)最大緩沖區(qū)時(shí)長(zhǎng)設(shè)置過大時(shí),會(huì)造成緩沖區(qū)對(duì)內(nèi)存的消耗。通過啟用大緩存,可以將視頻數(shù)據(jù)緩存到文件中,從而降低內(nèi)存的占用,進(jìn)一步提高播放器性能。

當(dāng)mMaxBufferDuration設(shè)置超過50000 ms時(shí),通過開啟本地緩存觸發(fā)大緩存功能自動(dòng)啟用。操作流程如下:

  1. 開啟全局本地緩存。

    本地緩存功能默認(rèn)關(guān)閉,如需使用,需要手動(dòng)開啟。通過AliPlayerGlobalSettings中的enableLocalCache控制。代碼示例請(qǐng)參見本地緩存中的開啟本地緩存

  2. 開啟URL的本地緩存。

    代碼示例請(qǐng)參見本地緩存中的開啟或關(guān)閉單個(gè)URL的本地緩存

  3. 開啟大緩存。

    AliPlayerGlobalSettings.enableBufferToLocalCache(true);

預(yù)加載

Android播放器SDK提供預(yù)加載功能,是對(duì)本地緩存功能的升級(jí),通過設(shè)置視頻緩存的內(nèi)存占用大小,更能提升視頻的起播速度。

預(yù)加載功能的使用限制如下:

  • 目前支持MP4、MP3、FLV、HLS等單個(gè)媒體文件的加載。

  • 僅支持UrlSource播放方式播放視頻的預(yù)加載,暫不支持VidAuth、VidSts方式播放視頻的預(yù)加載。

說明

Android播放器SDK默認(rèn)提供預(yù)加載時(shí)網(wǎng)絡(luò)資源自動(dòng)調(diào)度能力,以減少預(yù)加載的網(wǎng)絡(luò)請(qǐng)求對(duì)正在播放視頻的網(wǎng)絡(luò)請(qǐng)求的影響。自動(dòng)調(diào)度的策略是:僅當(dāng)正在播放的視頻緩沖到達(dá)一定閾值后,才會(huì)允許預(yù)加載進(jìn)行請(qǐng)求。若您需要自行控制預(yù)加載的實(shí)時(shí)請(qǐng)求,可以通過以下方法將此策略關(guān)閉:

AliPlayerGlobalSettings.enableNetworkBalance(false);
  1. 開啟本地緩存功能,詳細(xì)操作請(qǐng)參見本地緩存

  2. 獲取AliMediaLoader實(shí)例。

    AliMediaLoader實(shí)例為單例,即無論獲取多少次,創(chuàng)建的都是同一個(gè)實(shí)例。

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

    配置回調(diào),并開始加載。

    說明

    playerprepare時(shí)刻與mediaLoader.load的調(diào)用時(shí)刻一致,由于都需要遍歷本地文件,則可能導(dǎo)致出現(xiàn)ANR的問題。建議設(shè)置為當(dāng)playeronPrepared回調(diào)中時(shí),才開始加載。

    展開查看代碼

    /**
     * 設(shè)置加載狀態(tài)回調(diào)
     */
    mediaLoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
        @Override
        public void onErrorV2(String url, ErrorInfo errorInfo) {
            //加載出錯(cuò)
        }
    
        @Override
        public void onCompleted(String s) {
            //加載完成
        }
    
        @Override
        public void onCanceled(String s) {
            //加載取消
        }
    });
    /**
     * 開始加載文件。異步加載。可以同時(shí)加載多個(gè)視頻文件。
     * @param url - 視頻文件地址。
     * @param duration - 加載的時(shí)長(zhǎng)大小,單位:毫秒。
     */
    mediaLoader.load("url","duration");
  4. 可選:刪除加載文件。

    可按需刪除加載文件,以節(jié)省空間。Android播放器SDK不提供刪除接口,需要在App刪除加載目錄下的文件。

動(dòng)態(tài)預(yù)加載

動(dòng)態(tài)預(yù)加載策略,支持集成方既可以控制當(dāng)前正在播放視頻的緩存,又可以控制預(yù)加載的個(gè)數(shù)和緩存,滿足業(yè)務(wù)方對(duì)播放體驗(yàn)與成本開銷之間取得平衡的訴求。

展開查看代碼

// 開啟推薦配置和動(dòng)態(tài)預(yù)加載
ListPlayer.setPreloadScene(IListPlayer.SceneType.SCENE_SHORT);

// 配置基準(zhǔn)預(yù)加載時(shí)長(zhǎng)
// 設(shè)置預(yù)加載時(shí)長(zhǎng)為1000ms
PreloadConfig config = new PreloadConfig();
config.mPreloadDuration = 1000;
ListPlayer.updatePreloadConfig(config);

// 配置預(yù)加載的數(shù)量,支持雙向
// 1為向前預(yù)加載的數(shù)量,3為向后預(yù)加載的數(shù)量
ListPlayer.setPreloadCount(1, 3);

// 配置動(dòng)態(tài)預(yù)加載的遞減的offset
ListPlayer.enablePreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, true);
ListPlayer.setPreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, "{\"algorithm\": \"sub\",\"offset\": \"200\"}");

多碼率HLS視頻預(yù)加載

listPlayer+多碼率HLS視頻播放場(chǎng)景下,支持集成方預(yù)加載與當(dāng)前播放清晰度一致的流,并且可以根據(jù)業(yè)務(wù)情況選擇預(yù)加載模式。

展開查看支持的預(yù)加載模式

  /**
   * 默認(rèn)配置,播放和預(yù)加載默認(rèn)碼率
   */
  /****
   * default mode, play and preload default bitrate of a stream
   */
  MultiBitratesMode_Default(0),

  /**
   * 首幀優(yōu)先配置,起播視頻默認(rèn)播放已完成預(yù)加載的碼率
   */
  /****
   * 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),

  /**
   * 播放平滑優(yōu)先配置,起播視頻默認(rèn)播放前一個(gè)視頻的碼率
   */
  /****
   * Play Smooth priority, play the same bitrate before and after moveToNext.
   */
  MultiBitratesMode_SmoothPrio(3);

展開查看集成代碼

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


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


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

獲取下載速度

獲取當(dāng)前播放視頻的下載速度,在onInfo回調(diào)中獲取,由getExtraValue接口實(shí)現(xiàn)。示例如下:

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

網(wǎng)絡(luò)特性

HTTPDNS

HTTPDNS是通過DNS解析技術(shù)將域名解析請(qǐng)求發(fā)送到特定的HTTPDNS服務(wù)器,以獲取更快、更穩(wěn)定的域名解析結(jié)果,降低DNS劫持風(fēng)險(xiǎn)。

阿里云播放器SDK提供增強(qiáng)型HTTPDNS功能,專為阿里云CDN域名提供HTTPDNS服務(wù),支持阿里云CDN網(wǎng)絡(luò)精準(zhǔn)調(diào)度、實(shí)時(shí)解析生效,有效提高網(wǎng)絡(luò)性能。

說明

播放器SDK從6.7.0版本開始支持增強(qiáng)型HTTPDNS。6.7.0~6.11.0版本播放器SDK,請(qǐng)先提交工單或聯(lián)系阿里云商務(wù)經(jīng)理申請(qǐng)開通;6.12.0及以后版本無需申請(qǐng),默認(rèn)開啟。

增強(qiáng)型HTTPDNS使用示例

增強(qiáng)型HTTPDNS僅為阿里云CDN域名提供HTTPDNS服務(wù),請(qǐng)確保您配置的域名為阿里云CDN域名且已完成域名配置可正常使用。視頻點(diǎn)播中添加和配置CDN域名請(qǐng)參見添加加速域名。更多有關(guān)CDN域名的信息請(qǐng)參見阿里云CDN

//打開增強(qiáng)型httpdns
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
//可選,增加httpdns預(yù)解析域名
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");

HTTP/2

說明

Android播放器SDK自5.5.0.0版本開始默認(rèn)開啟使用HTTP/2。

Android播放器SDK支持使用HTTP/2協(xié)議,該協(xié)議通過多路復(fù)用,避免隊(duì)頭阻塞,以改善播放性能。示例如下:

AliPlayerGlobalSettings.setUseHttp2(true);

HTTP預(yù)建連TCP

針對(duì)HTTP的視頻播放請(qǐng)求(非HTTPS),通過提前建立TCP連接能夠顯著改善用戶體驗(yàn),降低網(wǎng)絡(luò)連接耗時(shí),確保播放的即時(shí)性與連續(xù)性,同時(shí)優(yōu)化網(wǎng)絡(luò)和系統(tǒng)資源的使用效率。使用方式如下:

// domain格式為host[:port],port可選,用分號(hào)(;)隔開多個(gè)域名
// 全局設(shè)置
// 全量接口每次設(shè)置后使用當(dāng)前的字符串為準(zhǔn)(多-新增,少-刪除),字符串空為停止預(yù)建連
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");

視頻下載

Android播放器SDK提供了點(diǎn)播服務(wù)視頻的下載功能,允許用戶通過阿里云播放器將視頻緩存至本地觀看。同時(shí),提供了普通下載和安全下載兩種下載方式。

  • 普通下載

    下載后的視頻數(shù)據(jù)未經(jīng)過阿里云加密,用戶可以用第三方播放器播放。

  • 安全下載

    下載后的視頻數(shù)據(jù)經(jīng)過阿里云加密。第三方播放器無法播放。僅支持使用阿里云的播放器進(jìn)行播放。

使用說明

  • 僅VidSts和VidAuth方式支持視頻下載功能。

  • 使用播放器的視頻下載功能,需要在點(diǎn)播控制臺(tái)開啟并配置下載模式,詳細(xì)操作請(qǐng)參見離線下載

  • 視頻下載支持?jǐn)帱c(diǎn)續(xù)傳。

操作步驟

  1. 可選:配置安全下載的加密校驗(yàn)文件。僅安全下載需要配置,普通下載無需配置。

    說明

    請(qǐng)確保配置的加密校驗(yàn)文件與App信息一致,否則會(huì)導(dǎo)致視頻下載失敗。

    如果設(shè)置為安全下載方式,則需要將在點(diǎn)播控制臺(tái)生成的密鑰文件配置到播放器SDK中,用于視頻下載和播放的解密驗(yàn)證,密鑰文件的生成請(qǐng)參見開啟安全下載

    建議在Application中配置一次即可,示例如下:

    PrivateService.initService(getApplicationContext(),  "encryptedApp.dat所在的文件路徑"); //建議將encryptedApp.dat加密校驗(yàn)文件存放到手機(jī)中后,此處設(shè)置加密校驗(yàn)文件的手機(jī)本地文件路徑
  2. 創(chuàng)建并設(shè)置下載器。

    創(chuàng)建下載器,通過AliDownloaderFactory創(chuàng)建。示例如下:

    AliMediaDownloader mAliDownloader = null;
    ......
    //創(chuàng)建下載器
    mAliDownloader = AliDownloaderFactory.create(getApplicationContext());
    //配置下載保存的路徑
    mAliDownloader.setSaveDir("保存的文件夾地址");
  3. 設(shè)置監(jiān)聽事件。

    下載器提供了多個(gè)事件監(jiān)聽。示例如下:

    展開查看代碼

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

    通過prepare方法準(zhǔn)備下載源。下載源支持VidSts和VidAuth兩種方式。示例如下:

    • VidSts

      //創(chuàng)建VidSts
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("Vid信息");// 視頻ID(VideoId)。
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>");// STS臨時(shí)AK對(duì)的訪問密鑰ID,需要調(diào)用STS服務(wù)的AssumeRole接口生成。
      aliyunVidSts.setAccessKeySecret"<yourAccessKeySecret>");// STS臨時(shí)AK對(duì)的訪問密鑰,需要調(diào)用STS服務(wù)的AssumeRole接口生成。
      aliyunVidSts.setSecurityToken("<yourSecurityToken>");// STS安全令牌,需要調(diào)用STS服務(wù)的AssumeRole接口生成。
      aliyunVidSts.setRegion("接入地域");// 點(diǎn)播服務(wù)的接入地域,默認(rèn)為cn-shanghai。
      //準(zhǔn)備下載源
      mAliDownloader.prepare(aliyunVidSts)
    • VidAuth

      //創(chuàng)建VidAuth
      VidAuth vidAuth = new VidAuth();
      vidAuth.setVid("Vid信息");// 視頻ID(VideoId)。
      vidAuth.setPlayAuth("<yourPlayAuth>");// 播放憑證,需要調(diào)用點(diǎn)播服務(wù)的GetVideoPlayAuth接口生成。
      vidAuth.setRegion("接入地域");// 5.5.5.0及之后版本播放器SDK,本參數(shù)已棄用,無需設(shè)置region,播放器會(huì)自動(dòng)解析region;5.5.5.0之前版本播放器SDK,本參數(shù)必選,點(diǎn)播服務(wù)的接入地域,默認(rèn)為cn-shanghai。
      //準(zhǔn)備下載源
      mAliDownloader.prepare(vidAuth);
    說明

    源文件格式與輸出的下載文件格式保持一致,不支持更改。

  5. 準(zhǔn)備成功后,選擇下載項(xiàng)并開始下載。

    準(zhǔn)備成功后,會(huì)回調(diào)OnPreparedListener方法。返回的TrackInfo中會(huì)包含各視頻流的清晰度等信息,請(qǐng)選擇一個(gè)Track進(jìn)行下載,示例如下:

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

    為了防止VidSts和VidAuth過期,您也可以更新下載源的信息后開始下載。示例如下:

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

    下載成功后,在onCompletion或者onError回調(diào)中調(diào)用release釋放下載器。示例如下:

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

    下載過程中,或者下載完成后,可以刪除下載的文件。示例如下:

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

后續(xù)操作

下載的視頻可以使用阿里云播放器進(jìn)行播放。具體方法如下:

  1. 下載完成后獲取視頻文件的絕對(duì)路徑。

    String path = mAliDownloader.getFilePath();
  2. 通過點(diǎn)播UrlSource方式設(shè)置絕對(duì)路徑進(jìn)行播放。

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

視頻加密播放

點(diǎn)播視頻支持HLS標(biāo)準(zhǔn)加密、阿里云私有加密和DRM加密,直播視頻僅支持DRM加密。加密播放請(qǐng)參見視頻加密播放

Native RTS播放

Android播放器SDK集成Native RTS SDK實(shí)現(xiàn)Native端低延時(shí)直播功能,詳情請(qǐng)參見阿里云播放器SDK集成Native RTS SDK實(shí)現(xiàn)說明(Android端)

異常處理

使用阿里云播放器播放視頻發(fā)生異常時(shí),可借助單點(diǎn)探查功能快速定位問題,詳細(xì)內(nèi)容,請(qǐng)參見單點(diǎn)追查

相關(guān)文檔