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 中實現了半螢幕/全螢幕切換的功能。其基本原理是透過設定 PolyvVideoView 和 PolyvPlayerMediaController 的寬高為 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 中設定 Activity 的 configChanges 屬性:
//...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();
...
}
