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

简介:

一、实现目标 

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万能播放器
     * 
     * 
@author  农民伯伯
     * 
@version  2012-5-22
     * 
     
*/
     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( thisnew 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万能播放器(2)—— 手势控制亮度、音量、缩放,如需转载请自行联系原博主。

目录
相关文章
|
6月前
|
数据采集 前端开发 Android开发
Android平台RTMP推送或GB28181设备接入端如何实现采集audio音量放大?
我们在做Android平台RTMP推送和GB28181设备对接的时候,遇到这样的问题,有的设备,麦克风采集出来的audio,音量过高或过低,特别是有些设备,采集到的麦克风声音过低,导致播放端听不清前端采集的audio,这时候,就需要针对采集到的audio,做音量放大处理。
|
6月前
|
缓存 网络协议 开发工具
庖丁解牛之-Android平台RTSP|RTMP播放器设计
我们在做Android平台RTSP或者RTMP播放器开发的时候,需要注意的点非常多,以下,以大牛直播SDK(官方)的接口为例,大概介绍下相关接口设计:
101 0
|
6月前
|
前端开发 开发工具 Android开发
Android播放器之SurfaceView与GLSurfaceView
Surface的官方介绍:Handle onto a raw buffer that is being managed by the screen compositor,Surface是一个raw buffer的句柄,通过它在raw buffer上进行绘制,可以通过Surface获得一个Canvas。
|
6月前
|
开发工具 Android开发 iOS开发
Android、iOS平台RTMP/RTSP播放器实现实时音量调节
介绍移动端RTMP、RTSP播放器实时音量调节之前,我们之前也写过,为什么windows播放端加这样的接口,windows端播放器在多窗口大屏显示的场景下尤其需要,尽管我们老早就有了实时静音接口,相对实时静音来说,播放端实时音量调节粒度更细,从[0, 100],用户体验更好。
109 1
|
3月前
|
XML 存储 Java
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
24 0
|
6月前
|
编解码 网络协议 Android开发
Android平台RTMP|RTSP直播播放器功能进阶探讨
很多开发者在跟我聊天的时候,经常问我,为什么一个RTMP或RTSP播放器,你们需要设计那么多的接口,真的有必要吗?带着这样的疑惑,我们今天聊聊Android平台RTMP、RTSP播放器常规功能,如软硬解码设置、实时音量调节、实时快照、实时录像、视频view翻转和旋转、画面填充模式设定、解码后YUV、RGB数据回调等:
|
6月前
|
Android开发 开发者
Android平台GB28181设备接入端如何调节实时音量?
我们在对接Android平台GB28181设备接入端的时候,有开发者提出这样的疑惑,如何调整设备接入端的实时音量?
|
6月前
|
数据处理 开发工具 Android开发
Android平台RTMP/RTSP播放器开发系列之解码和绘制
本文主要抛砖引玉,粗略介绍下Android平台RTMP/RTSP播放器中解码和绘制相关的部分(Github)。
|
6月前
|
Android开发 开发者
Android播放器实现视频窗口实时放大缩小功能
很多开发者希望Android播放端实现视频窗口的放大缩小功能,为此,我们做了个简单的demo,通过播放端回调RGB数据,直接在上层view操作处理即可,Github:https://github.com/daniulive/SmarterStreaming
150 0
|
8月前
|
编解码 Ubuntu Java
Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
166 0

相关产品

  • 云迁移中心