使用Vitamio打造自己的Android萬能播放器(1)——准備
一、實現目標
1.1亮度控制
模仿VPlayer界面:
1.2聲音控制
模仿VPlayer界面:
1.3畫面縮放
根據下面API提供畫面的拉伸、剪切、100%、全屏
二、Vitamio API 介紹
VideoView
2.1public void start()
開始播放
2.2public void pause()
暫停播放
2.3public long getDuration()
獲取視頻的時長
2.4public long getCurrentPosition()
獲取已經播放的時長
2.5public void seekTo(long msec)
設置播放器從指定的位置開始播放
2.6public boolean isPlaying()
是否正在播放
2.7public int getVideoWidth()
獲取視頻寬
2.8public int getVideoHeight()
獲取視頻高
2.9public void setBufferSize(int bufSize)
設置緩存大小,默認1024KB
2.10public void setVideoQuality(int quality)
設置視頻質量,低、中、高(MediaPlayer.VIDEOQUALITY_LOW、MediaPlayer.VIDEOQUALITY_MEDIUM 、MediaPlayer.VIDEOQUALITY_HIGH ),
默認低(最流暢)。
2.11public void setSubShown(boolean shown)
設置是否顯示字幕
2.12public void setAudioTrack(int audioIndex)
設置音軌,必須是getAudioTrackMap(String) 的返回值。
2.13public void setVolume(float leftVolume, float rightVolume)
設置立體音左右音量。
2.14public void setSubPath(String subPath)
設置外掛字幕路徑
2.15public int getBufferPercentage()
獲取緩沖百分比
2.16public void stopPlayback()
停止播放
2.17public void setVideoPath(String path)
設置視頻播放路徑
2.18public void setVideoURI(Uri uri)
設置視頻播放路徑
2.19public void setVideoLayout(int layout, float aspectRatio)
設置視頻縮放(拉伸、剪切、100%、全屏)
三、 實現代碼
3.1xml
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/surface_view" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
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">
android:layout_gravity="center" android:src="@drawable/video_volumn_bg"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="25dip">
android:layout_gravity="left" android:src="@drawable/video_num_bg"
android:layout_width="94dip" android:layout_height="wrap_content" />
android:layout_gravity="left" android:src="@drawable/video_num_front"
android:layout_width="0dip" android:layout_height="wrap_content"
android:scaleType="matrix" />
3.2Activity
/**
*
* 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(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 將支持自定義進度控制條等。