Android 使用Vitamio打造自己的萬(wàn)能播放器(2)—— 手勢(shì)控制亮度、音量、縮放
前言
本章繼續(xù)完善播放相關(guān)播放器的核心功能,為后續(xù)擴(kuò)展打好基礎(chǔ)。
系列
1、Android 使用Vitamio打造自己的萬(wàn)能播放器(1)——準(zhǔn)備
正文
一、實(shí)現(xiàn)目標(biāo)
1.1 亮度控制
模仿VPlayer界面:

1.2 聲音控制
模仿VPlayer界面:

1.3 畫(huà)面縮放
根據(jù)下面API提供畫(huà)面的拉伸、剪切、100%、全屏
二、Vitamio API 介紹
VideoView
2.1 public void start()
開(kāi)始播放
2.2 public void pause()
暫停播放
2.3 public long getDuration()
獲取視頻的時(shí)長(zhǎng)
2.4 public long getCurrentPosition()
獲取已經(jīng)播放的時(shí)長(zhǎng)
2.5 public void seekTo(long msec)
設(shè)置播放器從指定的位置開(kāi)始播放
2.6 public boolean isPlaying()
是否正在播放
2.7 public int getVideoWidth()
獲取視頻寬
2.8 public int getVideoHeight()
獲取視頻高
2.9 public void setBufferSize(int bufSize)
設(shè)置緩存大小,默認(rèn)1024KB
2.10 public void setVideoQuality(int quality)
設(shè)置視頻質(zhì)量,低、中、高(MediaPlayer.VIDEOQUALITY_LOW、MediaPlayer.VIDEOQUALITY_MEDIUM 、MediaPlayer.VIDEOQUALITY_HIGH ),
默認(rèn)低(最流暢)。
2.11 public void setSubShown(boolean shown)
設(shè)置是否顯示字幕
2.12 public void setAudioTrack(int audioIndex)
設(shè)置音軌,必須是getAudioTrackMap(String) 的返回值。
2.13 public void setVolume(float leftVolume, float rightVolume)
設(shè)置立體音左右音量。
2.14 public void setSubPath(String subPath)
設(shè)置外掛字幕路徑
2.15 public int getBufferPercentage()
獲取緩沖百分比
2.16 public void stopPlayback()
停止播放
2.17 public void setVideoPath(String path)
設(shè)置視頻播放路徑
2.18 public void setVideoURI(Uri uri)
設(shè)置視頻播放路徑
2.19 public void setVideoLayout(int layout, float aspectRatio)
設(shè)置視頻縮放(拉伸、剪切、100%、全屏)
三、 實(shí)現(xiàn)代碼
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萬(wàn)能播放器
*
*
*/
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;
/** 當(dāng)前聲音 */
private int mVolume = -1;
/** 當(dāng)前亮度 */
private float mBrightness = -1f;
/** 當(dāng)前縮放模式 */
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;
// 處理手勢(shì)結(jié)束
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return super.onTouchEvent(event);
}
/** 手勢(shì)結(jié)束 */
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;
}
/** 滑動(dòng) */
@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)// 右邊滑動(dòng)
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX < windowWidth / 5.0)// 左邊滑動(dòng)
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
/** 定時(shí)隱藏 */
private Handler mDismissHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};
/**
* 滑動(dòng)改變聲音大小
*
* @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);
// 變更進(jìn)度條
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width
* index / mMaxVolume;
mOperationPercent.setLayoutParams(lp);
}
/**
* 滑動(dòng)改變亮度
*
* @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 代碼說(shuō)明
3.3.1 縮放功能
該功能SDK已經(jīng)提供好了接口,直接使用即可。
3.3.2 音量和亮度控制實(shí)現(xiàn)
根據(jù)layout可以看得出,利用FrameLayout的特點(diǎn)(后面視圖會(huì)覆蓋前面視圖),通過(guò)控制后一個(gè)視圖的寬度來(lái)達(dá)到進(jìn)度條的效果。
3.3.3 自動(dòng)隱藏
可用Handle來(lái)實(shí)現(xiàn)自定延時(shí)隱藏的功能,比較實(shí)用。
3.3.4 手勢(shì)
手勢(shì)方面大家可用多查查GestureDetector方面的資料,雙擊、縮放手勢(shì)都可以實(shí)現(xiàn)。
四、代碼下載
請(qǐng)移步#Taocode(SVN):(沒(méi)有賬戶的請(qǐng)注冊(cè)一個(gè)賬戶即可。)
項(xiàng)目地址:http://code.taobao.org/p/oplayer
五、Vitamio相關(guān)信息
5.1 近期將發(fā)布新的SDK版本
5.1.1 將直接內(nèi)置各平臺(tái)解碼器,無(wú)需外下載!
5.1.2 將支持自定義進(jìn)度控制條等。
六、相關(guān)文章
6.1 Android 播放電影時(shí)滑動(dòng)屏幕調(diào)整屏幕亮度
6.2 android MediaPlayer API
結(jié)束
本系列文章承諾每周至少出一篇,以幫助需要的朋友盡快將Vitamio融合入自己或公司的項(xiàng)目中。
以上就是對(duì)Android Vitamio 資料的整理,后續(xù)繼續(xù)補(bǔ)充。
- Android 使用Vitamio打造自己的萬(wàn)能播放器(10)—— 本地播放 (縮略圖、視頻信息、視頻掃描服務(wù))
- Android 使用Vitamio打造自己的萬(wàn)能播放器(9)—— 在線播放 (在線電視)
- Android 使用Vitamio打造自己的萬(wàn)能播放器(8)——細(xì)節(jié)優(yōu)化
- Android 使用Vitamio打造自己的萬(wàn)能播放器(7)——在線播放(下載視頻)
- Android 使用Vitamio打造自己的萬(wàn)能播放器(6)——在線播放(播放列表)
- Android 使用Vitamio打造自己的萬(wàn)能播放器(5)——在線播放(播放優(yōu)酷視頻)
- Android 使用Vitamio打造自己的萬(wàn)能播放器(4)——本地播放(快捷搜索、數(shù)據(jù)存儲(chǔ))
- Android 使用Vitamio打造自己的萬(wàn)能播放器(3)——本地播放(主界面、播放列表)
- Android 使用Vitamio打造自己的萬(wàn)能播放器(1)——準(zhǔn)備
- Android使用vitamio插件實(shí)現(xiàn)視頻播放器
相關(guān)文章
Android實(shí)現(xiàn)圖片轉(zhuǎn)高斯模糊以及高斯模糊布局
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片轉(zhuǎn)高斯模糊的方法,以及高斯模糊布局,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android實(shí)現(xiàn)沉浸式狀態(tài)欄
這篇文章主要為大家詳細(xì)介紹了Android沉浸式狀態(tài)欄的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android實(shí)現(xiàn)TV端大圖瀏覽效果的全過(guò)程
最近的開(kāi)發(fā)中遇到了個(gè)需求,需要在tv端加載很長(zhǎng)的圖片,發(fā)現(xiàn)網(wǎng)上沒(méi)有相關(guān)的資料,所以跟大家分享下,這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)TV端大圖瀏覽效果的相關(guān)資料,需要的朋友可以參考下2023-01-01
Android使用kotlin實(shí)現(xiàn)多行文本上下滾動(dòng)播放
這篇文章主要為大家詳細(xì)介紹了Android使用kotlin實(shí)現(xiàn)多行文本的上下滾動(dòng)播放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
使用newInstance()來(lái)實(shí)例化fragment并傳遞數(shù)據(jù)操作
這篇文章主要介紹了使用newInstance()來(lái)實(shí)例化fragment并傳遞數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
使用Fragment來(lái)處理Andoird app的UI布局的實(shí)例分享
這篇文章主要介紹了使用Fragment來(lái)處理Andoird appUI布局的實(shí)例分享,Fragment的出現(xiàn)緩解了代碼依賴(lài)于Activity而造成的臃腫狀況,需要的朋友可以參考下2016-02-02
Android?kotlin?跳轉(zhuǎn)手機(jī)熱點(diǎn)開(kāi)關(guān)頁(yè)面和判斷熱點(diǎn)是否打開(kāi)(親測(cè)可用)
跳轉(zhuǎn)手機(jī)熱點(diǎn)的頁(yè)面肯定是用intent,重點(diǎn)是action不知道是什么,網(wǎng)上最常見(jiàn)的就是Settings.ACTION_WIFI_SETTINGS 跳轉(zhuǎn)wifi設(shè)置頁(yè)面,本文介紹Android?kotlin?跳轉(zhuǎn)手機(jī)熱點(diǎn)開(kāi)關(guān)頁(yè)面和判斷熱點(diǎn)是否打開(kāi),感興趣的朋友一起看看吧2023-08-08
android實(shí)現(xiàn)上下滾動(dòng)的TextView
android實(shí)現(xiàn)上下滾動(dòng)的TextView,需要的朋友可以參考一下2013-05-05

