首先是效果圖
實(shí)現(xiàn)方案
全屏滾動(dòng)列表
實(shí)現(xiàn)方式 RecyclerView+PagerSnapHelper。方便起見譬巫,使用了開源庫(kù)DingMouRen/LayoutManagerGroup中的ViewPagerLayoutManager脓杉∫捣ぃ滑動(dòng)到某一頁(yè)時(shí)開始播放那一頁(yè)的視頻姨俩,同時(shí)停止播放之前播放的視頻柬祠。
播放器
使用的是B站開源的ijkplayer北戏。api與原生MediaPlayer類似。另外需要自己編譯支持https漫蛔。
原本想使用七牛的免費(fèi)播放器PLDroidPlayer嗜愈,但是存在一些小問題,比如來(lái)回切換時(shí)莽龟,在部分設(shè)備上會(huì)有卡頓一下的情況等蠕嫁。
邊緩存邊播放
使用的是AndroidVideoCache。通過(guò)代理實(shí)現(xiàn)一邊緩存視頻流毯盈,一邊播放剃毒。可以自己設(shè)置最大緩存空間等搂赋,調(diào)用也十分簡(jiǎn)單赘阀。
遇到的問題
IjkMediaPlayer空指針
快速來(lái)回滑動(dòng)時(shí),有時(shí)IjkMediaPlayer會(huì)在native報(bào)空指針錯(cuò)誤脑奠。我在播放的視頻被滑出可視范圍后處理是
mMediaPlayer.stop();
理論上我沒有調(diào)用release基公,應(yīng)該不會(huì)出現(xiàn)這個(gè)問題啊。
后來(lái)就改成了直接釋放捺信,在使用時(shí)重新創(chuàng)建酌媒。改成這樣后就沒有再出現(xiàn)這個(gè)問題。
/**
* 停止播放時(shí)直接釋放資源迄靠,在設(shè)置播放地址時(shí)再初始化
*/
public void stopPlayback() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
/**
* 設(shè)置播放地址秒咨。同時(shí)創(chuàng)建一個(gè)新的player實(shí)例
*
* @param url
*/
public void setVideoPath(String url) {
try {
createPlayer();
mMediaPlayer.setDataSource(mProxyCacheServer.getProxyUrl(url));
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void createPlayer() {
mMediaPlayer = new IjkMediaPlayer();
mMediaPlayer.setOnPreparedListener(this);
if (mSurface != null) {
mMediaPlayer.setSurface(mSurface);
}
}
RecyclerView.SCROLL_STATE_IDLE不調(diào)用
有一種情況,在監(jiān)聽RecyclerView的滑動(dòng)回調(diào)里接收不到RecyclerView.SCROLL_STATE_IDLE這個(gè)狀態(tài)的回調(diào)掌挚。
具體的操作方法是從第二個(gè)視頻滑動(dòng)到第一個(gè)視頻的時(shí)候雨席,滑動(dòng)到一半松手,在滑動(dòng)到頂部之前再按下吠式,往下拖拽陡厘。
第一次碰到的時(shí)候也是很懵逼,這也行特占?
解決方法是手動(dòng)調(diào)用
setScrollState(SCROLL_STATE_DRAGGING);
完整解決代碼
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent e) {
final int action = e.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN://手指按下
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE://手指移動(dòng)(從手指按下到抬起 move多次執(zhí)行)
break;
case MotionEvent.ACTION_UP://手指抬起
if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING &&
pagerLayoutManager.findSnapPosition() == 0) {
if (recyclerView.getChildAt(0).getY() == 0 &&
recyclerView.canScrollVertically(1)) {//下滑操作
recyclerView.stopScroll();
}
}
break;
default:
break;
}
return false;
}
});
2019.1.10更新
支持監(jiān)聽視頻播放進(jìn)度
viewHolder.videoView.setOnVideoProgressUpdateListener(new ListVideoView.OnVideoProgressListener() {
@Override
public void onProgress(float progress, long currentTime) {
Log.d("youzai", "progresss---->" + progress + "\t" + "currentTime---->" + currentTime);
}
});
2019.11.14更新
- 非前臺(tái)狀態(tài)暫停播放糙置,返回播放列表時(shí)重新開始播放
- 播放視頻時(shí)保持屏幕常亮
如果喜歡的話就點(diǎn)個(gè)贊吧。歡迎start是目。