视频框架 Vitamio 使用教程+部分心得 (四) 滑动控制声音和亮度+android 4.4.X 以上时全屏播放

6 篇文章 0 订阅
5 篇文章 0 订阅
转载注明出处:

http://blog.csdn.net/u010181592/article/category/5893483

文章出自 我不只是看客/NotLooker的博客

先列出参考资料:
* Vitamio 官网:http://www.vitamio.org(不太稳定,时常打不开)
* 农民伯伯 博客:http://www.cnblogs.com/over140/category/409230.html(开发者之一,博客中有部分Vitamio中文API)

上一篇博文介绍了自定义MediaController 的用法,这次继续完成我们视频播放器的其他功能:滑动控制声音和亮度( 针对左右滑动调节视频进度的问题,博主测试了下 发现 Vitamio对进度条seekBar的封装性很强,木有留下相关操作接口。不修改源文件下实现比较困难,所以放到以后再说……)
还有,测试发现,在第一篇博文使用的全屏,在4.4.X以上的系统时会出现标题栏虽然被隐藏,但任然会留下黑边的bug;还有无法完全隐藏掉虚拟按键的问题。这篇博客我们就解决以上三个问题;

完全全屏

google了一下5.0 隐藏虚拟按键的,网上好多,但参差不齐,这里直接上代码:

public void toggleHideyBar() {
    // BEGIN_INCLUDE (get_current_ui_flags)
    // The UI options currently enabled are represented by a bitfield.
    // getSystemUiVisibility() gives us that bitfield.
    int uiOptions = getWindow().getDecorView().getSystemUiVisibility();
    int newUiOptions = uiOptions;

    // END_INCLUDE (get_current_ui_flags)
    // BEGIN_INCLUDE (toggle_ui_flags)
    boolean isImmersiveModeEnabled =
            ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
    if (isImmersiveModeEnabled) {
        Log.i(TAG, "Turning immersive mode mode off. ");
    } else {
        Log.i(TAG, "Turning immersive mode mode on.");
    }

    // Navigation bar hiding:  Backwards compatible to ICS.
    if (Build.VERSION.SDK_INT >= 14) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    }

    // Status bar hiding: Backwards compatible to Jellybean
    if (Build.VERSION.SDK_INT >= 16) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
    }

    // Immersive mode: Backward compatible to KitKat.
    // Note that this flag doesn't do anything by itself, it only augments the behavior
    // of HIDE_NAVIGATION and FLAG_FULLSCREEN.  For the purposes of this sample
    // all three flags are being toggled together.
    // Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
    // Sticky immersive mode differs in that it makes the navigation and status bars
    // semi-transparent, and the UI flag does not get cleared when the user interacts with
    // the screen.
    if (Build.VERSION.SDK_INT >= 18) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    }

    getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
    //END_INCLUDE (set_ui_flags)
}

解释一下,4.4以后推出了一个全新的api——ImmersiveMode,用户沉浸模式(就是完全全屏,隐藏虚拟按键和状态栏) 方法针对不容的sdk加载了不同的模式,而且flag一共有5种模式

    // BEGIN_INCLUDE (get_current_ui_flags) 
   // The "Decor View" is the parent view of the Activity.  It's also conveniently the easiest 
   // one to find from within a fragment, since there's a handy helper method to pull it, and 
   // we don't have to bother with picking a view somewhere deeper in the hierarchy and calling 
   // "findViewById" on it. 
   View decorView = getActivity().getWindow().getDecorView();       
