概览

简介

Vitamio 能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在 Android 与 iOS 上跨平台支持 MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,包括点播与直播。
Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐,到目前,全球已经有超过 10,000 种应用在使用 Vitamio,覆盖用户超过5亿。

最近更新较少,上一次更新(2017-04-01)已经是两年前了,但是这并不妨碍它是一个优秀的框架。

Vitamio 官网:http://www.vitamio.org
github: https://github.com/yixia/VitamioBundle
使用博客:农民伯伯:http://www.cnblogs.com/over140/category/409230.html(开发者之一,有大量的文档)

本文内容

本文对其使用进行了一些扩展和功能的丰富,将其整理后汇总。除集成外,扩展功能如下:

  1. 双击暂停,开始播放
  2. 全屏播放
  3. 倍速播放
  4. 左边上下滑动调节亮度
  5. 右边上下滑动调节声音
  6. 左右滑动快进快退
  7. 退出时保留播放进度
  8. 全屏播放时根据手机方向变化,屏幕自动旋转
  9. 进度条控件大小和位置的设置

注意事项

个人使用免费,商用需要授权
大家如果商用的话,别忘了去要授权……

集成

导入

github地址: https://github.com/yixia/VitamioBundle
首先从github上下载源文件,然后以 module的方式导入工程中,即可开始使用。

  1. 导入module,在Android Studio 中依次点击 File -->New --> Import Module…,然后在弹出框中选择文件的路径。
  2. 添加依赖,打开Project Structure选项卡,点击左上角的’+'按钮,然后按照提示添加即可。

目前为止,github上的代码已经很久没有维护了,上次维护应该还是 [2014-04-18] 发布的 4.2.2 版本。所以并不推荐用在公司项目中,一是很久没有维护了,二是需要授权。

  1. 打开app/src/main目录下的AndroidManifest.xml,注册io.vov.vitamio.activity.InitActivity

    注意:这个InitActivity存在于vitamio/src/对应的目录下,不需要用户编写.

<activityandroid:name="io.vov.vitamio.activity.InitActivity"android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"android:launchMode="singleTop"android:theme="@android:style/Theme.NoTitleBar"android:windowSoftInputMode="stateAlwaysHidden" />

至此,vitamio导入完毕.

扩展功能

需求。左侧上下滑动调节亮度,右侧上下滑动调节声音,中间添加提示:
界面文件,因为点击之后控制器会布满屏幕,所及监听和显示组件都要添加到 MediaController中
在这里我们采用手势去处理

1. 双击暂停,开始播放

//播放与暂停
private void playOrPause(){if (videoView != null)if (videoView.isPlaying()) {videoView.pause();} else {videoView.start();}
}

2. 全屏播放

全屏播放,点击按钮后隐藏其他控件,重设尺寸即可
半屏播放同理

3. 倍速播放

Vitamio 支持倍速播放,可以根据项目需求进行设置

4. 左边上下滑动调节亮度

