频道栏目
首页 > 程序开发 > 综合编程 > 其他综合 > 正文
视频框架Vitamio学习分享
2016-04-02 09:48:13         来源:Jem的博客  
收藏   我要投稿

概述

开发公司一个直播项目时,本来有个播放视频广告的功能,到最后不了了之。虽然没有在项目中做要求,但是这个点子还是激起了我研究多媒体的好奇心。刚好后面遇到一款比较喜欢的视频APP魔力盒,上面视频播放的体验及整个产品的设计都是我喜欢的类型,于是反编译了一下,发现其中用到了一个视频框架Vitamio,(还有一个很流畅的下拉刷新框架hardmark), 然后,一番百度google,发现居然是国内团队开发的框架,而且应用已经很广泛。所以研究了下,自己写了个demo。  

 

使用Vitamio打造自己的Android万能播放器——新版Vitamio内测SDK发布 摘要: Vitamio系列文章至今受到了许多Android开发者和创业者的关注,新版的SDK也在千呼万唤中发布,虽然处于内测阶段,已明显改善并达到预期,极其方便和友好的集成到自己的产品中,欢迎大家抢先测试!

 

使用Vitamio打造自己的Android万能播放器(8)——细节优化 摘要: 成功的产品往往在细节之处也做到极致,产品和项目从使用的角度来看最大的区别我认为也就是细节的处理上。开播视频的目标是产品,前面7篇文章高歌猛进,添加了很多的功能,也该停下来休整一下,优化一下,也欢迎交流反馈做得不周到的地方。由于开源,大家也可以按照自己的喜好来添加修改不同的功能和细节。

  

 

使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频) 摘要: 本章将实现非常实用的功能——下载在线视频。涉及到多线程、线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术细节实现!

 

 

使用Vitamio打造自己的Android万能播放器(6)——在线播放(播放列表) 摘要: 新版本的VPlayer由设计转入开发阶段,预计开发周期为一个月,这也意味着新版本的Vitamio将随之发布,开发者们可以和本系列文章一样,先开发其他功能。本章内容为"在线视频播放列表",集合了主流各大视频网站的手机版,欢迎给"开播视频"反馈改进建议!

 

使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频) 摘要: 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图、视频时间、尺寸等),跳过直接写在线播放部分的章节。从Vitamio的介绍可以看得出,其支持http、m3u8等多种网络协议,本章将编写播放优酷视频的例子。

  

 

使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储) 摘要: 本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能)完成,和播放组件关系不大,但用到一些实用的技术,欢迎交流!

  

 

使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表) 摘要: 打造一款可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment、ViewPager来搭建播放器的主界面,并实现本地播放基本功能。系列文章提供截图、代码说明、源码下载,欢迎交流!

 

使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放 摘要: 本章继续完善播放相关播放器的核心功能,为后续扩展打好基础。

  

 

使用Vitamio打造自己的Android万能播放器(1)——准备 摘要: 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式、性能等各方面都十分有限,这里与大家一起利用开源项目Vitamio来打造属于自己的Android万能播放器!

  

相关知识点

项目中有个获取视频缩略图的功能,在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;  
    }

     

点击复制链接 与好友分享!回本站首页
相关TAG标签 框架 视频
上一篇:浅谈Volley源码
下一篇:浅谈利用线程的生命周期使小球撞墙弹回
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站