4 视频播放

1. 播放前准备

1.1 部署播放器

PolyvVideoView 是视频播放器的主类 View,可以控制视频播放,进度等等。若要实现视频播放功能,只需要添加布局,调用videoView.setVid(vid)即可。调用setVid(vid)方法视频会自动播放。代码示例如下:

<RelativeLayout
        android:id="@+id/view_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/top_center_player_height"
        android:background="@color/top_text_color_black">

        <com.easefun.polyvsdk.video.PolyvVideoView
            android:id="@+id/polyv_video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
   
    	...
</RelativeLayout>
PolyvVideoView videoView = findViewById(R.id.polyv_video_view);
videoView.setVid(vid);

此外还有更多重载的方法,可支持更多的播放设定。如:

videoView.setVid(videoId, isMustFromLocal);//是否播放本地视频。本地存在视频id的文件,并且是完整的就播放
videoView.setVid(videoId, bitRate);//设置视频id,播放对应码率的视频。
videoView.setVidWithStudentId(videoId,studentId);//指定观众的id,播放视频
//播放外部视频
videoView.setVideoPath(path);//设置视频路径,如网址URL。
...

1.2 外部传入播放凭证

自点播2.17.0版本开始,支持通过外部传入播放凭证的方式进行加密视频的播放,以避免非法盗版者利用漏洞创建无身份信息的播放凭证。

  • Token是用于解密播放保利威平台加密视频的,本地传入Token将更好地提升视频安全性。

  • 客户在使用此功能的时候,务必要保证传入的Token在自家api传输中的安全性,如接口加密。

首先,您需要集成点播SDK在2.17.0以上版本。

其次,在播放器初始化时,调用setVideoTokenRequestListener方法设置回调监听,传入播放凭证。

videoView.setVideoTokenRequestListener(new IPLVVideoTokenRequestListener() {
    @Override
    public String onRequestToken(PolyvVideoVO videoVO, String viewerId, String viewerName, String viewerParam) {
        // 返回外部获取的 token
        // 注意:此处如果为异步请求token,需要将线程等待,待请求结果返回后,再进行return
        // 可参考使用CountDownLatch进行线程等待
        return token;
    }
});

播放凭证应通过您自定义的接口获取。后端开发者的接口开发,以及播放加密视频实践全流程,可参考 播放加密视频最佳实践

2. 基本设置

在正式使用播放器之前,我们应当先对PolyvVideoView进行基本的属性配置,以便让视频播放器更适合开发者的设计与使用。部分设置如下,更多的设置可查看 API 文档

2.1 自动播放

设置是否自动播放,默认自动播放。

setAutoPlay(boolean isAutoPlay)

2.2 自动续播

设置是否自动续播,默认关闭。开启后重新进入视频可从上一次播放位置继续播放。

setAutoContinue(boolean isAutoContinue)

2.3 开启广告

设置是否开启广告,默认关闭。

setOpenAd(boolean isOpenAd)

2.4 开启字幕

设置是否开启字幕,默认关闭。

setOpenSRT(boolean isOpenSRT)

2.5 开启预加载

设置是否开启预加载,默认关闭。

setOpenPreload(boolean isOpenPreload)

2.6 开启跑马灯

设置是否开启跑马灯,默认关闭。

setOpenMarquee(boolean isOpenMarquee)

2.7 开启手势

设置是否需要手势,默认关闭。开启后设置手势监听将有回调触发。

setNeedGestureDetector(boolean need)

2.8 开启防录屏

设置是否开启防录屏开关,默认关闭。如开启防录屏,投屏功能将不可用。

disableScreenCAP(Activity activity, boolean disableScreenCAP)

2.9 设置加载超时时间

设置加载超时时间,默认关闭,最少25秒。

setLoadTimeoutSecond(int timeoutSecond)//设置后自动开启
setLoadTimeoutSecond(boolean isOpenLoadTimeout, int timeoutSecond)

