先看效果图
做这个项目遗留有不少问题,视频全屏播放无法改变视频的大小,没有办法只好跳转界面,有大牛可指点一下,另一个就是,我桌面的Appwidget已实现播放视频
但问题来咯!切换界面时视频还在界面呆着移不走了,而且桌面背景全黑了,额!效果很差,没办法了。
嗯,上代码吧。首先进来去取视频文件数据
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://" + Environment.getExternalStorageDirectory())));
这句话的意思是扫描全盘的视频文件
private void getMediaData() {
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null,
null);
data = new ArrayList<VideoInfo>();
for (cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()) {
VideoInfo info = new VideoInfo();
int id = cursor.getInt(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
info.setId(id);
// 名称 :MediaStore.Audio.Media.TITLE
String title = cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
info.setTitle(title);
// 专辑名:MediaStore.Audio.Media.ALBUM
// String album = cursor.getString(cursor
// .getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM));
// 歌手名: MediaStore.Audio.Media.ARTIST
// String artist = cursor.getString(cursor
// .getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST));
// 路径 :MediaStore.Audio.Media.DATA
String path = cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
info.setPath(path);
// 总播放时长 :MediaStore.Audio.Media.DURATION
int duration = cursor.getInt(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
info.setDuration(duration);
// 大小 :MediaStore.Audio.Media.SIZE
int size = (int) cursor.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
info.setSize(size);
String displayname = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
info.setDisplayname(displayname);
// 拍摄时间
// int dateTaken = cursor.getInt(cursor
// .getColumnIndexOrThrow(MediaStore.Video.Media.DATE_TAKEN));
// Bitmap bm =
// android.media.ThumbnailUtils.createVideoThumbnail(path,
// Images.Thumbnails.MICRO_KIND);
data.add(info);
}
cursor.close();
}
这是查询Contentprovider里视频文件的信息,得到数据就好办了,放到listview里显示出来就行,下面的核心就是播放出视频文件了。
先贴出code
private void playoneVideo(String path) {
filePath = path;
curindex=getindex();
videoview.setVideoPath(path);
videoview.setMySizeChangeLinstener(new MySizeChangeLinstener() {
public void doMyThings() {
setVideoScale(SCREEN_DEFAULT);
}
});
videoview.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
progress.setMax(videoview.getDuration());
totalTime.setText(toTime(videoview.getDuration()));
setVideoScale(SCREEN_FULL);
videoview.seekTo(currentPosition);
handler.post(updateRun);
setVideoScale(SCREEN_DEFAULT);
videoview.start();
}
});
videoview.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
if(curindex==-1||curindex==-2){
playoneVideo(filePath);
}
else{
curindex=0;
playVideo();
}
}
});
}
传进来播放文件的路径,给videoview就行了,这个Videoview系统也有,我是自己写了个,因为我还要把它加到Widget里去,需要修改一下它的代码。说白了Videoview也是继承SurfaceView的,进行一了封装而已。直接看核心代码:
private void openVideo() {
if (mUri == null || mSurfaceHolder == null) {
// not ready for playback just yet, will try again later
return;
}
// Tell the music playback service to pause
// TODO: these constants need to be published somewhere in the framework.
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mContext.sendBroadcast(i);
if (mMediaPlayer != null) {
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
}
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mIsPrepared = false;
Log.v(TAG, "reset duration to -1 in openVideo");
mDuration = -1;
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mContext, mUri);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
attachMediaController();
} catch (IOException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
return;
} catch (IllegalArgumentException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
return;
}
}
注意在新建MediaPlayer之前一定要释放资源,其他的没什么好说的,就是从外部传值(mUri),传对象(Listener,mSurfaceHolder)等数据过来。你如果外面要对MediaPlayer操作的话全写在这里面,在外面直接调就行了。例如
public int getCurrentPosition() {
if (mMediaPlayer != null && mIsPrepared) {
return mMediaPlayer.getCurrentPosition();
}
return 0;
}
怎么调
int currentPosition = videoview.getCurrentPosition();
就这样ok了。
全屏那个功能点实现的不好,也说说我的思路,双击视频或点击全屏按钮时
currentPosition = videoview.getCurrentPosition();
Intent intent = new Intent();
Bundle bd = new Bundle();
bd.putString("path", filePath);
bd.putInt("curposition", currentPosition);
intent.putExtras(bd);
intent.setClass(getBaseContext(), PlayVideoFullScreenAct.class);
startActivityForResult(intent, 1);
我也说过当我直接把videoview放大到全屏时,视频还是以前的大小,只好搞这中笨方法了。把播放的视频路径,和当前播放的进度传过去,在那个Activity里接一下就ok了,就能继续播放了
intent = getIntent();
filepath = intent.getExtras().getString("path");
curposition = intent.getExtras().getInt("curposition");
有了路径和进度就可以直接播放了
private void playVideo() {
curindex = getindex();
videoview.setVideoPath(filepath);
videoview.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
seekbar.setMax(videoview.getDuration());
fulltotaltext.setText(toTime(videoview.getDuration()));
videoview.setVideoScale(screenWidth, screenHeight);
videoview.seekTo(curposition);
handler.post(updateRun);
videoview.start();
}
});
videoview.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
if(curindex==-1||curindex==-2){
PlayVideoFullScreenAct.this.finish();
}
curindex++;
if (curindex > data.size() - 1) {
curindex = 0;
}
curposition = 0;
handler.removeCallbacks(updateRun);
videoview.reset();
playVideo();
}
});
}
当退出全屏时再把路径和进度传回去就ok了,嗯!差不多了。
视频播放项目源码