使用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)—— 手势控制亮度、音量、缩放,如需转载请自行联系原博主。

目录
相关文章
|
15天前
|
Java 程序员 开发工具
Android|修复阿里云播放器下载不回调的问题
虽然 GC 带来了很多便利,但在实际编码时,我们也需要注意对象的生命周期管理,该存活的存活,该释放的释放,避免因为 GC 导致的问题。
26 2
|
5月前
|
XML 存储 数据库
如何使用Android Studio创建一个基本的音乐播放器应用
如何使用Android Studio创建一个基本的音乐播放器应用
223 0
|
3月前
|
编解码 开发工具 Android开发
Android平台RTSP|RTMP播放器如何实现TextureView渲染
本文介绍了在Android平台上使用TextureView进行RTSP和RTMP视频流渲染的技术背景和实现方法。TextureView相较于SurfaceView具备更高性能、更强功能性和更灵活的绘制方式等优势,但也有必须在硬件加速环境下运行和较高内存占用等局限。文中详细展示了如何在SmartPlayerV2工程中创建和配置TextureView,并通过代码示例解释了如何根据视频分辨率信息调整显示比例,以及处理TextureView的各种生命周期回调。此外,还列举了该播放器SDK支持的多项高级功能,如多实例播放、多种编码格式支持、硬解码能力等,旨在帮助开发者更好地理解和实现高性能的直播播放器。
|
3月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
3月前
|
编解码 网络协议 开发工具
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
158 0
|
6月前
|
Java Android开发
修改Android 触摸提示音及音量大小
修改Android 触摸提示音及音量大小
252 4
|
5月前
|
Android开发
Android音量细分
【6月更文挑战第3天】
|
5月前
|
API Android开发 UED
56. 【Android教程】媒体播放器:MediaPlayer
56. 【Android教程】媒体播放器:MediaPlayer
100 0
|
6月前
|
程序员 Android开发
Android亮度调节的几种实现方法
Android亮度调节的几种实现方法
247 0
|
6月前
|
Android开发
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
122 0
下一篇
无影云桌面