2.10 设置缓冲超时时间

设置缓冲超时时间,默认关闭,最少15秒。

setBufferTimeoutSecond(int timeoutSecond)
setBufferTimeoutSecond(boolean isOpenBufferTimeout, int timeoutSecond)

2.11 设置后台播放

PolyvPlayerActivity 中有字段 isBackgroundPlay 控制是否允许后台播放,默认不允许。

private boolean isBackgroundPlay = false;//默认不允许后台播放

需要注意的是我们没有额外地处理后台保活,需要开发者自行增加相关逻辑。

自 SDK2.11.0 开始,实现了进入后台播放开启 foreground service 的保活逻辑,并默认允许后台播放。

2.12 设置预加载时长

设置视频的预加载时长,提供设置视频的最大缓存字节数,以及设置最大缓存的时间两种方式实现。

setMaxCacheSize(long maxBuffer)
setMaxCacheDuration(int cacheDuration)

3. 高级设置

3.1 设置清晰度

设置码率,也就是设置清晰度。传入的参数为 PolyvBitRate.java 中的枚举类型。

/**
* @param bitRate :
* 0-自动, 1-流畅, 2-高清, 3-超清
*/
changeBitRate(int bitRate)
changeBitRate(int bitRate, boolean isMustFromLocal)
changeBitRate(int bitRate, @PolyvPlayStrategy.PlayStrategy int strategy)

3.2 线路切换

线路切换指切换视频所访问的 CDN 服务商,保利威为加密的点播提供了多种线路切换。可以通过 getRouteCount() 知道可切换线路来源数量。route 的值大于等于1。

changeRoute(final int route)//切换线路
getRouteCount()//获取线路源数量

3.3 设置播放速度

播放器支持倍速播放,正常播放速度为 1.0 。开发者可以通过修改该值来改变播放器的播放速度,倍速播放最好不要超过2.0 。

setSpeed(float speed)//设置播放速度
getSpeed()//获取当前播放速度

3.4 设置播放音量

设置播放音量。取值范围为 [0,100]。

closeSound()//关闭声音
openSound()//开启声音
setVolume(int volume)//设置音量
getVolume()//获取当前音量

3.5 播放进度跳转

视频跳转到某个时间点,单位是毫秒。如从视频开始跳转到2秒 videoView.seekTo(2000)

seekTo(int pos)//跳转进度

3.6 设置视频画面拉伸模式

setAspectRatio(int screen)

PolyvPlayerScreenRatio.java 中定义了屏幕比的可选模式:

拉伸模式说明

AR_ASPECT_FIT_PARENT

按比例缩放

AR_ASPECT_FILL_PARENT

充满父窗

AR_ASPECT_WRAP_CONTENT

匹配内容

AR_MATCH_PARENT

适配父窗

AR_16_9_FIT_PARENT

16:9 比例缩放

AR_4_3_FIT_PARENT

4:3 比例缩放

3.7 音视 / 视频模式切换

控制播放器播放音频还是视频。默认是视频播放模式。可选参数为 PolyvVideoVO.MODE_VIDEO [视频模式] | PolyvVideoVO.MODE_AUDIO [音频模式]

changeMode(String priorityMode)
getCurrentMode()//获取当前播放模式,视频模式或音频模式
setPriorityMode(String priorityMode)//设置优先模式

音频播放的方式有两种:

一种是视频模式下播放源文件为 MP3 的资源,由于是视频模式,播放器会默认没有画面。demo 中在这种情况显示音频模式的UI。开发者可自行定义。

videoView.setOnPreparedListener(new IPolyvOnPreparedListener2() {
    @Override
    public void onPrepared() {
        if (videoView.getVideo() != null && videoView.getVideo().isMp3Source()) {
            audioSourceCoverView.onlyShowCover(videoView);
        } else {
            audioSourceCoverView.hide();
        }
		//...
    }
});