/*** 滑动改变亮度** @param percent*/
private void onBrightnessSlide(float percent) {if (mBrightness < 0) {mBrightness = activity.getWindow().getAttributes().screenBrightness;if (mBrightness <= 0.00f)mBrightness = 0.50f;if (mBrightness < 0.01f)mBrightness = 0.01f;// 显示//mOperationBg.setImageResource(R.drawable.video_brightness_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);mOperationTv.setVisibility(VISIBLE);}

5. 右边上下滑动调节声音

/*** 滑动改变声音大小** @param percent*/
private void onVolumeSlide(float percent) {if (mVolume == -1) {mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);if (mVolume < 0)mVolume = 0;// 显示mVolumeBrightnessLayout.setVisibility(View.VISIBLE);mOperationTv.setVisibility(VISIBLE);}int index = (int) (percent * mMaxVolume) + mVolume;if (index > mMaxVolume)index = mMaxVolume;else if (index < 0)index = 0;if (index >= 10) {mOperationBg.setImageResource(R.drawable.volmn_100);} else if (index >= 5 && index < 10) {mOperationBg.setImageResource(R.drawable.volmn_60);} else if (index > 0 && index < 5) {mOperationBg.setImageResource(R.drawable.volmn_30);} else {mOperationBg.setImageResource(R.drawable.volmn_no);}//DecimalFormat    df   = new DecimalFormat("######0.00");mOperationTv.setText((int) (((double) index / mMaxVolume)*100)+"%");// 变更声音mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);}

6. 左右滑动快进快退

//滑动监听@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {float mOldX = e1.getX(), mOldY = e1.getY();int y = (int) e2.getRawY();int x = (int) e2.getRawX();Display disp = activity.getWindowManager().getDefaultDisplay();int windowWidth = disp.getWidth();int windowHeight = disp.getHeight();if (mOldX > windowWidth * 3.0 / 4.0) {// 右边滑动 屏幕 3/4onVolumeSlide((mOldY - y) / windowHeight);} else if (mOldX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕 1/4onBrightnessSlide((mOldY - y) / windowHeight);}return super.onScroll(e1, e2, distanceX, distanceY);}

7. 退出时保留播放进度

当页面失去焦点时,保存当前播放进度数值,然后当恢复播放的时候,重新设置进度

8. 全屏播放时根据手机方向变化,屏幕自动旋转

首先确定开始收集转屏,然后页面设置中设置为响应屏幕方向的变化,即可自动切换

9. 进度条控件大小和位置的设置

@Override
protected View makeControllerView() {View v = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(getResources().getIdentifier("mymediacontroller", "layout", getContext().getPackageName()), this);v.setMinimumHeight(controllerWidth);... // 省略其他代码mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);return v;
}

完整代码

public class MyMediaController extends MediaController {private static final int HIDEFRAM = 0;//控制提示窗口的显示
private static final int SHOW_PROGRESS = 2;private GestureDetector mGestureDetector;//手势监听类
private ImageButton img_back;//返回键
private ImageView img_Battery;//电池电量显示
private TextView textViewTime;//时间提示
private TextView textViewBattery;//文字显示电池
private VideoView videoView;
private Activity activity;
private Context context;
private int controllerWidth = 0;//设置mediaController高度为了使横屏时top显示在屏幕顶端private View mVolumeBrightnessLayout;//提示窗口
private ImageView mOperationBg;//提示图片
private TextView mOperationTv;//提示文字
private AudioManager mAudioManager;private SeekBar progress;
private boolean mDragging;
private MediaPlayerControl player;
//最大声音
private int mMaxVolume;
// 当前声音
private int mVolume = -1;
//当前亮度
private float mBrightness = -1f;//返回监听
private View.OnClickListener backListener = new View.OnClickListener() {public void onClick(View v) {if(activity != null){activity.finish();}}
};private Handler myHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {long pos;switch (msg.what) {case HIDEFRAM://隐藏提示窗口mVolumeBrightnessLayout.setVisibility(View.GONE);mOperationTv.setVisibility(View.GONE);break;}}
};//videoview 用于对视频进行控制的等,activity为了退出
public MyMediaController(Context context, VideoView videoView , Activity activity) {super(context);this.context = context;this.videoView = videoView;this.activity = activity;WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);controllerWidth = wm.getDefaultDisplay().getWidth();mGestureDetector = new GestureDetector(context, new MyGestureListener());
}@Override
protected View makeControllerView() {View v = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(getResources().getIdentifier("mymediacontroller", "layout", getContext().getPackageName()), this);v.setMinimumHeight(controllerWidth);//TOP
//        img_back = (ImageButton) v.findViewById(getResources().getIdentifier("mediacontroller_top_back", "id", context.getPackageName()));
//        img_Battery = (ImageView) v.findViewById(getResources().getIdentifier("mediacontroller_imgBattery", "id", context.getPackageName()));
//        img_back.setOnClickListener(backListener);
//        textViewBattery = (TextView)v.findViewById(getResources().getIdentifier("mediacontroller_Battery", "id", context.getPackageName()));
//        textViewTime = (TextView)v.findViewById(getResources().getIdentifier("mediacontroller_time", "id", context.getPackageName()));img_back = (ImageButton) v.findViewById(R.id.mediacontroller_top_back);img_Battery = (ImageView) v.findViewById(R.id.mediacontroller_imgBattery);img_back.setOnClickListener(backListener);textViewBattery = (TextView)v.findViewById(R.id.mediacontroller_Battery);textViewTime = (TextView)v.findViewById(R.id.mediacontroller_time);progress = (SeekBar)v.findViewById(R.id.mediacontroller_seekbar);//midmVolumeBrightnessLayout = (RelativeLayout)v.findViewById(R.id.operation_volume_brightness);mOperationBg = (ImageView)v.findViewById(R.id.operation_bg);mOperationTv = (TextView) v.findViewById(R.id.operation_tv);mOperationTv.setVisibility(View.GONE);mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);return v;}@Override
public boolean dispatchKeyEvent(KeyEvent event) {System.out.println("MYApp-MyMediaController-dispatchKeyEvent");return true;
}@Override
public boolean onTouchEvent(MotionEvent event) {if (mGestureDetector.onTouchEvent(event)) return true;// 处理手势结束switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_UP:endGesture();break;}return super.onTouchEvent(event);
}/*** 手势结束*/
private void endGesture() {mVolume = -1;mBrightness = -1f;// 隐藏myHandler.removeMessages(HIDEFRAM);myHandler.sendEmptyMessageDelayed(HIDEFRAM, 1);
}private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {//当收拾结束,并且是单击结束时,控制器隐藏/显示toggleMediaControlsVisiblity();return super.onSingleTapConfirmed(e);}@Overridepublic boolean onDown(MotionEvent e) {return true;}
//滑动监听@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {float mOldX = e1.getX(), mOldY = e1.getY();int y = (int) e2.getRawY();int x = (int) e2.getRawX();Display disp = activity.getWindowManager().getDefaultDisplay();int windowWidth = disp.getWidth();int windowHeight = disp.getHeight();if (mOldX > windowWidth * 3.0 / 4.0) {// 右边滑动 屏幕 3/4onVolumeSlide((mOldY - y) / windowHeight);} else if (mOldX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕 1/4onBrightnessSlide((mOldY - y) / windowHeight);}return super.onScroll(e1, e2, distanceX, distanceY);}//双击暂停或开始@Overridepublic boolean onDoubleTap(MotionEvent e) {playOrPause();return true;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return super.onFling(e1, e2, velocityX, velocityY);}
}/*** 滑动改变声音大小** @param percent*/
private void onVolumeSlide(float percent) {if (mVolume == -1) {mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);if (mVolume < 0)mVolume = 0;// 显示mVolumeBrightnessLayout.setVisibility(View.VISIBLE);mOperationTv.setVisibility(VISIBLE);}int index = (int) (percent * mMaxVolume) + mVolume;if (index > mMaxVolume)index = mMaxVolume;else if (index < 0)index = 0;if (index >= 10) {mOperationBg.setImageResource(R.drawable.volmn_100);} else if (index >= 5 && index < 10) {mOperationBg.setImageResource(R.drawable.volmn_60);} else if (index > 0 && index < 5) {mOperationBg.setImageResource(R.drawable.volmn_30);} else {mOperationBg.setImageResource(R.drawable.volmn_no);}//DecimalFormat    df   = new DecimalFormat("######0.00");mOperationTv.setText((int) (((double) index / mMaxVolume)*100)+"%");// 变更声音mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);}/*** 滑动改变亮度** @param percent*/
private void onBrightnessSlide(float percent) {if (mBrightness < 0) {mBrightness = activity.getWindow().getAttributes().screenBrightness;if (mBrightness <= 0.00f)mBrightness = 0.50f;if (mBrightness < 0.01f)mBrightness = 0.01f;// 显示//mOperationBg.setImageResource(R.drawable.video_brightness_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);mOperationTv.setVisibility(VISIBLE);}WindowManager.LayoutParams lpa = activity.getWindow().getAttributes();lpa.screenBrightness = mBrightness + percent;if (lpa.screenBrightness > 1.0f)lpa.screenBrightness = 1.0f;else if (lpa.screenBrightness < 0.01f)lpa.screenBrightness = 0.01f;activity.getWindow().setAttributes(lpa);mOperationTv.setText((int) (lpa.screenBrightness * 100) + "%");if (lpa.screenBrightness * 100 >= 90) {mOperationBg.setImageResource(R.drawable.light_100);} else if (lpa.screenBrightness * 100 >= 80 && lpa.screenBrightness * 100 < 90) {mOperationBg.setImageResource(R.drawable.light_90);} else if (lpa.screenBrightness * 100 >= 70 && lpa.screenBrightness * 100 < 80) {mOperationBg.setImageResource(R.drawable.light_80);} else if (lpa.screenBrightness * 100 >= 60 && lpa.screenBrightness * 100 < 70) {mOperationBg.setImageResource(R.drawable.light_70);} else if (lpa.screenBrightness * 100 >= 50 && lpa.screenBrightness * 100 < 60) {mOperationBg.setImageResource(R.drawable.light_60);} else if (lpa.screenBrightness * 100 >= 40 && lpa.screenBrightness * 100 < 50) {mOperationBg.setImageResource(R.drawable.light_50);} else if (lpa.screenBrightness * 100 >= 30 && lpa.screenBrightness * 100 < 40) {mOperationBg.setImageResource(R.drawable.light_40);} else if (lpa.screenBrightness * 100 >= 20 && lpa.screenBrightness * 100 < 20) {mOperationBg.setImageResource(R.drawable.light_30);} else if (lpa.screenBrightness * 100 >= 10 && lpa.screenBrightness * 100 < 20) {mOperationBg.setImageResource(R.drawable.light_20);}}public void setTime(String time){if (textViewTime != null)textViewTime.setText(time);
}
//显示电量,
public void setBattery(String stringBattery){if(textViewTime != null && img_Battery != null){textViewBattery.setText(stringBattery + "%");int battery = Integer.valueOf(stringBattery);if(battery < 15)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_15));if(battery < 30 && battery >= 15)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_15));if(battery < 45 && battery >= 30)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_30));if(battery < 60 && battery >= 45)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_45));if(battery < 75 && battery >= 60)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_60));if(battery < 90 && battery >= 75)img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_75));if(battery > 90 )img_Battery.setImageDrawable(getResources().getDrawable(R.drawable.battery_90));}
}
//隐藏/显示
private void toggleMediaControlsVisiblity(){if (isShowing()) {hide();} else {show();}
}
//播放与暂停
private void playOrPause(){if (videoView != null)if (videoView.isPlaying()) {videoView.pause();} else {videoView.start();}
}
}

