视频功能:
1、视频播放的控制台,进度条,播放、暂停按钮、播放时长,返回按钮,播放影片的名称
2、调节音量
3、调节亮度
4、拖动屏幕来进行视频的快进跟快退
5、视频在横竖屏切换的时候的显示(注:动态改变vidwoView的高度能解决切换的时候自适应的问题)
开发的资料:
1、首先要有vitamio的library,这里是我修改过的一个 :http://download.csdn.net/detail/u012808234/8959989
2、然后就是一个vitamio的api文档,网上直接搜就好了;
然后就是真正的开发了
首先新建一个项目 : Vitamio_Demo, 然后就是把vitamio的library导入。
(1)在第一次进入的时候一定要对vitamio进行初始化及检查,
- new AsyncTask<Object, Object, Object>() {
- @Override
- protected Object doInBackground(Object... params) {
- Vitamio.initialize(getApplicationContext());
- if (Vitamio.isInitialized(getApplicationContext()))
- return null;
- //反射解压
- try {
- Class c = Class.forName("io.vov.vitamio.Vitamio");
- Method extractLibs = c.getDeclaredMethod("extractLibs", new Class[] { android.content.Context.class, int.class });
- extractLibs.setAccessible(true);
- extractLibs.invoke(c, new Object[] { getApplicationContext(), R.raw.libarm });
- // Field vitamioLibraryPath = c.getDeclaredField("vitamioLibraryPath");
- //
- // AndroidContextUtils.getDataDir(ctx) + "libs/"
- } catch (NoSuchMethodException e) {
- Log.e("extractLibs", e.toString());
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
- }.execute();
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
Vitamio.initialize(getApplicationContext());
if (Vitamio.isInitialized(getApplicationContext()))
return null;
//反射解压
try {
Class c = Class.forName("io.vov.vitamio.Vitamio");
Method extractLibs = c.getDeclaredMethod("extractLibs", new Class[] { android.content.Context.class, int.class });
extractLibs.setAccessible(true);
extractLibs.invoke(c, new Object[] { getApplicationContext(), R.raw.libarm });
// Field vitamioLibraryPath = c.getDeclaredField("vitamioLibraryPath");
//
// AndroidContextUtils.getDataDir(ctx) + "libs/"
} catch (NoSuchMethodException e) {
Log.e("extractLibs", e.toString());
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}.execute();
(2) 实现一堆接口: OnClickListener, OnCompletionListener, OnInfoListener,
OnPreparedListener, OnErrorListener, OnBufferingUpdateListener, OnSeekCompleteListener
OnPreparedListener, OnErrorListener, OnBufferingUpdateListener, OnSeekCompleteListener
- private void stopPlayer() {
- if (mVideoView != null)
- mVideoView.pause();
- }
- private void startPlayer() {
- if (mVideoView != null)
- mVideoView.start();
- }
- private boolean isPlaying() {
- return mVideoView != null && mVideoView.isPlaying();
- }
- /** 是否�?��自动恢复播放,用于自动暂停,恢复播放 */
- private boolean needResume;
- @Override
- public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
- switch (arg1) {
- case MediaPlayer.MEDIA_INFO_BUFFERING_START:
- // �?��缓存,暂停播�?
- if (isPlaying()) {
- stopPlayer();
- needResume = true;
- }
- mLoadingView.setVisibility(View.VISIBLE);
- break;
- case MediaPlayer.MEDIA_INFO_BUFFERING_END:
- // 缓存完成,继续播�?
- if (needResume) {
- startPlayer();
- }
- mLoadingView.setVisibility(View.GONE);
- break;
- case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
- // 显示 下载速度
- break;
- }
- return true;
- }
- /**
private void stopPlayer() {
if (mVideoView != null)
mVideoView.pause();
}
private void startPlayer() {
if (mVideoView != null)
mVideoView.start();
}
private boolean isPlaying() {
return mVideoView != null && mVideoView.isPlaying();
}
/** 是否�?��自动恢复播放,用于自动暂停,恢复播放 */
private boolean needResume;
@Override
public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
switch (arg1) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
// �?��缓存,暂停播�?
if (isPlaying()) {
stopPlayer();
needResume = true;
}
mLoadingView.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
// 缓存完成,继续播�?
if (needResume) {
startPlayer();
}
mLoadingView.setVisibility(View.GONE);
break;
case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
// 显示 下载速度
break;
}
return true;
}
/**
- * 播放完成
- */
- @Override
- public void onCompletion(MediaPlayer arg0) {
- }
- /**
- * //在视频预处理完成后调用。在视频预处理完成后被调用。此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。
- */
- @Override
- public void onPrepared(MediaPlayer arg0) {
- }
- /**
- * 在异步操作调用过程中发生错误时调用。例如视频打开失败。
- */
- @Override
- public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
- mLoadingView.setVisibility(View.GONE);
- mTv_NoPlay.setVisibility(View.VISIBLE);
- return false;
- }
- /**
- * 在网络视频流缓冲变化时调用。
- *
- * @param arg0
- * @param arg1
- */
- @Override
- public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
- mTv_NoPlay.setVisibility(View.GONE);
- mLoadingView.setVisibility(View.VISIBLE);
- }
- /**
- * 在seek操作完成后调用。
- */
- @Override
- public void onSeekComplete(MediaPlayer arg0) {
- }
- private MediaController.PlayControl mPlayControll = new PlayControl() {
- @Override
- public void downLoad() {
- }
- @Override
- public void collect() {
- }
- };
- lt;span style="white-space:pre"> </span>//点击开始暂停的回调
- private onPauseListener mPauseListener = new onPauseListener() {
- @Override
- public void onPause() {
- Log.d("pause", "pause");
- }
- @Override
- public void onPlay() {
- Log.e("onPlay", "play");
- }
- };
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- }
* 播放完成
*/
@Override
public void onCompletion(MediaPlayer arg0) {
}
/**
* //在视频预处理完成后调用。在视频预处理完成后被调用。此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。
*/
@Override
public void onPrepared(MediaPlayer arg0) {
}
/**
* 在异步操作调用过程中发生错误时调用。例如视频打开失败。
*/
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
mLoadingView.setVisibility(View.GONE);
mTv_NoPlay.setVisibility(View.VISIBLE);
return false;
}
/**
* 在网络视频流缓冲变化时调用。
*
* @param arg0
* @param arg1
*/
@Override
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
mTv_NoPlay.setVisibility(View.GONE);
mLoadingView.setVisibility(View.VISIBLE);
}
/**
* 在seek操作完成后调用。
*/
@Override
public void onSeekComplete(MediaPlayer arg0) {
}
private MediaController.PlayControl mPlayControll = new PlayControl() {
@Override
public void downLoad() {
}
@Override
public void collect() {
}
};
<span style="white-space:pre"> </span>//点击开始暂停的回调
private onPauseListener mPauseListener = new onPauseListener() {
@Override
public void onPause() {
Log.d("pause", "pause");
}
@Override
public void onPlay() {
Log.e("onPlay", "play");
}
};
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
然后就是实现他们的方法
(3) 然后初始化videoView, 进度条,等等的控件。
- if (mPath.startsWith("http:"))
- mVideoView.setVideoURI(Uri.parse(mPath));
- else
- mVideoView.setVideoPath(mPath);
- // 设置显示名称
- mMediaController = new MediaController(MainActivity.this, mVideoView);
- mMediaController.setmPlayControl(mPlayControll);
- mMediaController.setOnPauseListener(mPauseListener);
- mVideoView.setMediaController(mMediaController);
- mMediaController.setFileName("哈哈哈");
- int mCurrentOrientation = getResources().getConfiguration().orientation;
- if (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT) {
- Utils.full(false, MainActivity.this);
- mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 400));
- if (mVideoView != null){
- mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH, 0);
- }
- } else if (mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
- Utils.full(true, MainActivity.this);
- mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- if (mVideoView != null)
- mVideoView.setVideoLayout(mLayout, 0);
- }
- mVideoView.requestFocus();
if (mPath.startsWith("http:"))
mVideoView.setVideoURI(Uri.parse(mPath));
else
mVideoView.setVideoPath(mPath);
// 设置显示名称
mMediaController = new MediaController(MainActivity.this, mVideoView);
mMediaController.setmPlayControl(mPlayControll);
mMediaController.setOnPauseListener(mPauseListener);
mVideoView.setMediaController(mMediaController);
mMediaController.setFileName("哈哈哈");
int mCurrentOrientation = getResources().getConfiguration().orientation;
if (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT) {
Utils.full(false, MainActivity.this);
mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 400));
if (mVideoView != null){
// mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH, 0);
}
} else if (mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
Utils.full(true, MainActivity.this);
mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
}
mVideoView.requestFocus();
(4)然后就是进行音量调节,快进,快退亮度的调节,使用手势监听就能实现这一点
- <span style="white-space:pre"> </span>mGestureDetector = new GestureDetector(new MyGestureListener());
<span style="white-space:pre"> </span>mGestureDetector = new GestureDetector(new MyGestureListener());
然后就是在onTouch 跟onScroll 里边进行处理;
现在我是把屏幕分成平均的俩分,如果是在左边滑动,而且没有在快进回事快退的时候就是调整亮度,反之就是调整音量。
在调整进度的时候是不能调整亮度的,我加了这判断,而且视频只有在快进已经快退完成以后才进行视频的seekTo()。
- /** 滑动 */
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- mMediaController.hide();
- float mOldX = e1.getX(), mOldY = e1.getY();
- int y = (int) e2.getRawY();
- int x = (int) e2.getRawX();
- Display disp = getWindowManager().getDefaultDisplay();
- int windowWidth = disp.getWidth();
- int windowHeight = disp.getHeight();
- if (Math.abs(x- mOldX) >20 && !isUp_downScroll) { //执行快进快退
- isFast_Forword = true;
- mFast_forward = x - mOldX;
- fast_ForWord(mFast_forward);
- }else if (mOldX > windowWidth * 1.0 / 2 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 右边滑动
- onVolumeSlide((mOldY - y) / windowHeight);
- else if (mOldX < windowWidth / 2.0 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 左边滑动
- onBrightnessSlide((mOldY - y) / windowHeight);
- return super.onScroll(e1, e2, distanceX, distanceY);
- }
/** 滑动 */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
mMediaController.hide();
float mOldX = e1.getX(), mOldY = e1.getY();
int y = (int) e2.getRawY();
int x = (int) e2.getRawX();
Display disp = getWindowManager().getDefaultDisplay();
int windowWidth = disp.getWidth();
int windowHeight = disp.getHeight();
if (Math.abs(x- mOldX) >20 && !isUp_downScroll) { //执行快进快退
isFast_Forword = true;
mFast_forward = x - mOldX;
fast_ForWord(mFast_forward);
}else if (mOldX > windowWidth * 1.0 / 2 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 右边滑动
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX < windowWidth / 2.0 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 左边滑动
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
- /**
- * 滑动改变声音大小
- *
- * @param percent
- */
- private void onVolumeSlide(float percent) {
- isUp_downScroll = true;
- 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 onVolumeSlide(float percent) {
isUp_downScroll = true;
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) {
- isUp_downScroll = true;
- 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);
- }
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
isUp_downScroll = true;
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);
}
在手势进行快进快退的时候让时间进行改变:
- private void fast_ForWord(float dis){
- long currentProgress ;
- long duration = mVideoView.getDuration();
- if (mVideoView.getCurrentPosition() + 500*(long)dis < 0)
- currentProgress = 0;
- else
- currentProgress = mVideoView.getCurrentPosition() + 500*(long)dis;
- mTv_progress.setText(Utils.generateTime(currentProgress) + "/" + Utils.generateTime(duration));
- if (dis > 0)
- mIv_Progress_bg.setImageResource(R.drawable.btn_fast_forword);
- else
- mIv_Progress_bg.setImageResource(R.drawable.btn_back_forword);
- mFl_Progress.setVisibility(View.VISIBLE);
- }
private void fast_ForWord(float dis){
long currentProgress ;
long duration = mVideoView.getDuration();
if (mVideoView.getCurrentPosition() + 500*(long)dis < 0)
currentProgress = 0;
else
currentProgress = mVideoView.getCurrentPosition() + 500*(long)dis;
mTv_progress.setText(Utils.generateTime(currentProgress) + "/" + Utils.generateTime(duration));
if (dis > 0)
mIv_Progress_bg.setImageResource(R.drawable.btn_fast_forword);
else
mIv_Progress_bg.setImageResource(R.drawable.btn_back_forword);
mFl_Progress.setVisibility(View.VISIBLE);
}
改变进度是在onTouch 的action _up 的时候执行的:
- @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;
- if (isFast_Forword) {
- onSeekProgress(mFast_forward);
- }
- // 隐藏
- mDismissHandler.removeMessages(0);
- mDismissHandler.sendEmptyMessageDelayed(0, 800);
- }
@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;
if (isFast_Forword) {
onSeekProgress(mFast_forward);
}
// 隐藏
mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 800);
}
- <span style="white-space:pre"> </span>onSeekProgress(long)是调整进度的:<pre name="code" class="java"> private void onSeekProgress(float dis){
- Log.e("position ==", mVideoView.getCurrentPosition() + 500*(long)dis+"/"+mVideoView.getDuration());
- mVideoView.seekTo(mVideoView.getCurrentPosition() + 500*(long)dis);