本文介绍一个简单的视频播放器的实现,主要功能是读取U盘视频文件,通过UI显示进行播放,包括UI的一些控制逻辑,由于以demo的形式实现,因此UI设计效果比较一般,主要实现对应的功能,下面就简单介绍下整体的实现过程。
1:进入主页,点击获取并播放视频,进行视频资源的获取和播放,首先视频资源的获取实现如下:
/**
* 获取搜索到的结果
*/
public void getVideoList() {
ExecutorsThreadManager.getInstance().submitThread(new Runnable() {
@Override
public void run() {
List<String> list = new ArrayList<>();
File file = new File(PATH_USB_SRC);
// Log.d("daxiang",file.getName());
if (file.exists()) {
File[] files = file.listFiles();
if (files != null && files.length != 0) {
for (int i = 0; i < files.length; i++) {
File result = files[i];
Log.d("daxiang", result.getName());
if (!result.isDirectory() && result.getName().endsWith(VIDEO_NAME)) {
String videoPath = PATH_USB_SRC +"/"+result.getName();
list.add(videoPath);
}
}
Message msg = mFileHandler.obtainMessage();
msg.obj = list;
mFileHandler.sendMessage(msg);
}
}
}
});
}
通过轮询u盘根目录,查找根目录下包括对应视频类型文件放入List集合中,并将数据返回给到Activity。
2:UI的实现是通过ViewPager2加载RecyclerView.Adapter实现,具体的实现方式是:
UI的加载:
mGxAdapter = new GxAdapter(result);
mGxAdapter.setGxAdapterListener(this);
binding.viewpage2.setAdapter(mGxAdapter);
binding.viewpage2.registerOnPageChangeCallback(new GxPageChangeCallback(this));
数据在adapter的刷新展示:
private void listenLiveData() {
videoData.observe(this, new Observer() {
@Override
public void onChanged(Object o) {
result = (List<String>) o;
for (int i = 0; i < result.size(); i++) {
Log.d(TAG, "result==>" + result.get(i));
}
if (mGxAdapter != null) {
mGxAdapter.notifyAdapter(result);
}
}
});
}
其中GxAdapterListener:
/**
* 设置SurfaceView的点击监听
*
* @param l 监听对象
*/
public void setGxAdapterListener(GxAdapterListener l) {
mGxAdapterListener = l;
}
3:ViewPager2的下拉刷新策略:
首先在xml中设置ViewPager2的下拉方向为垂直,
android:orientation="vertical"
然后ViewPager2监听页面改变事件
binding.viewpage2.registerOnPageChangeCallback(new GxPageChangeCallback(this));
在onPageScrollStateChanged时候将对应的位置返回给到Activity进行ui的刷新,如下:
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
Log.d("daxiang","onPageScrollStateChanged state==>"+state);
this.state=state;
if(mCallback!=null&&state==ViewPager2.SCROLL_STATE_IDLE){
mCallback.onPageChange(position);
}
}
MainActivity在页面切换后的刷新操作:
@Override
public void onPageChange(final int index) {
Log.d("daxiang", "onPageChange index==>" + index);
stop();
play(index);
tempIndex = index;
}
/**
* 处理多媒体播放视频的停止操作
*/
private void stop() {
if (mMediaPlayer != null) {//&&mMediaPlayer.isPlaying()
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
/**
* 播放对应位置视频
*
* @param index 位置
*/
private void play(int index) {
String path = null;
try {
Log.d("daxiang", "index==>" + index + " result size==>" + result.size());
if (result != null && result.size() > index) {
path = result.get(index);
binding.playpause.setVisibility(View.GONE);
binding.seekbar.setVisibility(View.GONE);
binding.currentTime.setVisibility(View.GONE);
binding.totalTime.setVisibility(View.GONE);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(path);
surfaceView = mGxAdapter.getView(index);
surfaceView.getHolder().addCallback(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.prepare();
}
} catch (IOException e) {
e.printStackTrace();
}
}
然后再MediaPlayer的OnPreparedListener回调方法中对对应的视频资源进行播放,如下:
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d("daxiang", "onPrepared");
if (mMediaPlayer != null) {
mMediaPlayer.start();
countTime = mMediaPlayer.getDuration();
binding.seekbar.setMax(countTime);
binding.currentTime.setText(GxUtils.timeConversion(0));
binding.totalTime.setText(GxUtils.timeConversion(countTime));
stopTimeLis = true;
ExecutorsThreadManager.getInstance().submitThread(mPlayLisRunnable);
}
if (mMediaPlayer != null && surfaceView != null && surfaceView.isAttachedToWindow()) {
mMediaPlayer.setDisplay(surfaceView.getHolder());
}
}
另外这里还有一些关于视频播放控制这块的逻辑就不做介绍了,有对应的代码可供参考,具体的地址如下:https://github.com/daxiangzaici214703306/GxPlayer.git
下面是实现的效果图
图中有双击弹出爱心的效果实现,在代码中可以参考,切曲可以上拉或者下拉或者点击旁边的按钮。