功能简介 点播(VOD):

通过LSS服务发起推流的直播会存储在云端生成一个视频文件 , 只要这个视频文件没有被移除, 点播功能就可以随时去播放这些视频文件,点播的场景就如爱奇艺、优酷等,可以自由的拖动进度条去控制当前播放的视频文件。

调用流程及API介绍:

1.1 创建 VHVodPlayer

VHVodPlayer 是SDK中负责点播的模块,需要传入上下文,和视频渲染的View,也就是播放画面的View,SDK使用的是系统自带的SurfaceView,将创建的Surface的实例传入VHVodPlayer即可创建。

  • Context 传入上下文
  • SurfaceView 传入渲染的View
  • addListener 添加监听
 mPlayer = new VHVodPlayer(this, mSurfaceView);
 mPlayer.addListener(new MyPlayer());

2 VHDocument

2.1 创建 VHDocumentView 文档

如果当前的视频文件存在文档信息, 在观看点播的过程中是可以和文档一起观看的,使用SDK中提供的VHDocumentView View 控件。 通过FindById获取View的实例。

 <com.vhall.ops.VHDocumentView
        android:id="@+id/doc"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

2.2 创建 VHDocument 对象

将2.1 创建的View 设置进VHDocument , 用于文档的显示。

  • recordId 点播id 可以通过调用 api 创建 (这里的recordId 必须和Start发起的recordId 一致)
 mDoc = new VHDocument(recordId);
        mDoc.setDocumentView(mDocView);
        mDoc.join();

3 开始观看

  • recordId 点播id 可以通过调用 api 创建
  • accessToken 可以通过调用 api 获得
 void start(String recordId,String accessToken);

4 设置观看清晰度

从 IVHLivePlayer.EVENT_DPI_LIST 获取当前地址可用的分辨率,确定可用的情况下在切换

清晰度 描述
IVHLivePlayer.DPI_SD 低清
IVHLivePlayer.DPI_HD 高清
IVHLivePlayer.DPI_XHD 超清
IVHLivePlayer.DPI_AUDIO 纯音频
IVHLivePlayer.DPI_SAME 原画
 void.setDPI(dpi);

5 暂停观看/ 恢复观看

停止拉流,而云端的视频源还在不断地更新着 , 当重新恢复时,会从最新的时间点播放

 void pause();
 void resume();

6 控制播放相关API

 long getDuration();  // 获取观看时长 (毫秒)
 
 long getPosition();  // 获取当前进度 (毫秒)
 
 void seek(long position); // Seek 操作

7 结束观看

 void stop();

8 销毁

销毁播放器的实例

 void release();

事件监听

事件监听 描述
VHVodPlayer.EVENT_STATUS_STARTING 正在运行
VHVodPlayer.EVENT_STATUS_STARTED 开始播放
VHVodPlayer.EVENT_STATUS_STOPED 停止播放
VHVodPlayer.EVENT_STATUS_END 播放结束
VHVodPlayer.EVENT_VIDEO_SIZE_CHANGED 视频的宽高发生改变
IVHLivePlayer.EVENT_DPI_LIST 可以的清晰度
IVHLivePlayer.EVENT_DPI_CHANGED 清晰度发生改变

示例代码:

public class VodPlayerActivity extends Activity {
    private static final String TAG = "LivePlayerActivity";
    private String roomId = "7a97e8c7";
    private String accessToken = "vhall";
    private SurfaceView mSurfaceView;
    private VHVodPlayer mPlayer;
    private boolean mPlaying = false;
    ImageView mPlayBtn;
    ProgressBar mLoadingPB;
    SeekBar mSeekbar;
    TextView mPosView, mMaxView;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mPlaying) {
                int pos = (int) mPlayer.getPosition();
                mSeekbar.setProgress(pos);
                mPosView.setText(String.valueOf(pos));
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        roomId = getIntent().getStringExtra("roomid");
        accessToken = getIntent().getStringExtra("token");
        setContentView(R.layout.vod_layout);
        mPlayBtn = (ImageView) this.findViewById(R.id.btn_play);
        mLoadingPB = (ProgressBar) this.findViewById(R.id.pb_loading);
        mSeekbar = (SeekBar) this.findViewById(R.id.seekbar);
        mSurfaceView = (SurfaceView) this.findViewById(R.id.surfaceview);
        mPosView = (TextView) this.findViewById(R.id.tv_pos);
        mMaxView = (TextView) this.findViewById(R.id.tv_max);
        mPlayer = new VHVodPlayer(this, mSurfaceView);
        mPlayer.addListener(new MyPlayer());
        mSeekbar.setOnSeekBarChangeListener(new MySeekbarListener());
        handlePosition();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mPlayer != null && mPlaying)
            mPlayer.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mPlayer != null && mPlayer.resumeAble()) {
            mPlayer.resume();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPlayer != null)
            mPlayer.release();
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    public void play(View view) {
        if (mPlaying) {
            mPlayer.pause();
        } else {
            if (mPlayer.resumeAble())
                mPlayer.resume();
            else
                mPlayer.start(roomId, accessToken);
        }
    }

    class MyPlayer implements VHPlayerListener {

        @Override
        public void onEvent(int event, String msg) {
            switch (event) {
                case VHVodPlayer.EVENT_STATUS_STARTING:
                    mLoadingPB.setVisibility(View.VISIBLE);
                    break;
                case VHVodPlayer.EVENT_STATUS_STARTED:
                    int max = (int) mPlayer.getDuration();
                    mSeekbar.setMax(max);
                    mMaxView.setText(String.valueOf(max));
                    mLoadingPB.setVisibility(View.GONE);
                    mPlaying = true;
                    mPlayBtn.setImageResource(R.mipmap.icon_pause_bro);
                    break;
                case VHVodPlayer.EVENT_STATUS_STOPED:
                    mPlaying = false;
                    mPlayBtn.setImageResource(R.mipmap.icon_start_bro);
                    mLoadingPB.setVisibility(View.GONE);
                    break;
                case VHVodPlayer.EVENT_STATUS_END:
                    mPlaying = false;
                    mPlayBtn.setImageResource(R.mipmap.icon_start_bro);
                    mLoadingPB.setVisibility(View.GONE);
                    break;
                case VHVodPlayer.EVENT_STATUS_WH:
                    break;
            }
        }

        @Override
        public void onError(int errorCode, String msg) {
            mPlaying = false;
            mPlayBtn.setImageResource(R.mipmap.icon_start_bro);
            mLoadingPB.setVisibility(View.GONE);
            Toast.makeText(VodPlayerActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    }

    class MySeekbarListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            mPosView.setText(String.valueOf(seekBar.getProgress()));
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mPlayer.seek(seekBar.getProgress());
        }
    }
    //每秒获取一下进度
    Timer timer;

    private void handlePosition() {
        if (timer != null)
            return;
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.sendEmptyMessage(0);
            }
        }, 1000, 1000);
    }
}