前言

  本章继续完善播放相关播放器的核心功能,为后续扩展打好基础。
 
声明
  欢迎转载,但请保留文章原始出处:) 
    博客园:http://www.cnblogs.com
    农民伯伯: http://over140.cnblogs.com
系列
正文

  一、实现目标

1.1 亮度控制

模仿VPlayer界面:

1.2 声音控制

模仿VPlayer界面:

1.3 画面缩放

根据下面API提供画面的拉伸、剪切、100%、全屏

  二、Vitamio API 介绍

VideoView

2.1 public void start()

开始播放

2.2 public void pause()

暂停播放

2.3 public long getDuration()

获取视频的时长

2.4 public long getCurrentPosition()

获取已经播放的时长

2.5 public void seekTo(long msec)

设置播放器从指定的位置开始播放

2.6 public boolean isPlaying()

是否正在播放

2.7 public int getVideoWidth()

获取视频宽

2.8 public int getVideoHeight()

获取视频高

2.9 public void setBufferSize(int bufSize)

设置缓存大小,默认1024KB

2.10 public void setVideoQuality(int quality)

设置视频质量,低、中、高(MediaPlayer.VIDEOQUALITY_LOW、MediaPlayer.VIDEOQUALITY_MEDIUM 、MediaPlayer.VIDEOQUALITY_HIGH ),

默认低(最流畅)。

2.11 public void setSubShown(boolean shown)

设置是否显示字幕

2.12 public void setAudioTrack(int audioIndex)

设置音轨,必须是getAudioTrackMap(String) 的返回值。

2.13 public void setVolume(float leftVolume, float rightVolume)

设置立体音左右音量。

2.14 public void setSubPath(String subPath)

设置外挂字幕路径

2.15 public int getBufferPercentage()

获取缓冲百分比

2.16 public void stopPlayback()

停止播放

2.17 public void setVideoPath(String path)

设置视频播放路径

2.18 public void setVideoURI(Uri uri)

设置视频播放路径

2.19 public void setVideoLayout(int layout, float aspectRatio)

设置视频缩放(拉伸、剪切、100%、全屏)

  三、 实现代码

3.1 xml

  1.  
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4.     android:orientation="vertical" android:layout_width="match_parent"
  5.     android:layout_height="match_parent">
  6.     <io.vov.vitamio.widget.VideoView
  7.         android:id="@+id/surface_view" android:layout_width="match_parent"
  8.         android:layout_height="match_parent" android:layout_centerHorizontal="true"
  9.         android:layout_centerVertical="true" />
  10.     <FrameLayout android:id="@+id/operation_volume_brightness"
  11.         android:visibility="invisible" android:layout_centerInParent="true"
  12.         android:layout_width="wrap_content" android:layout_height="wrap_content"
  13.         android:background="#00000000" android:orientation="horizontal"
  14.         android:padding="0dip">
  15.         <ImageView android:id="@+id/operation_bg"
  16.             android:layout_gravity="center" android:src="@drawable/video_volumn_bg"
  17.             android:layout_width="wrap_content" android:layout_height="wrap_content" />
  18.         <FrameLayout android:layout_gravity="bottom|center_horizontal"
  19.             android:layout_width="wrap_content" android:layout_height="wrap_content"
  20.             android:paddingBottom="25dip">
  21.             <ImageView android:id="@+id/operation_full"
  22.                 android:layout_gravity="left" android:src="@drawable/video_num_bg"
  23.                 android:layout_width="94dip" android:layout_height="wrap_content" />
  24.             <ImageView android:id="@+id/operation_percent"
  25.                 android:layout_gravity="left" android:src="@drawable/video_num_front"
  26.                 android:layout_width="0dip" android:layout_height="wrap_content"
  27.                 android:scaleType="matrix" />
  28.         </FrameLayout>
  29.     </FrameLayout>

</RelativeLayout>