视频播放库Vitamio的使用以及功能扩展相关推荐

  1. 基于开源蜜罐的实践与功能扩展

    0×00 前言 具有一定规模的公司都会有自己的机房,当网络规模和硬件系统到达一定程度,就需要跟进各种安全预警防护手段,而蜜罐系统就是一种常见的防护手段之一,蜜罐主要是通过在网络环境当中,用虚拟各种真实 ...

  2. libcap-ng库旨在使具有posix功能的编程比传统的libcap库容易得多

    libcap-ng库旨在使具有posix功能的编程比传统的libcap库容易得多.它包括一些实用程序,可以分析所有当前正在运行的应用程序并打印出任何功能,以及是否具有开放式边界集.不带securebi ...

  3. android 第三方视频库,android视频播放库

    因为要学习使用当前流行的视频播放库,下面介绍当前比较流行的四款视频播放库.(文章末有一些优秀的播放库) gsyvideoplayer ijkPlayer ExoPlayer jiaoziVideoPl ...

  4. SkeyeARS 8K视频播放器软解码硬解码功能实现

    SkeyeARS 8K视频播放器软解码&硬解码功能实现 首先,我们简单了解一下软解码&硬解码: 软解码:由CPU负责解码进行播放 优点:不受视频格式限制.画质可能略好于硬解缺点:会占用 ...

  5. tf_course4 功能扩展

    神经网络八股功能扩展 第四讲 功能扩展 一.回顾: 1.tf.keras搭建神经网络八股--六步法 2. 代码 mnist_train_baseline.py: 二. 本讲用 tf.keras 完善功 ...

  6. html5桌面系统,基于HTML5的IVI桌面系统及本地功能扩展研究实现

    摘要: 随着汽车技术以及互联网技术的发展,智能化车载信息娱乐系统(IVI:In-Vehicle Infotainment)已经成为汽车工业未来发展的新方向.目前,在用于开发智能化车载信息娱乐系统的大量 ...

  7. Python库集合--各个Python的功能介绍

    欢迎补充!!!! Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构 ...

  8. EasyPlayer实现视频播放局部缩放、广角平移功能(类似水滴直播,快手视频)

    本文转自:http://blog.csdn.net/jyt0551/article/details/56063869 视频播放局部缩放.广角平移功能 在预览图片的时候,利用手势控制图片的缩放.平移,已 ...

  9. Cocos Store 插件升级,支持联网功能扩展和微信小游戏适配

    年前 Cocos Store 刚上线一款功能强大的新插件,其提供者 Matchvs 游戏云是国内一家游戏联网服务引擎,用户通过接入 Matchvs-SDK,即可将 Cocos 项目方便快速地导入,并轻 ...

