概述
开发公司一个直播项目时,本来有个播放视频广告的功能,到最后不了了之。虽然没有在项目中做要求,但是这个点子还是激起了我研究多媒体的好奇心。刚好后面遇到一款比较喜欢的视频APP魔力盒,上面视频播放的体验及整个产品的设计都是我喜欢的类型,于是反编译了一下,发现其中用到了一个视频框架Vitamio,(还有一个很流畅的下拉刷新框架hardmark), 然后,一番百度google,发现居然是国内团队开发的框架,而且应用已经很广泛。所以研究了下,自己写了个demo。
资料总结
Vitamio官网:https://www.vitamio.org
源码地址:https://github.com/yixia/VitamioBundle
最佳教程:大名鼎鼎的农民伯伯博客http://www.cnblogs.com/over140/category/409230.html,农民伯伯应该是这个开发团队的一员。
VPlayer好像是这个框架的最佳产品,不过看到官网的一些合作伙伴,如果确实是用到这个框架的话,好像也很不错(可以反编译看看,学习学习~)
下面是农名伯伯开发教程实现的产品的源码(下载测试后,可以运行,扫描本地视频好像没找到文件,仔细找下原因应该是可以解决的,项目用到的内容还算是比较常规的吧,没有比较难懂的地方,也可能是我没有研究那么细):
项目地址:http://code.taobao.org/p/oplayer
SVN地址:http://code.taobao.org/svn/oplayer/
总体感觉,初次接触会比较难理解,花点时间去研究的话,还是比较好懂的,这个框架发展了这么久,现在算是比较成熟了。目前还是面向个人开发者免费。如果有需要的话,可以引用。
资料引用
【Android】OPlayer升级Vitamio到4.1
摘要: 很久没有更新OPlayer,还是使用旧版Vitamio 3.0版本(新版已经到4.1),这次更新下。 阅读全文
posted @ 2013-09-20 11:00 农民伯伯 阅读(5970) | 评论 (26) 编辑
【Android】Vitamio 4.0 正式版发布/ Vitamio IOS 测试版发布(2013-07-16)
摘要: Vitamio 4.0 正式版发布! 阅读全文
posted @ 2013-07-16 16:05 农民伯伯 阅读(5520) | 评论 (18) 编辑
【Android】Vitamio 4.0 公测版发布(2013-05-28)
摘要: 【Android】Vitamio 4.0 公测版发布(2013-05-28) 阅读全文
posted @ 2013-05-28 15:09 农民伯伯 阅读(4662) | 评论 (13) 编辑
Vitamio不支持特性列表(本文会持续更新 2013-03-13)
摘要: 一直再说Vitamio的优点,这里也罗列一下缺点,一方面提醒开发者注意,另一方面也更好的提供给Vitamio团队参考之用,作为后续版本升级的参考。 阅读全文
posted @ 2013-03-13 10:18 农民伯伯 阅读(3700) | 评论 (25) 编辑
使用Vitamio打造自己的Android万能播放器(12)—— 播放网络视频缓冲处理
摘要: 受限于网速等原因,播放网络视频时一般都会要加上缓冲处理,一般可以通过设置加大缓冲和显示正在缓冲的进度条来改善体验。 阅读全文
posted @ 2013-03-12 13:20 农民伯伯 阅读(10028) | 评论 (11) 编辑
Vitamio 3.0 新手教程
摘要: Vitamio项目发展迅猛,官方群突破400位开发者,基于Vitamio的项目突破1000个,使用Vitamio提供优质播放体验的用户超过5000万。文档是短板,也欢迎大家分享你的Vitamio使用经验,本文将进一步介绍Vitamio的简单使用方法。 阅读全文
posted @ 2013-01-15 10:58 农民伯伯 阅读(22644) | 评论 (14) 编辑
使用Vitamio打造自己的Android万能播放器(11)—— 本地扫描后台服务
摘要: Vitamio和OPlayer系列文章得到广大同行的关注和支持,非常感谢!离系列文章的上篇有几个月了,各种忙暂停了本系列文章,非常抱歉!离OPlayer正式上线还有距离,还有很多要做的事情,继续前行! 阅读全文
posted @ 2012-11-07 17:49 农民伯伯 阅读(5985) | 评论 (15) 编辑
Vitamio中文API文档(5)—— MediaPlayer
摘要: MediaPlayer是Vitamio的核心类,与系统自带的这个类用法类似,是基于Vitamio开发自己Android播放器必读文档。 阅读全文
posted @ 2012-09-06 14:39 农民伯伯 阅读(12863) | 评论 (10) 编辑
Vitamio中文API文档(4)—— VitamioInstaller
摘要: 在使用程序任何类和方法以前,建议使用这个类来检查设备是否已经安装Vitamio插件。 阅读全文
posted @ 2012-09-03 17:48 农民伯伯 阅读(3893) | 评论 (2) 编辑
Vitamio SDK 2.0 新版发布(2012-08-31)
摘要: 离上次发版有将近两个月时间,总算是把解决共存问题新版发出来,期间VPlayer新版本也发了6个。还请大家理解,VPlayer是团队的主业,Vitamio是副业,所以无法保证能按时发版,不过以后会逐步提升Vitamio的重要性,感谢支持,欢迎使用! 阅读全文
posted @ 2012-08-31 15:54 农民伯伯 阅读(8627) | 评论 (19) 编辑
Vitamio中文API文档(3)—— MediaController
摘要: MediaController与VideoView配套使用,基本能实现播放界面的主要功能,大家可用参考 OPlayer的代码实现。 阅读全文
posted @ 2012-08-30 14:34 农民伯伯 阅读(6134) | 评论 (1) 编辑
Vitamio中文API文档(2)—— VideoView
摘要: VideoView是Vitamio最重要的类之一,使用方法与系统的VideoView差不多,提供诸多方法供开发者调用,实现各种强大的播放功能,例如外挂字幕,画面缩放、设置画面质量等。 阅读全文
posted @ 2012-08-30 10:42 农民伯伯 阅读(13466) | 评论 (11) 编辑
Vitamio中文API文档(1)—— MediaStore
摘要: Vitamio新版SDK发布在即,文档一直欠缺,接下来的一段时间将陆续补上,后续还会推出开发者指南等系列文章,官网也在改版,帮助开发者更好的使用Vitamio。本章MediaStore主要用于读取本地视频、音频信息、缩略图用,请参加Vitamio万能播放器系列文章第10篇。 阅读全文
posted @ 2012-08-29 11:32 农民伯伯 阅读(7590) | 评论 (1) 编辑
Vitamio FAQ(2012-11-20 )
摘要: Vitamio系列文章汇总FAQ,详细回答关于Vitamio各种问题 阅读全文
posted @ 2012-08-01 10:02 农民伯伯 阅读(13097) | 评论 (52) 编辑
[重要]使用Vitamio打造自己的Android万能播放器(10)—— 本地播放 (缩略图、视频信息、视频扫描服务)
摘要: Vitamio是团队的诚意之作,我们除了要将VPlayer打造成Android最好的播放器,也要将Vitamio播放组件打造成Android最好的播放器组件。新版发布内测SDK虽然还有一些问题,但已经具备高可扩展性、便捷性和许多内置实用的功能,后续文章将继续深挖和介绍Vitamio的使用细节和方法。本章将提供显示缩略图、视频大小等视频信息,并介绍使用Vitamio内置的ContentProvider以及文件扫描服务。 阅读全文
posted @ 2012-07-21 15:27 农民伯伯 阅读(11273) | 评论 (36) 编辑
使用Vitamio打造自己的Android万能播放器(9)—— 在线播放 (在线电视)
摘要: 如果不想自己去找视频看,以传统方式看电视也不错,比如CCTV、湖南卫视等。本章从网络收集几百个电视台的地址,采用多级分类方式呈现,极大丰富在线播放部分的内容。 阅读全文
posted @ 2012-07-15 12:22 农民伯伯 阅读(7979) | 评论 (11) 编辑
使用Vitamio打造自己的Android万能播放器——新版Vitamio内测SDK发布
摘要: Vitamio系列文章至今受到了许多Android开发者和创业者的关注,新版的SDK也在千呼万唤中发布,虽然处于内测阶段,已明显改善并达到预期,极其方便和友好的集成到自己的产品中,欢迎大家抢先测试! 阅读全文
posted @ 2012-07-09 12:23 农民伯伯 阅读(15011) | 评论 (71) 编辑
使用Vitamio打造自己的Android万能播放器(8)——细节优化
摘要: 成功的产品往往在细节之处也做到极致,产品和项目从使用的角度来看最大的区别我认为也就是细节的处理上。开播视频的目标是产品,前面7篇文章高歌猛进,添加了很多的功能,也该停下来休整一下,优化一下,也欢迎交流反馈做得不周到的地方。由于开源,大家也可以按照自己的喜好来添加修改不同的功能和细节。 阅读全文
posted @ 2012-07-08 18:48 农民伯伯 阅读(6139) | 评论 (0) 编辑
使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)
摘要: 本章将实现非常实用的功能——下载在线视频。涉及到多线程、线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术细节实现! 阅读全文
posted @ 2012-06-29 14:45 农民伯伯 阅读(10083) | 评论 (26) 编辑
使用Vitamio打造自己的Android万能播放器(6)——在线播放(播放列表)
摘要: 新版本的VPlayer由设计转入开发阶段,预计开发周期为一个月,这也意味着新版本的Vitamio将随之发布,开发者们可以和本系列文章一样,先开发其他功能。本章内容为"在线视频播放列表",集合了主流各大视频网站的手机版,欢迎给"开播视频"反馈改进建议! 阅读全文
posted @ 2012-06-20 10:27 农民伯伯 阅读(10577) | 评论 (10) 编辑
使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)
摘要: 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图、视频时间、尺寸等),跳过直接写在线播放部分的章节。从Vitamio的介绍可以看得出,其支持http、m3u8等多种网络协议,本章将编写播放优酷视频的例子。 阅读全文
posted @ 2012-06-15 14:47 农民伯伯 阅读(17903) | 评论 (20) 编辑
使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储)
摘要: 本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能)完成,和播放组件关系不大,但用到一些实用的技术,欢迎交流! 阅读全文
posted @ 2012-06-08 17:59 农民伯伯 阅读(8284) | 评论 (14) 编辑
使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表)
摘要: 打造一款可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment、ViewPager来搭建播放器的主界面,并实现本地播放基本功能。系列文章提供截图、代码说明、源码下载,欢迎交流! 阅读全文
posted @ 2012-05-30 17:27 农民伯伯 阅读(12798) | 评论 (22) 编辑
使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放
摘要: 本章继续完善播放相关播放器的核心功能,为后续扩展打好基础。 阅读全文
posted @ 2012-05-22 16:19 农民伯伯 阅读(22546) | 评论 (18) 编辑
使用Vitamio打造自己的Android万能播放器(1)——准备
摘要: 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式、性能等各方面都十分有限,这里与大家一起利用开源项目Vitamio来打造属于自己的Android万能播放器! 阅读全文
posted @ 2012-04-26 14:43 农民伯伯 阅读(65020) | 评论 (41) 编辑
iteye上面有几篇
http://www.iteye.com/topic/1124550
相关知识点
项目中有个获取视频缩略图的功能,在VPlayer的源码中好像注释掉了,从API 8开始,现有Android API里面就有了一个用于实现相关功能的类
android.media.ThumbnailUtils这个类提供了3个静态方法一个用来获取视频第一帧得到的Bitmap,2个对图片进行缩略处理。
publicstatic Bitmap createVideoThumbnail (String filePath, int kind)
第一个参数是视频文件的路径,第二个参数是指定图片的大小,有两种选择Thumbnails.MINI_KIND与Thumbnails.MICRO_KIND。
- 第一种文档上说大小是512 x 384 ,我用一个MP4格式文件测试得到544 x 960,用一个wmv格式文件测试得到160 x 120。明显不靠谱。
- 第二种参数两种格式文件得到的大小都是 96 x 96,这个才是缩略图。
extractThumbnail(Bitmap source, int width, int height, int options)
extractThumbnail(Bitmap source, int width, int height)
这两种方法都是用来处理Bitmap的大小的,第一个参数是要处理的Bitmap,第二个参数是处理后宽度,第三个是高度,第四个参数options,如果options定义为OPTIONS_RECYCLE_INPUT,则回收资源。也就是说可以用第三种方法把截取到的视频第一帧的Bitmap转成任意想要的大小,第三个方法还可以获取内存卡内图片的缩略图。
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path1, Thumbnails.MINI_KIND);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, 210, 210);
从API 10开始新增一类MediaMetadataRetriever可以用来获取媒体文件的信息
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource("/sdcard/33.mp4");
Bitmap bitmap = mmr.getFrameAtTime();
image.setImageBitmap(bitmap);
System.out.println(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)+"");
System.out.println(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE)+"");
mmr.release();
MediaMetadataRetriever可以获取视频任何一帧的缩略图。
publicstatic Bitmap createVideoThumbnail(String filePath) {
// MediaMetadataRetriever is available on API Level 8
// but is hidden until API Level 10
Class<?> clazz = null;
Object instance = null;
try {
clazz = Class.forName("android.media.MediaMetadataRetriever");
instance = clazz.newInstance();
Method method = clazz.getMethod("setDataSource", String.class);
method.invoke(instance, filePath);
// The method name changes between API Level 9 and 10. if (Build.VERSION.SDK_INT <= 9) {
return (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
} else {
byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
if (data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bitmap != null) return bitmap;
}
return (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
}
} catch (IllegalArgumentException ex) {
// Assume this is a corrupt video file
} catch (RuntimeException ex) {
// Assume this is a corrupt video file.
} catch (InstantiationException e) {
Log.e(TAG, "createVideoThumbnail", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "createVideoThumbnail", e);
} catch (ClassNotFoundException e) {
Log.e(TAG, "createVideoThumbnail", e);
} catch (NoSuchMethodException e) {
Log.e(TAG, "createVideoThumbnail", e);
} catch (IllegalAccessException e) {
Log.e(TAG, "createVideoThumbnail", e);
} finally {
try {
if (instance != null) {
clazz.getMethod("release").invoke(instance);
}
} catch (Exception ignored) {
}
}
returnnull;
}