3.2 Activity

  1.  
  2.     /**
  3.      * 
  4.      * Android万能播放器
  5.      * 
  6.      * @author 农民伯伯
  7.      * @version 2012-5-22
  8.      * 
  9.      */
  10.     public class VideoViewDemo extends Activity {
  11.     
  12.         private String path = Environment.getExternalStorageDirectory()
  13.                 + "/Moon.mp4";
  14.         private VideoView mVideoView;
  15.         private View mVolumeBrightnessLayout;
  16.         private ImageView mOperationBg;
  17.         private ImageView mOperationPercent;
  18.         private AudioManager mAudioManager;
  19.         /** 最大声音 */
  20.         private int mMaxVolume;
  21.         /** 当前声音 */
  22.         private int mVolume = -1;
  23.         /** 当前亮度 */
  24.         private float mBrightness = -1f;
  25.         /** 当前缩放模式 */
  26.         private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
  27.         private GestureDetector mGestureDetector;
  28.         private MediaController mMediaController;
  29.     
  30.         @Override
  31.         public void onCreate(Bundle icicle) {
  32.             super.onCreate(icicle);
  33.             setContentView(R.layout.videoview);
  34.             mVideoView = (VideoView) findViewById(R.id.surface_view);
  35.             mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
  36.             mOperationBg = (ImageView) findViewById(R.id.operation_bg);
  37.             mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
  38.     
  39.             mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  40.             mMaxVolume = mAudioManager
  41.                     .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  42.             mVideoView.setVideoPath(path);
  43.             mMediaController = new MediaController(this);
  44.             mVideoView.setMediaController(mMediaController);
  45.             mVideoView.requestFocus();
  46.     
  47.             mGestureDetector = new GestureDetector(this, new MyGestureListener());
  48.         }
  49.     
  50.         @Override
  51.         public boolean onTouchEvent(MotionEvent event) {
  52.             if (mGestureDetector.onTouchEvent(event))
  53.                 return true;
  54.     
  55.             // 处理手势结束
  56.             switch (event.getAction() & MotionEvent.ACTION_MASK) {
  57.             case MotionEvent.ACTION_UP:
  58.                 endGesture();
  59.                 break;
  60.             }
  61.     
  62.             return super.onTouchEvent(event);
  63.         }
  64.     
  65.         /** 手势结束 */
  66.         private void endGesture() {
  67.             mVolume = -1;
  68.             mBrightness = -1f;
  69.     
  70.             // 隐藏
  71.             mDismissHandler.removeMessages(0);
  72.             mDismissHandler.sendEmptyMessageDelayed(0, 500);
  73.         }
  74.     
  75.         private class MyGestureListener extends SimpleOnGestureListener {
  76.     
  77.             /** 双击 */
  78.             @Override
  79.             public boolean onDoubleTap(MotionEvent e) {
  80.                 if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
  81.                     mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
  82.                 else
  83.                     mLayout++;
  84.                 if (mVideoView != null)
  85.                     mVideoView.setVideoLayout(mLayout, 0);
  86.                 return true;
  87.             }
  88.     
  89.             /** 滑动 */
  90.             @Override
  91.             public boolean onScroll(MotionEvent e1, MotionEvent e2,
  92.                     float distanceX, float distanceY) {
  93.                 float mOldX = e1.getX(), mOldY = e1.getY();
  94.                 int y = (int) e2.getRawY();
  95.                 Display disp = getWindowManager().getDefaultDisplay();
  96.                 int windowWidth = disp.getWidth();
  97.                 int windowHeight = disp.getHeight();
  98.     
  99.                 if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
  100.                     onVolumeSlide((mOldY - y) / windowHeight);
  101.                 else if (mOldX < windowWidth / 5.0)// 左边滑动
  102.                     onBrightnessSlide((mOldY - y) / windowHeight);
  103.     
  104.                 return super.onScroll(e1, e2, distanceX, distanceY);
  105.             }
  106.         }
  107.     
  108.         /** 定时隐藏 */
  109.         private Handler mDismissHandler = new Handler() {
  110.             @Override
  111.             public void handleMessage(Message msg) {
  112.                 mVolumeBrightnessLayout.setVisibility(View.GONE);
  113.             }
  114.         };
  115.     
  116.         /**
  117.          * 滑动改变声音大小
  118.          * 
  119.          * @param percent
  120.          */
  121.         private void onVolumeSlide(float percent) {
  122.             if (mVolume == -1) {
  123.                 mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
  124.                 if (mVolume < 0)
  125.                     mVolume = 0;
  126.     
  127.                 // 显示
  128.                 mOperationBg.setImageResource(R.drawable.video_volumn_bg);
  129.                 mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  130.             }
  131.     
  132.             int index = (int) (percent * mMaxVolume) + mVolume;
  133.             if (index > mMaxVolume)
  134.                 index = mMaxVolume;
  135.             else if (index < 0)
  136.                 index = 0;
  137.     
  138.             // 变更声音
  139.             mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
  140.     
  141.             // 变更进度条
  142.             ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
  143.             lp.width = findViewById(R.id.operation_full).getLayoutParams().width
  144.                     * index / mMaxVolume;
  145.             mOperationPercent.setLayoutParams(lp);
  146.         }
  147.     
  148.         /**
  149.          * 滑动改变亮度
  150.          * 
  151.          * @param percent
  152.          */
  153.         private void onBrightnessSlide(float percent) {
  154.             if (mBrightness < 0) {
  155.                 mBrightness = getWindow().getAttributes().screenBrightness;
  156.                 if (mBrightness <= 0.00f)
  157.                     mBrightness = 0.50f;
  158.                 if (mBrightness < 0.01f)
  159.                     mBrightness = 0.01f;
  160.     
  161.                 // 显示
  162.                 mOperationBg.setImageResource(R.drawable.video_brightness_bg);
  163.                 mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  164.             }
  165.             WindowManager.LayoutParams lpa = getWindow().getAttributes();
  166.             lpa.screenBrightness = mBrightness + percent;
  167.             if (lpa.screenBrightness > 1.0f)
  168.                 lpa.screenBrightness = 1.0f;
  169.             else if (lpa.screenBrightness < 0.01f)
  170.                 lpa.screenBrightness = 0.01f;
  171.             getWindow().setAttributes(lpa);
  172.     
  173.             ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
  174.             lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
  175.             mOperationPercent.setLayoutParams(lp);
  176.         }
  177.     
  178.         @Override
  179.         public void onConfigurationChanged(Configuration newConfig) {
  180.             if (mVideoView != null)
  181.                 mVideoView.setVideoLayout(mLayout, 0);
  182.             super.onConfigurationChanged(newConfig);
  183.         }

}

