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

所属分类: 软件编程 / Android 阅读数: 498
收藏 0 赞 0 分享

前言

  本章继续完善播放相关播放器的核心功能,为后续扩展打好基础。

系列

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

正文

           一、实现目标

 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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="match_parent"
 android:layout_height="match_parent">
 <io.vov.vitamio.widget.VideoView
 android:id="@+id/surface_view" android:layout_width="match_parent"
 android:layout_height="match_parent" android:layout_centerHorizontal="true"
 android:layout_centerVertical="true" />
 <FrameLayout android:id="@+id/operation_volume_brightness"
 android:visibility="invisible" android:layout_centerInParent="true"
 android:layout_width="wrap_content" android:layout_height="wrap_content"
 android:background="#00000000" android:orientation="horizontal"
 android:padding="0dip">
 <ImageView android:id="@+id/operation_bg"
 android:layout_gravity="center" android:src="@drawable/video_volumn_bg"
 android:layout_width="wrap_content" android:layout_height="wrap_content" />
 <FrameLayout android:layout_gravity="bottom|center_horizontal"
 android:layout_width="wrap_content" android:layout_height="wrap_content"
 android:paddingBottom="25dip">
 <ImageView android:id="@+id/operation_full"
 android:layout_gravity="left" android:src="@drawable/video_num_bg"
 android:layout_width="94dip" android:layout_height="wrap_content" />
 <ImageView android:id="@+id/operation_percent"
 android:layout_gravity="left" android:src="@drawable/video_num_front"
 android:layout_width="0dip" android:layout_height="wrap_content"
 android:scaleType="matrix" />
 </FrameLayout>
 </FrameLayout>
</RelativeLayout>

          3.2 Activity

 /**
 * 
 * Android万能播放器
 * 
 * 
 */
 public class VideoViewDemo extends Activity {
 
 private String path = Environment.getExternalStorageDirectory()
 + "/Moon.mp4";
 private VideoView mVideoView;
 private View mVolumeBrightnessLayout;
 private ImageView mOperationBg;
 private ImageView mOperationPercent;
 private AudioManager mAudioManager;
 /** 最大声音 */
 private int mMaxVolume;
 /** 当前声音 */
 private int mVolume = -1;
 /** 当前亮度 */
 private float mBrightness = -1f;
 /** 当前缩放模式 */
 private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
 private GestureDetector mGestureDetector;
 private MediaController mMediaController;
 
 @Override
 public void onCreate(Bundle icicle) {
 super.onCreate(icicle);
 setContentView(R.layout.videoview);
 mVideoView = (VideoView) findViewById(R.id.surface_view);
 mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
 mOperationBg = (ImageView) findViewById(R.id.operation_bg);
 mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
 
 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
 mMaxVolume = mAudioManager
 .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
 mVideoView.setVideoPath(path);
 mMediaController = new MediaController(this);
 mVideoView.setMediaController(mMediaController);
 mVideoView.requestFocus();
 
 mGestureDetector = new GestureDetector(this, new MyGestureListener());
 }
 
 @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;
 
 // 隐藏
 mDismissHandler.removeMessages(0);
 mDismissHandler.sendEmptyMessageDelayed(0, 500);
 }
 
 private class MyGestureListener extends SimpleOnGestureListener {
 
 /** 双击 */
 @Override
 public boolean onDoubleTap(MotionEvent e) {
 if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
 mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
 else
 mLayout++;
 if (mVideoView != null)
 mVideoView.setVideoLayout(mLayout, 0);
 return true;
 }
 
 /** 滑动 */
 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2,
 float distanceX, float distanceY) {
 float mOldX = e1.getX(), mOldY = e1.getY();
 int y = (int) e2.getRawY();
 Display disp = getWindowManager().getDefaultDisplay();
 int windowWidth = disp.getWidth();
 int windowHeight = disp.getHeight();
 
 if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
 onVolumeSlide((mOldY - y) / windowHeight);
 else if (mOldX < windowWidth / 5.0)// 左边滑动
 onBrightnessSlide((mOldY - y) / windowHeight);
 
 return super.onScroll(e1, e2, distanceX, distanceY);
 }
 }
 
 /** 定时隐藏 */
 private Handler mDismissHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
 mVolumeBrightnessLayout.setVisibility(View.GONE);
 }
 };
 
 /**
 * 滑动改变声音大小
 * 
 * @param percent
 */
 private void onVolumeSlide(float percent) {
 if (mVolume == -1) {
 mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
 if (mVolume < 0)
 mVolume = 0;
 
 // 显示
 mOperationBg.setImageResource(R.drawable.video_volumn_bg);
 mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
 }
 
 int index = (int) (percent * mMaxVolume) + mVolume;
 if (index > mMaxVolume)
 index = mMaxVolume;
 else if (index < 0)
 index = 0;
 
 // 变更声音
 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
 
 // 变更进度条
 ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
 lp.width = findViewById(R.id.operation_full).getLayoutParams().width
 * index / mMaxVolume;
 mOperationPercent.setLayoutParams(lp);
 }
 
 /**
 * 滑动改变亮度
 * 
 * @param percent
 */
 private void onBrightnessSlide(float percent) {
 if (mBrightness < 0) {
 mBrightness = 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);
 }
 WindowManager.LayoutParams lpa = 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;
 getWindow().setAttributes(lpa);
 
 ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
 lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
 mOperationPercent.setLayoutParams(lp);
 }
 
 @Override
 public void onConfigurationChanged(Configuration newConfig) {
 if (mVideoView != null)
 mVideoView.setVideoLayout(mLayout, 0);
 super.onConfigurationChanged(newConfig);
 }

 } 

 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融合入自己或公司的项目中。

 以上就是对Android Vitamio 资料的整理,后续继续补充。

更多精彩内容其他人还在看

Android中加入名片扫描功能实例代码

这篇文章主要介绍了Android中加入名片扫描功能实例代码的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android仿微信发表说说实现拍照、多图上传功能

这篇文章主要为大家详细介绍了Android仿微信发表说说实现拍照、多图上传功能,使用Retrofit2.0技术,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

设置Android系统永不锁屏永不休眠的方法

在进行Android系统开发的时候,有些特定的情况需要设置系统永不锁屏,永不休眠。本篇文章给大家介绍Android 永不锁屏,开机不锁屏,删除设置中休眠时间选项,需要的朋友一起学习吧
收藏 0 赞 0 分享

Android Retrofit 2.0框架上传图片解决方案

这篇文章主要介绍了Android Retrofit 2.0框架上传一张与多张图片解决方案,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android自定义等待对话框

这篇文章主要为大家详细介绍了Android自定义等待对话框的实现方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android中Window添加View的底层原理

这篇文章主要介绍了Android中Window添加View的底层原理,需要的朋友可以参考下
收藏 0 赞 0 分享

Android调用系统默认浏览器访问的方法

这篇文章主要介绍了Android调用系统默认浏览器访问的方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android开发退出程序的方法汇总

Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗口B后,在B中如何关闭整个Android应用程序呢? 下面脚本之家小编就给大家介绍android开发退出程序的几种方法,感兴趣的朋友参考下吧
收藏 0 赞 0 分享

Android程序开发中单选按钮(RadioGroup)的使用详解

在android程序开发中,无论是单选按钮还是多选按钮都非常的常见,接下来通过本文给大家介绍Android程序开发中单选按钮(RadioGroup)的使用,需要的朋友参考下吧
收藏 0 赞 0 分享

Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中

这篇文章主要介绍了Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多