进阶功能

本文介绍Android播放器SDK进阶功能的使用示例,更多功能的支持和使用请参见API说明

播放

短视频列表播放

针对典型的短视频列表播放场景,Android播放器SDK提供了完善的列表播放功能,结合预加载等机制大幅改善短视频的起播速度。长视频场景不建议使用该功能。

使用限制

AliListPlayer存在以下限制,推荐使用多个AliPlayer的方式来实现短视频列表播放,详细内容请参见沉浸式短视频

  • 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) {
            //切换到软解
        }
    }
});

H265自适应播放

当播放H265流硬解失败且已设置H264备流时,实现自动降级播放H264备流;若未设置H264备流,则自动降级为H265软解播放。

说明
  • 该功能只有在开通端云结合自适应解码增值服务后才会开启。您需要提交宜搭表单申请License授权

  • 端云结合自适应解码增值服务主要包含:1、云端硬解兼容性数据动态下发;2、H265流自适应降级H264流。

  • SDK依然具备硬解失败自动转换为软解的功能,即便未开启增值服务。

设置备流示例如下:

// 应用层维护一个Map,存储所有原URL-备URL的键值对,切换时根据原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 "";
        }
    }
});

网络自适应切换视频清晰度

说明
  • HLS的多码率自适应视频流可以在视频点播中经过视频打包转码模板组进行转码处理后生成,详细操作请参见点播多码率自适应配置

  • 经过视频点播转码生成的自适应流,如果使用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(视频点播推荐使用此方式)两种播放方式。如何配置和使用试看功能,请参见试看视频

配置试看功能之后,通过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);

打开RTS降级开关

在使用超低延时直播RTS地址播放的场景下,当不设置RTS降级地址且RTS拉流失败时,会自动降级到RTS对应的默认HLS地址进行播放。示例如下:

// 1表示开启,0表示关闭。默认开启
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.ALLOW_RTS_DEGRADE, 1);

切换左右声道

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位数据两两为一组,按照顺序分别表示A(alpha 透明度) R(red) G(green) B(blue)
//例如0x0000ff00,表示绿色
player.setVideoBackgroundColor(0x0000ff00);

vidAuth设置指定播放域名

通过vidAuth方式可以指定vid对应的域名等字段,支持的字段详情请参见GetPlayInfo请求参数。接口及用法说明如下:

接口示例

/**
 * 设置播放参数
 *
 * @param playConfig 播放参数
 */
public void setPlayConfig(VidPlayerConfigGen playConfig);

用法说明

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

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
//增加playDomain字段,可以添加的字段参考
//https://help.aliyun.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);

性能

预渲染

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

player.setOption(ALLOW_PRE_RENDER, 1);

本地缓存

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);

使用默认缓存路径

如果想要使用默认路径进行缓存,可以通过AliPlayerGlobalSettings进行如下设置。

/**
 * 开启本地缓存,开启之后,就会缓存到本地文件中。
 * @param enable true:开启本地缓存。false:关闭。默认关闭。
 */
/****
 * 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)

大缓存

通过设置数据的最大缓冲区时长可以在播放视频时通过缓存视频数据到内存中,从而提高播放性能和观看体验。当最大缓冲区时长设置过大时,会造成缓冲区对内存的消耗。通过启用大缓存,可以将视频数据缓存到文件中,从而降低内存的占用,进一步提高播放器性能。

当mMaxBufferDuration设置超过50000 ms时,通过开启本地缓存触发大缓存功能自动启用。操作流程如下:

  1. 开启全局本地缓存。

    本地缓存功能默认关闭,如需使用,需要手动开启。通过AliPlayerGlobalSettings中的enableLocalCache控制。代码示例请参见本地缓存中的开启本地缓存

  2. 开启URL的本地缓存。

    代码示例请参见本地缓存中的开启或关闭单个URL的本地缓存

  3. 开启大缓存。

    AliPlayerGlobalSettings.enableBufferToLocalCache(true);

预加载

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 onErrorV2(String url, ErrorInfo errorInfo) {
            //加载出错
        }
    
        @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域名且已完成域名配置可正常使用。视频点播中添加和配置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端)

异常处理

使用阿里云播放器播放视频发生异常时,可借助单点探查功能快速定位问题,详细内容,请参见单点追查

相关文档