介紹個第三方:
實現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 }