最新文章

  1. linux的source命令,linux命令之Source命令
  2. mysql 亿级_mysql 亿级数据量 ( sum ,group by )的优化
  3. 为Linux命令起别名
  4. 云服务器会获取系统信息吗,国内云服务器会被监控吗
  5. jvm classLoader 过程
  6. 【 CodeForces - 1060B 】Maximum Sum of Digits(思维,构造)
  7. oracle load data infile
  8. 深度学习框架PyTorch:入门与实践 学习(三)
  9. 清华天才王垠和阿里 P10 面试官赵海平神仙打架后,我们来说说技术面试中的该与不该!...
  10. App加密:常用加密方式和爱加密原理
  11. winows服务器的ftp密码如何修改,windows怎么修改服务器ftp密码
  12. Math 的 ceil、floor、round方法详解及示例
  13. 私房小菜菜谱和煲汤大全汇总
  14. 风格的要素 C语言 pdf,英语写作手册:风格的要素(新译本) [Elements of Style]
  15. 计算机动画电影英语翻译,英语翻译_推荐!最适合练口语的10部动画电影_沪江英语...
  16. OPPO发布旗舰电视、真无线降噪耳机,智美生活更近一步
  17. 全志 H6 Orange Pi Lite 2 Android 7.0 UART配置
  18. 群发邮件怎么发很多人?邮件群发软件
  19. Python应用之回测基金定投,选周几收益最高?
  20. 庄子如何应对杠精? 什么, 庄子原来不是在诡辩? ---庄子与惠子游于濠梁之上解析

热门文章

  1. 【Camera相机开发】实现相机预览
  2. Java中的字节是什么意思?
  3. bom event周期_BOM-event事件
  4. 实现读文本文件(IOl流)
  5. 计算机毕业设计Java-超市会员积分管理系统-(源码+系统+mysql数据库+lw文档)
  6. devise 笔记
  7. 面向对象(冰箱装大象)
  8. 项目笔记:Arduino读取SD卡
  9. matlab rawdat,工控网络安全态势感知算法实现.pdf
  10. 操作系统:什么是中断?