int newUiOptions = uiOptions;        // END_INCLUDE (get_current_ui_flags) 
   // BEGIN_INCLUDE (toggle_lowprofile_mode) 
   // Low profile mode doesn't resize the screen at all, but it covers the nav & status bar 
   // icons with black so they're less distracting.  Unlike "full screen" and "hide nav bar," 
   // this mode doesn't interact with immersive mode at all, but it's instructive when running 
   // this sample to observe the differences in behavior. 
   if (mLowProfileCheckBox.isChecked()) { 
       newUiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;//低调模式:通知栏和虚拟键变暗 
   } else { 
       newUiOptions &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; 
   }        // END_INCLUDE (toggle_lowprofile_mode) 
   `

   // BEGIN_INCLUDE (toggle_fullscreen_mode) 
   // When enabled, this flag hides non-critical UI, such as the status bar, 
   // which usually shows notification icons, battery life, etc 
   // on phone-sized devices.  The bar reappears when the user swipes it down.  When immersive 
   // mode is also enabled, the app-drawable area expands, and when the status bar is swiped 
   // down, it appears semi-transparently and slides in over the app, instead of pushing it 
   // down. 
   if (mHideStatusBarCheckBox.isChecked()) {//全屏模式:隐藏状态栏,但并不隐藏虚拟键 
       newUiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN; 
   } else { 
       newUiOptions &= ~View.SYSTEM_UI_FLAG_FULLSCREEN; 
   }        // END_INCLUDE (toggle_fullscreen_mode) 

   // BEGIN_INCLUDE (toggle_hidenav_mode) 
   // When enabled, this flag hides the black nav bar along the bottom, 
   // where the home/back buttons are.  The nav bar normally instantly reappears 
   // when the user touches the screen.  When immersive mode is also enabled, the nav bar 
   // stays hidden until the user swipes it back. 
   if (mHideNavCheckbox.isChecked()) {//隐藏虚拟键,点击可出现 
       newUiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 
   } else { 
       newUiOptions &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 
   }        // END_INCLUDE (toggle_hidenav_mode) 

   // BEGIN_INCLUDE (toggle_immersive_mode) 
   // Immersive mode doesn't do anything without at least one of the previous flags 
   // enabled.  When enabled, it allows the user to swipe the status and/or nav bars 
   // off-screen.  When the user swipes the bars back onto the screen, the flags are cleared 
   // and immersive mode is automatically disabled. 
   if (mImmersiveModeCheckBox.isChecked()) { 
       newUiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE; 
   } else { 
       newUiOptions &= ~View.SYSTEM_UI_FLAG_IMMERSIVE; 
   }        // END_INCLUDE (toggle_immersive_mode) 

   // BEGIN_INCLUDE (toggle_immersive_mode_sticky) 
   // There's actually two forms of immersive mode, normal and "sticky".  Sticky immersive mode 
   // is different in 2 key ways: 
   // 
   // * Uses semi-transparent bars for the nav and status bars 
   // * This UI flag will *not* be cleared when the user interacts with the UI. 
   //   When the user swipes, the bars will temporarily appear for a few seconds and then 
   //   disappear again. 
   if (mImmersiveModeStickyCheckBox.isChecked()) { 
       newUiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
   } else { 
       newUiOptions &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
   }        // END_INCLUDE (toggle_immersive_mode_sticky) 

   // BEGIN_INCLUDE (set_ui_flags) 
   //Set the new UI flags.        decorView.setSystemUiVisibility(newUiOptions); 
   Log.i(TAG, "Current height: " + decorView.getHeight() + ", width: " + decorView.getWidth());        // END_INCLUDE (set_ui_flags)

同样需要在setContentView()前调用;

滑动调节亮度和声音

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

<RelativeLayout
        android:id="@+id/operation_volume_brightness"
        android:layout_width="150dp"
        android:layout_height="75dp"
        android:layout_centerInParent="true"
        android:background="@drawable/videobg"
        android:orientation="horizontal"
        android:padding="0dip"
        android:visibility="gone">
        <ImageView
            android:id="@+id/operation_bg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/video_volumn_bg"/>
        <TextView
            android:id="@+id/operation_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/operation_bg"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom ="true"
            android:text="32:22/45:00"
            android:textColor="#ffffff"
            android:textSize="10sp"
            android:visibility="gone"
            />
    </RelativeLayout>

只需要在控制器文件中添加一个图片显示和文字显示就好,为方便显示,套在一个RelativeLayout中
MyMediaController.class

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() {
    @Override
    public 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);
    //mid
    mVolumeBrightnessLayout = (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 {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        //当收拾结束,并且是单击结束时,控制器隐藏/显示
        toggleMediaControlsVisiblity();
        return super.onSingleTapConfirmed(e);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        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();
        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/4
            onVolumeSlide((mOldY - y) / windowHeight);
        } else if (mOldX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕 1/4
            onBrightnessSlide((mOldY - y) / windowHeight);
        }
        return super.onScroll(e1, e2, distanceX, distanceY);
    }
    //双击暂停或开始
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        playOrPause();
        return true;
    }

    @Override
    public 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();
        }
}
}

具体代码都有注释,相对简单易懂,搞定;
还要在Activity中添加完全全屏:
PlayActivity.class

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //定义全屏参数
    int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
    //获得当前窗体对象
    Window window = PlayActivity.this.getWindow();
    //设置当前窗体为全屏显示
    window.setFlags(flag, flag);
    //完全全屏
    toggleHideyBar();
    //设置视频解码监听
    if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
        return;
    setContentView(R.layout.activity_play);
......
}

效果图:
这里写图片描述

Github Demo:WHPlayer

下一篇会解决作用滑动控制进度,以及Vitamio其他部分中文API;

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值