3.3 代码说明

3.3.1  缩放功能

该功能SDK已经提供好了接口,直接使用即可。

3.3.2  音量和亮度控制实现

根据layout可以看得出,利用FrameLayout的特点(后面视图会覆盖前面视图),通过控制后一个视图的宽度来达到进度条的效果。

3.3.3  自动隐藏

可用Handle来实现自定延时隐藏的功能,比较实用。

3.3.4  手势

手势方面大家可用多查查GestureDetector方面的资料,双击、缩放手势都可以实现。

  四、代码下载

请移步#Taocode(SVN):(没有账户的请注册一个账户即可。)

项目地址:http://code.taobao.org/p/oplayer

  五、Vitamio相关信息

5.1 近期将发布新的SDK版本

5.1.1    将直接内置各平台解码器,无需外下载!

5.1.2    将支持自定义进度控制条等。

  六、相关文章

6.1 Android 播放电影时滑动屏幕调整屏幕亮度

6.2 android MediaPlayer API

结束

  本系列文章承诺每周至少出一篇,以帮助需要的朋友尽快将Vitamio融合入自己或公司的项目中。

使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放的更多相关文章

  1. 使用Vitamio打造自己的Android万能播放器(6)——在线播放(播放列表)

    前言 新版本的VPlayer由设计转入开发阶段,预计开发周期为一个月,这也意味着新版本的Vitamio将随之发布,开发者们可以和本系列文章一样,先开发其他功能.本章内容为"在线视频播放列表& ...

  2. 使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)

    前言 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图.视频时间.尺寸等),跳过直接写在线播放部分的章节.从Vitamio的介绍可以看得出,其支持http ...

  3. 使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储)

    前言 关键字:Vitamio.VPlayer.Android播放器.Android影音.Android开源播放器 本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能) ...

  4. 使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表)

    前言 打造一款完整可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment.ViewPager来搭建播放器的主界面,并实现本地播放基本功能.系列文章 ...

  5. 使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)

    前言 本章将实现非常实用的功能——下载在线视频.涉及到多线程.线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术 ...

  6. 使用Vitamio打造自己的Android万能播放器(1)——准备

    前言 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,这里与大家一起利用免费的Vitamio来打造属于自己的And ...

  7. Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa

    MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...

  8. Android之万能播放器解码框架Vitamio的介绍及使用

    一.简介 Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS, RTSP, R ...

  9. Android VLC播放器二次开发3——音乐播放(歌曲列表+歌词同步滚动)

    今天讲一下对VLC播放器音频播放功能进行二次开发,讲解如何改造音乐播放相关功能.最近一直在忙着优化视频解码部分代码,因为我的视频播放器需要在一台主频比较低的机器上跑(800M主频),所以视频解码能力受 ...

随机推荐

  1. Centos安装webbench

    webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统:Linux 2.编译安装: 引用 wget htt ...

  2. linux之cal命令

    现在时间2014/11/25 21:36 让我们简单了解下日历命令的用法 1.显示当月的日历 2.显示一年的日历 3.显示2014年2月的月历

  3. HDU2594——Simpsons’ Hidden Talents

    Problem Description Homer: Marge, I just figured out a way to discover some of the talents we weren’ ...

  4. UVA 12219 Common Subexpression Elimination

    题意: 求最小的表达式树,也就是把相同的表达式子树给替换成最前面相同的编号. 分析: 用map<string,int>smp;存放子树对应的字符串,如果以后出现相同的子树则用相同编号表示. ...

  5. 点击TextView浏览器打开指定网页

    直接上代码: /** * 点击跳转到版权页面 */ private void getCopyRight() { // TODO Auto-generated method stub TextView ...

  6. android开发网络连接工具类(一)

    网络连接工具类整理: package com.gzcivil.utils; import java.io.IOException; import java.util.ArrayList; import ...

  7. SpringMVC(三) —— 参数绑定和数据回显

    参数绑定的过程:就是页面向后台传递参数,后台接受的一个过程. 默认支持的参数类型:(就是你在方法上以形参的形式去定义一下的类型,就可以直接使用它) HttpServletRequest HttpSer ...

  8. thoughtworks家庭作业C++版本

    商品类: #ifndef ITEM_H_ #define ITEM_H_ class SalesTax; //This represents the Items which don't have an ...

  9. mysql学习(九)sql语句

    SQL种类: DDL:数据定义语言 DML:数据操作语言 DQL:数据查询语言 DCL:数据控制语言 DDL: show databases; //查询数据库 create database if n ...

  10. jQuery二级联动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...