另外一种是切换到音频模式。它是对支持音视频切换的视频,直接通过changeMode()方法,切换为音频模式播放。生成支持音视频切换的视频需要联系管理员,开通相关功能。开通后会在后台视频设置里面可控制开关,开启后将会在对视频转码时,额外生成一份音频文件,然后播放器就可以进行音频 / 视频的切换。

3.8 设置Seek精准模式与Seek策略

播放器Seek模式分为两种,控制了Seek时候是否准确滑动到对应时间点:

  • PolyvSeekType.SEEKTYPE_NORMAL:普通模式,根据关键帧Seek。播放器内部会获取视频信息,提取关键帧,Seek的位置视关键帧位置所定。

  • PolyvSeekType.SEEKTYPE_ACCURATE:精准模式。播放器内部会处理分析,Seek时候精确到秒,比普通模式更为精确。同时消耗资源也会有所增加。

videoView.setSeekType(PolyvSeekType.SEEKTYPE_NORMAL);

此外自 2.12.1 开始,在 demo 增加了 Seek 策略配置控制,开发者可以参考或者直接引用实现,对Seek进度条禁止拖拽等实现。开发者只需通过控制dragSeekStrategy为所需的配置即可。默认为DRAG_SEEK_PLAYED,只允许在已播放进度区域拖动跳转播放进度。

//PolyvPlayerMediaController.java
//进度条拖拽跳转播放进度策略
public static final int DRAG_SEEK_ALLOW = 0;//允许拖动进度条跳转进度
public static final int DRAG_SEEK_BAN = 1;//禁止拖动进度条跳转进度
public static final int DRAG_SEEK_PLAYED = 2;//只允许在已播放进度区域拖动跳转播放进度
private int dragSeekStrategy = DRAG_SEEK_PLAYED;

4. 播放状态

4.1 暂停与继续播放

通过start() 方法可以把播放状态改变为继续播放。注意要先调用 setVid(vid) 方法,因为start()方法没有设置视频源,直接调用 start()方法是无效的。它只是修改播放状态为继续播放。配合pause() 方法可以实现暂停继续功能。

start()//开始播放
pause()//暂停播放
pause(boolean isNotShowAdvert)//暂停的时候是否显示广告
isPlaying()//是否正在播放

此外,在基本设置中,开启自动续播,可以在再次进入同一个视频的时候自动跳到上一次的进度。

setAutoContinue(true)//开启自动续播

4.2 媒体时长与缓冲进度

媒体时长的返回单位是毫秒。通过getCurrentPosition() 可以获取当前播放进度。如一个视频已经播放了2秒,则videoView.getCurrentPosition() = 2000

getCurrentPosition()//取得视频播放进度当前位置
getDuration()//获取总时长

通过getBufferPercentage() 可以获取当前缓冲进度的百分比。此外还可以设置最大缓存字节,默认为15M。

getBufferPercentage()//当前缓冲百分比
setMaxBuffer(long maxBuffer)//设置最大缓存字节,默认15M

4.3 获取当前时刻截图

screenshot()

4.4 手势交互

播放器支持识别8种手势,并把识别的手势类型与响应事件回调开放出来。开发者可以按照实际需求实现手势事件。回调的方法都在主线程中回调。具体实现可以参考 demo 的 PolyvPlayerActivity

interface IPolyvOnGestureRightUpListener;//手势右向上滑动
interface IPolyvOnGestureRightDownListener;//手势右向下滑动
interface IPolyvOnGestureLeftUpListener;//手势左向上滑动
interface IPolyvOnGestureLeftDownListener;//手势左向下滑动
interface IPolyvOnGestureSwipeLeftListener;//手势向左滑
interface IPolyvOnGestureSwipeRightListener;//手势向右滑
interface IPolyvOnGestureClickListener;//单击
interface IPolyvOnGestureDoubleClickListener;//双击

以下例子为设置手势左向上的时候,调高亮度:

videoView.setOnGestureLeftUpListener(new IPolyvOnGestureLeftUpListener() {
    @Override
    public void callback(boolean start, boolean end) {
        if(mediaController.isLocked()){
            return;
        }
        int brightness = videoView.getBrightness(PolyvPlayerActivity.this) + 5;
        if (brightness > 100) {
            brightness = 100;
        }
        videoView.setBrightness(PolyvPlayerActivity.this, brightness);
        lightView.setViewLightValue(brightness, end);
    }
});

4.5 状态回调

com.easefun.polyvsdk.video.listener 包下,还开放了更多的回调监听,都可以设置给播放器,监听播放器状态。这里只截取部分回调展示,详情请查看API 文档

  • 视频已经准备好马上进入播放回调

    public interface IPolyvOnPreparedListener2 {
        @MainThread
        void onPrepared();
    }
  • 视频完成回调

    public interface IPolyvOnCompletionListener2 {
        @MainThread
        void onCompletion();
    }
  • 视频播放器出错回调

    public interface IPolyvOnVideoPlayErrorListener2 {
        @MainThread
        boolean onVideoPlayError(@PolyvPlayErrorReason.PlayErrorReason int errorReason);
    }
  • 缓冲更新回调

    public interface IPolyvOnBufferingUpdateListener2 {
        @MainThread
        void onBufferingUpdate(int percent);
    }
  • seek 完成回调

    public interface IPolyvOnSeekCompleteListener2 {
        @MainThread
        void onSeekComplete();
    }
  • ...

5. 自定义播放器控件

5.1 播放器控制栏

播放器控制栏,可以方便我们控制播放器播放,切换播放器状态。如选择清晰度,控制音量等。自定义的播放器控制栏界面,需要继承自 PolyvBaseMediaController 类,原理和系统播放器一样。初始化完成后作为参数传递给 PolyvVideoView即可。以下摘以 demo 的例子作为展示:

//PolyvPlayerMediaController 是demo中自定义的播放器控制栏,具体实现请查看demo
PolyvPlayerMediaController mediaController = findViewById(R.id.polyv_player_media_controller);
...
videoView.setMediaController(mediaController);

建议有一定能力的开发者才自定义播放器控制栏界面,demo 中有完整播放器控制栏界面示例。

5.2 设置辅助视频

辅助视频可以用于播放广告,片头等。PolyvAuxiliaryVideoView 是其实现主类。其基本使用与 PolyvVideoView 类似。初始化完成后作为参数传递给 PolyvVideoView即可。注意设置需要开启广告设置才有效videoView.setOpenAd(true)

<com.easefun.polyvsdk.video.auxiliary.PolyvAuxiliaryVideoView
    android:id="@+id/polyv_auxiliary_video_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black" />
PolyvAuxiliaryVideoView auxiliaryVideoView = findViewById(R.id.polyv_auxiliary_video_view);
videoView.setAuxiliaryVideoView(auxiliaryVideoView);

相关的更多设置可以查看API 文档com.easefun.polyvsdk.video.auxiliary 部分。具体实现可参考 demo PolyvPlayerActivity相关设置。

5.3 跑马灯

跑马灯可以让视频播放的时候滚动显示文本,通常用于防盗水印的作用。Polyv SDK 提供了内置的跑马灯实现。主要通过 PolyvMarqueeView 作为显示的 View,通过 PolyvMarqueeItem 设置跑马灯属性。

<RelativeLayout
        ...>

        <com.easefun.polyvsdk.video.PolyvVideoView
            android:id="@+id/polyv_video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
        <com.easefun.polyvsdk.marquee.PolyvMarqueeView
            android:id="@+id/polyv_marquee_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
   
    	...
