为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

Android开发—SeeJoPlayer视频播放器源码解析

2011-11-30 7页 doc 380KB 58阅读

用户头像

is_155862

暂无简介

举报
Android开发—SeeJoPlayer视频播放器源码解析2010.03.27 SeeJoPlayer v1.2.0 beta版: 更新说明: 1、完美支持android1.5、android1.6、android2.0、android2.01、android2.1平台; 2、完美支持320×480、480×800、480×854等各种分辨率(自适应屏幕分辨率); 3、支持在线音视频播放,支持URL input和从浏览器调用SeeJoPlayer播放器播放在线音视频; 4、自动转为横屏播放,为用户提供更好的观看体验; 5、修改了没有SD卡程序出错的Bug; 6、美化了视频播放列表和操...
Android开发—SeeJoPlayer视频播放器源码解析
2010.03.27 SeeJoPlayer v1.2.0 beta版: 更新说明: 1、完美支持android1.5、android1.6、android2.0、android2.01、android2.1平台; 2、完美支持320×480、480×800、480×854等各种分辨率(自适应屏幕分辨率); 3、支持在线音视频播放,支持URL input和从浏览器调用SeeJoPlayer播放器播放在线音视频; 4、自动转为横屏播放,为用户提供更好的观看体验; 5、修改了没有SD卡程序出错的Bug; 6、美化了视频播放列和操作说明的界面。 第一部分:功能介绍 SeeJoPlayer的优点主要在相对还算美观的界面和便捷的交互操作上。先说操作吧,它支持: 1、全屏切换: 双击屏幕 2、播放/暂停: 长按屏幕 3、静音/恢复: 长按音量按钮 4、播放列表: 控制面板最右边的按钮(暂不支持编辑功能) 5、音量调节: 单击音量按钮,在弹出的音量显示区域触摸改变音量 这些操作和PC上的播放器较为类似,希望大家能用得习惯。 至于界面的话,多说无益,直接上图吧: 第二部分:源码解析 一、VideoView与视频比例缩放: 我们可以很方便的获得VideoView的源代码,最简单的是直接在GoogleCodeSearch上找“VideoView.java”。所以重写VideoView的过程其实只是在原来的基础上进行一些修改而已,并非一个很麻烦的工作。为什么Android自带的VideoView会保持视频的长宽比而不能让我们很方便的自定义比例呢?我猜想可能Google做Android也是一个很仓促的工程,许多代码并没有考虑得太成熟。 VideoView的源码中有这样一段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //Log.i("@@@@", "onMeasure"); int width = getDefaultSize(mVideoWidth, widthMeasureSpec); int height = getDefaultSize(mVideoHeight, heightMeasureSpec); if (mVideoWidth >0&& mVideoHeight >0) { if ( mVideoWidth * height > width * mVideoHeight ) { //Log.i("@@@", "image too tall, correcting"); height = width * mVideoHeight / mVideoWidth; } else if ( mVideoWidth * height < width * mVideoHeight ) { //Log.i("@@@", "image too wide, correcting"); width = height * mVideoWidth / mVideoHeight; } else { //Log.i("@@@", "aspect ratio is correct: " + //width+"/"+height+"="+ //mVideoWidth+"/"+mVideoHeight); } } //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height); setMeasuredDimension(width, height); } 这就是为什么长宽比不能改变的原因了。因为在OnMeasure的时候,就对这个长宽比进行了处理。 我们把其中处理的代码屏蔽掉,视频大小就可以随着VideoView的长宽改变而改变了。 1 2 3 4 5 6 7 8 9 10 11 12 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //Log.i("@@@@", "onMeasure"); int width = getDefaultSize(mVideoWidth, widthMeasureSpec); int height = getDefaultSize(mVideoHeight, heightMeasureSpec); setMeasuredDimension(width,height); } 二、视频控制菜单与播放界面的层次问题: 看到过一些别人写的视频播放器,其中有一些朋友老是简简单单的将VideoView和控制界面放在一个LinearLayout中。这样随着控制界面的出 现与否,VideoView会随之改变长宽,给人的体验并不很好。所以,我认为VideoView和控制界面最好不要放在同一个层次上。不要偷懒,使用一 个FrameLayout或者PopupWindow就可以解决这个问题。例如,我就简简单单地使用了PopupWindow,这个具体实现上,就百花争 鸣吧。 三、视频文件扫描: 视频文件的扫描,现在想来主要有两种方式: 第一种就是直接读取媒体库中的视频文件数据库。当Android启动的时候,系统会自动扫描sdcard,并为媒体文件建立(或者更新)数据库。我们可以通过对应的URI来访问数据库,从而得到视频文件的列表: 1 2 3 4 5 6 7 8 9 10 11 12 private Uri videoListUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; Cursor cursor = getContentResolver().query(videoListUri, new String[]{"_display_name","_data"}, null, null, null); int n = cursor.getCount(); cursor.moveToFirst(); LinkedList playList2 = new LinkedList(); for(int i = 0 ; i != n ; ++i){ MovieInfo mInfo = new MovieInfo(); mInfo.displayName = cursor.getString(cursor.getColumnIndex("_display_name")); mInfo.path = cursor.getString(cursor.getColumnIndex("_data")); playList2.add(mInfo); cursor.moveToNext(); } 这种方法可能是最有效率的了,不过不知为何,媒体库中似乎没有扫描进本身支持的3GP视频格式(也可能我这里是一个特例) 。不过,正是因为这个原因,我才想到有可能需要另外一种最基本的扫描文件系统的方法来扫描视频文件。这就是文件系统的遍历: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 private void getVideoFile(final LinkedList list,File file){ file.listFiles(new FileFilter(){ @Override public boolean accept(File file) { // TODO Auto-generated method stub String name = file.getName(); int i = name.indexOf('.'); if(i != -1){ name = name.substring(i); if(name.equalsIgnoreCase(".mp4")||name.equalsIgnoreCase(".3gp")){ MovieInfo mi = new MovieInfo(); mi.displayName = file.getName(); mi.path = file.getAbsolutePath(); list.add(mi); return true; } }else if(file.isDirectory()){ getVideoFile(list, file); } return false; } }); } 当然,随着Android平台下的硬件设备越来越多,越来越强大。我们有理由相信,它以后将不仅仅只支持MP4和3GP格式的视频文件,所以我们必须使用两种方式结合的方法来获得最大的视频集合作为我们的视频列表。 四、播放过程中进度条progress的设定: 视频开始播放了,那么一个小麻烦出现了:什么时候设定进度条才更有效率?我这里有一种方法供大家参考,那就是通过Handler自己给自己发消息来达到不断设置进度条的目的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Handler myHandler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch(msg.what){ case PROGRESS_CHANGED: int i = vv.getCurrentPosition(); seekBar.setProgress(i); i/=1000; int minute = i/60; int hour = minute/60; int second = i%60; minute %= 60; playedTextView.setText(String.format("%02d:%02d:%02d", hour,minute,second)); sendEmptyMessage(PROGRESS_CHANGED); break; 当然,这种方法,需要首先发送一个初始消息来启动。 五、全屏与非全屏: 大家都知道,一般一个Activity设置全屏的方法有两种,一是在OnCreate中: 1 2 3 4 5 6 7 8 9 @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_NO_TITLE); Window win = getWindow(); win.setFlags(WindowManager.LayoutParams.NO_STATUS_BAR_FLAG, WindowManager.LayoutParams.NO_STATUS_BAR_FLAG); setContentView(R.layout.mylayout); 二是在AndroidManifest.xml中: 1 2 3 然而,这两种方法都不能达到我们在视频播放过程中设置全屏与否的目的。因为它们都只能在初始化的时候决定全屏与否。那么我现在要说的就是第三种方法: 1getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 1getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 这种方法就可以在Activity运行过程中,动态地改变全屏与否。 六、音量调节: 音量调节的方法其实很简单,不过有人问到,我就在这里顺便说下: 1 AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 2 setIndex(am.getStreamVolume(AudioManager.STREAM_MUSIC));
/
本文档为【Android开发—SeeJoPlayer视频播放器源码解析】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索