磨洋工磨了好久,终于决定开始写视频播放器了,嗯,相册播放器那里,就是典型的旧坑未填,又挖新坑,233.再辞给自己立一个flag,一个月之后就要完成基本上的功能,比如基本的显示,自动播放了,上一个下一个,暂停开始,拖拉,视频列表。嗯,其他的慢慢来,总是要有个目标的,都没人管我,自己再不管自己就要废了。
嗯,时间真的是飞快哇,我都上班半年啦,清楚的记得,那天过来面试的时候,上午,小雨,打着伞,然后那天还很可怜的,到了公司早饭还没吃,站在公司外面吃包子,打电话跟人事说到了。穿的风衣T恤牛仔裤,嗯,填简历,等待,老大询问,老老大询问,工资,就完了,然后就是回去,终于不用跟耗子玩啦,(干哕),然后周一拖着行李箱,大件小件,也是下雨,打伞就拿不到行李,所以没打伞,心拔凉拔凉,走到公租房第一句是,这里没耗子吧,哈哈,被吓出阴影。就这样,过了半年,不能咸啊,要废,想一想,当初是怎么说的。现在就知道该怎么做了。加油哇皮皮虾。
嗯,这两天做了一个,关于天气的数据的整理,耽误了一点时间(虽然没人看233),后面会把他写出来,继续写视频吧。
18-10-29
昨天去做了头发,车祸现场了解一下。
视频现在可以实现基本的,暂停播放,上一首下一首,自动循环播放,以及seekbar的实时刷新。拖拉那里还有点问题。
嗯,重新写过......
现在差不多一个月,基本实现了以上说过的功能。
代码:
我一运行就会进到这个方法里面,显示第一个视频。
/**
* /storage/usb0/video/双笙 - 故梦.mp4
*/
private VideoView mVideoView;
private List<VideoFileInfo> videoLists = new ArrayList<VideoFileInfo>();// 新集合,集合记得new,不要犯这种傻错误啦
private int currentVideoIndex = 0;// 当前视频下标
private int allTime;// 当前视频总时间
// 操作视频
public void PlayVideoView() {
// 获取pointerObject中的视频资源
try {
List<FileVideoInfo> fileVideoList = pointerObject.getVideoItems();
for (FileVideoInfo fileVideoInfo : fileVideoList) {
// 把数据添加到VideoFileInfo里面,里面的属性可用的多一点
VideoFileInfo vinfo = new VideoFileInfo(fileVideoInfo.getPath());
videoLists.add(vinfo);
}
mVideoView.setVideoPath(videoLists.get(0).getPath());
} catch (RemoteException e) {
e.printStackTrace();
}
}
采用handler做循环刷新界面ui+thread做延迟操作。(以前用的是蠢handler发送消息,但是播放下一首的时候会出现同事发送两次的错误并且改不过来,所以改用handler+thread)。
需要注意的是:这里我用来做刷新页面时间数据的是now_tv,是先自增之后再使用的,视频需要从00:00开始,所以需要设置now_tv的值的地方都设置成了-1,自增过后就是0了。但是,不知道为什么,经常会有,textview显示视频剩两三秒才结束,实际播放的视频就已经结束了。
// thread+handler
int cProgress;
int now_tv = -1;
Thread mThread = new Thread(new Runnable() {
@SuppressWarnings("static-access")
@Override
public void run() {
sb_progress.setProgress(10);
try {
while (isExit) {
if (isPrepared) {
/**
* 1、在子线程死循环获取视频时长并发送给handler,handler执行ui更新操作,
*/
allTime = mVideoView.getDuration();
Message msg = mHandler.obtainMessage(0, allTime / 1000);// what,obj
mHandler.sendMessage(msg);
}
mThread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
@SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case 0:
if (!isPausing) {// 如果是暂停的就不做刷新操作
// 更新ui
now_tv++;
if (now_tv <= Integer.parseInt(msg.obj + "")) {
sb_progress.setProgress(now_tv);
refereshTime(tv_now_time, now_tv);
}
// 正常播放的时候就把isCompletion = false;
isCompletion = false;
}
break;
default:
Log.e(TAG, "switch default error");
break;
}
}
};
seekbar的监听事件,需要注意的是:这里的seekto的值是ms(毫秒),所以*1000就正常了,之前我就是不知道这个,所以一直直接seekto(progress),所以导致每一次跳转的时候都是跳到很前面,直到今天看见一个大佬说了,seekto是毫秒,之前自己在安卓开发api里面也没看到这个点。
// seekBar监听事件
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
now_tv = progress;
// 将seekBar设置到拖动的位置去
sb_progress.setProgress(progress);
Log.d(TAG, ".............progress:" + progress);
// 将mVideoView定位到seekBar拖动的位置,参数是毫秒!
mVideoView.seekTo(progress * 1000);
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
}
监听是否播放完毕,是安卓主线程中自己一直在做的事情,以前自己还傻傻的自己去循环判断是否播放完毕,,
@Override
public void onCompletion(MediaPlayer arg0) {
isCompletion = true;
sb_progress.setProgress(0);
mVideoView.setVideoPath(videoLists.get(
++currentVideoIndex % videoLists.size()).getPath());// 担心下一个超出计划范围??当然还是取模好用哇
// 播放完成,将now_tv=0
now_tv = -1;
}
监听视频资源知否准备好,这个也是安卓主线程自己一直 在做的事情。每一次准备好之后就可以获取到新的视频的时长。
@Override
public void onPrepared(MediaPlayer arg0) {
// 准备好就开始
mVideoView.start();
// 获取视频总时长
allTime = mVideoView.getDuration() / 1000;// s
// 设置seekbar的最大值
sb_progress.setMax(allTime);
// 设置文本框
refereshTime(tv_all_time, allTime);
isPrepared = true;
}
点击上一个下一个以及播放暂停,没什么好说的,就是++--和start和pause,这里我只给暂停播放还了图片,上一个下一个这里仔细一点的也可以在按下的时候换一张图片
// 上一个
public void onClickPre(View arg0) {
Log.d(TAG, "-------------onClickPre---------------");
now_tv = -1;
// 点击下一个开始播放
isPausing = false;
bt_play.setBackground(getResources().getDrawable(R.drawable.play));
try {
if (currentVideoIndex <= 0) {
currentVideoIndex = videoLists.size() - 1;
mVideoView.setVideoPath(videoLists.get(
currentVideoIndex % videoLists.size()).getPath());
} else {
mVideoView.setVideoPath(videoLists.get(
--currentVideoIndex % videoLists.size()).getPath());
}
} catch (Exception e) {
Log.e(TAG, "onClickPre error");
}
}
// 下一个
public void onClickNext(View arg0) {
Log.d(TAG, "-------------onClickNext---------------");
now_tv = -1;
// 点击下一个开始播放
isPausing = false;
bt_play.setBackground(getResources().getDrawable(R.drawable.play));
sb_progress.setProgress(0);
mVideoView.setVideoPath(videoLists.get(
++currentVideoIndex % videoLists.size()).getPath());
}
// 播放暂停
@SuppressLint("NewApi")
public void onClickPlay(View arg0) {
if (!isPausing) {// 点击播放,变成暂停
mVideoView.pause();
isPausing = true;
bt_play.setBackground(getResources().getDrawable(R.drawable.pause));
} else {// 点击暂停,变成播放
isPausing = false;
bt_play.setBackground(getResources().getDrawable(R.drawable.play));
mVideoView.start();
}
}
到这里及可以实现:上一个,下一个,暂停,播放,seekbar跳转视频了。
后面还要慢慢实现:点击视频视频缩小,显示视频目录,点击视频名称开始播放对应视频;一段时间不操作,视频又恢复大小,以及隐藏seekbar和几个按钮;还可以实现一个拖动的时候seekbar那里显示一个当前拖动到的值的数据;