介绍个第三方:
实现Android的全屏视频播放,支持完全自定义UI、手势修改进度和音量、hls、rtsp,设置http头信息,也能在ListView、ViewPager和ListView、ViewPager和Fragment等多重嵌套模式下全屏工作,占用空间非常小,不到60k。
本次是通过 SurfaceView + MediaPlayer 实现 横屏 全屏 播放。
//注意修改:
WindowFeature下的:Window.FEATURE_NO_TITLE, Window.FEATURE_INDETERMINATE_PROGRESS
Fullscreen
AndroidManifest.xml下activity节点添加android:screenOrientation="landscape"
1)通过 AudioManager 控制视频声音。
2)通过getWindow().getAttributes().screenBrightness 获取当前亮度,通过继承SimpleOnGestureListener手势监听onScroll,onSingleTapUp事件,
重新生成
1 WindowManager.LayoutParams lpa = getWindow().getAttributes(); 2 if (lpa.screenBrightness > 1.0f) 3 lpa.screenBrightness = 1.0f; 4 else if (lpa.screenBrightness < 0.01f) 5 lpa.screenBrightness = 0.01f; 6 7 getWindow().setAttributes(lpa);
3)activity oncreate 进行初始化 MediaPlayer, SurfaceView Holder
1 if (mediaPlayer == null) { 2 mediaPlayer = new MediaPlayer(); 3 // 不维持自身缓冲区,直接显示 4 // this value only use Hardware decoder before Android 2.3 5 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB 6 && mHardwareDecoder) { 7 sv_videoplayer.getHolder().setType( 8 SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 9 } 10 sv_videoplayer.getHolder().setFixedSize( 11 ScreenUtils.getScreenHeight(this), 12 ScreenUtils.getScreenWidth(this)); 13 14 sv_videoplayer.getHolder().setFormat(PixelFormat.RGBA_8888); 15 16 sv_videoplayer.getHolder().setKeepScreenOn(true); 17 sv_videoplayer.getHolder().addCallback(new SurFaceCallback()); 18 }
4)调用 MediaPlayer 进行播放
1 mediaPlayer.reset(); 2 mediaPlayer.setDataSource(playUrl); 3 mediaPlayer.setDisplay(sv_videoplayer.getHolder()); 4 // 缓冲 5 mediaPlayer.prepareAsync(); 6 mediaPlayer 7 .setOnBufferingUpdateListener(new BufferingUpdateListener()); 8 mediaPlayer.setOnPreparedListener(new PreparedListener(position)); 9 mediaPlayer.setOnCompletionListener(new CompletionListener());
5)在缓冲就绪初始化MediaController
1 /** 2 * //调用该方法,MediaPlayer就进入了"准备就绪" //状态,准备开始播放. //此处可用于动态设置SurfaceView的宽和高 3 * 4 */ 5 private final class PreparedListener implements OnPreparedListener { 6 private int position; 7 8 public PreparedListener(int position) { 9 this.position = position; 10 } 11 12 @Override 13 public void onPrepared(MediaPlayer arg0) { 14 // TODO Auto-generated method stub 15 //MediaController进行设置和使用 16 mMediaController.setMediaPlayer(VideoPlayerActivity.this); 17 mMediaController.setAnchorView(findViewById(R.id.rl_video_player)); 18 mMediaController.setEnabled(true); 19 mMediaController.show(); 20 mediaPlayer.start(); 21 mProgressBar.setVisibility(View.GONE); 22 mLoadRate.setVisibility(View.GONE); 23 if (position > 0) 24 mediaPlayer.seekTo(position); 25 } 26 27 }
6)显示缓冲百分比
1 private final class BufferingUpdateListener implements 2 OnBufferingUpdateListener { 3 4 @Override 5 public void onBufferingUpdate(MediaPlayer arg0, int percent) { 6 // TODO Auto-generated method stub 7 mLoadRate.setText(percent + "%"); 8 } 9 }
7)使用getHolder().addCallback(new SurFaceCallback()),继承Callback,
SurfaceView 所在Activity 离开了前台,SurfaceView会被destory。当Activity又重新
回到前台时,SurfaceView会被重新创建,SurfaceView是在onResume()方法之后被创建。
防止视频过程中,电话来到,导致视频播放失败。
1 private final class SurFaceCallback implements Callback { 2 3 @Override 4 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, 5 int arg3) { 6 7 } 8 9 @Override 10 public void surfaceCreated(SurfaceHolder arg0) { 11 if (mediaPlayer == null) { 12 return; 13 } 14 if (playUrl != null && position > 0) { 15 play(position); 16 position = 0; 17 } 18 } 19 20 @Override 21 public void surfaceDestroyed(SurfaceHolder arg0) { 22 if (mediaPlayer == null) { 23 return; 24 } 25 if (mediaPlayer.isPlaying()) { 26 mediaPlayer.stop(); 27 } 28 } 29 }