</RelativeLayout>
//开启跑马灯
videoView.setOpenMarquee(true);
// 设置跑马灯
videoView.setMarqueeView(marqueeView, marqueeItem = new PolyvMarqueeItem()
                         .setStyle(PolyvMarqueeItem.STYLE_ROLL) //样式
                         .setDuration(10000) //时长
                         .setText("POLYV Android SDK") //文本
                         .setSize(16) //字体大小
                         .setColor(Color.YELLOW) //字体颜色
                         .setTextAlpha(70) //字体透明度
                         .setInterval(1000) //隐藏时间
                         .setLifeTime(1000) //显示时间
                         .setTweenTime(1000) //渐隐渐现时间
                         .setHasStroke(true) //是否有描边
                         .setBlurStroke(true) //是否模糊描边
                         .setStrokeWidth(3) //描边宽度
                         .setStrokeColor(Color.MAGENTA) //描边颜色
                         .setReappearTime(3000) // 设置跑马灯再次出现的间隔
                         .setStrokeAlpha(70)); //描边透明度

6. 半屏 / 全屏切换

在 SDK 中并没有提供相关接口直接进行半屏/全屏切换,但是我们在 Demo 中实现了半屏/全屏切换的功能。其基本原理是通过设置 PolyvVideoViewPolyvPlayerMediaController 的宽高为 match_parent,然后改变Activity 的横竖屏状态,最后设置公共的父布局的宽高适应横竖屏,以此来实现半屏/全屏切换功能。以下实例代码摘自 demo:

1、布局实现:

<根布局...>
    <!--控制parent_view的高度-->
    <RelativeLayout
        android:id="@+id/parent_view"
        android:layout_width="match_parent"
        android:layout_height="300dp">

        <!--让 PolyvVideoView 和PolyvMediaPlayer 宽高跟随父布局-->
        <com.easefun.polyvsdk.video.PolyvVideoView
            android:id="@+id/polyv_video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#aaa" />

        <com.shawn.testsdk.PolyvMediaPlayer
            android:id="@+id/media_player"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
		<其他.../>
    </RelativeLayout>
    
    <其他.../>
</根布局...>

2、在AndroidManifest.xml中设置 ActivityconfigChanges 属性:

//...AndroidManifest.xml
<activity
     android:name="com.easefun.polyvsdk.activity.PolyvPlayerActivity"
     android:configChanges="orientation|screenSize|keyboardHidden"
     ...>
	...
</activity>

3、改变 parent_view 宽高属性以此实现半屏/全屏切换:

  • 切换全屏

//...PolyvPlayerMediaController.java
public void changeToLandscape() {
    PolyvScreenUtils.setLandscape(videoActivity);
    //初始为横屏时,状态栏需要隐藏
    PolyvScreenUtils.hideStatusBar(videoActivity);
    //初始为横屏时,导航栏需要隐藏
    PolyvScreenUtils.hideNavigationBar(videoActivity);
    //初始为横屏时,控制栏的宽高需要设置
    initLandScapeWH();
}

private void initLandScapeWH() {
    ViewGroup.LayoutParams vlp = parentView.getLayoutParams();
    vlp.width = ViewGroup.LayoutParams.MATCH_PARENT;
    vlp.height = ViewGroup.LayoutParams.MATCH_PARENT;
	...
}

PolyvScreenUtils 是 Demo 中定义的工具类。在这里主要是设置 Activity 为横屏模式。

  • 切换半屏

//...polyvPlayerActivity
protected void onCreate(Bundle saveInstanceState){
    ...
    PolyvScreenUtils.generateHeight16_9(this);//记录高度
}
//...PolyvPlayerMediaController.java
public void changeToPortrait() {
    PolyvScreenUtils.setPortrait(videoActivity);
    initPortraitWH();
}

private void initPortraitWH() {
    ViewGroup.LayoutParams vlp = parentView.getLayoutParams();
    vlp.width = ViewGroup.LayoutParams.MATCH_PARENT;
    vlp.height = PolyvScreenUtils.getHeight16_9();
    ...
}

Last updated