회원로그인
MediaPlayer 가로일 때 UI 숨기고 풀스크린 만들기
10년 전
가로일 땐 모든 UI와 상태바(StatusBar)까지 없애고 풀스크린으로 동영상 플레이를 하고자 한다면, 이런 방법도 괜찮다.
해당 Activity에 아래 속성을 추가한다.
android:screenOrientation="unspecified"
android:configChanges="orientation"
android:theme="@android:style/Theme.Black.NoTitleBar
자바 소스코드를 작성해보자.
package hansune.android.test;
import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
public class MoviePlayTestActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
private int mVideoWidth;
private int mVideoHeight;
private SurfaceView mPreview;
private SurfaceHolder holder;
private MediaPlayer videoPlayer;
private String path;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
private MediaPlayer bgm;
private ImageButton playBtn;
private int pausePosition = -1;
private boolean isCompletePlay = false;//동영상 플레이를 완료했는지요?
private boolean isSurfaceDestroy = true;//Surface 가 없어졌는지요?
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPreview = (SurfaceView)findViewById(R.id.surfaceView1);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
playBtn = (ImageButton)findViewById(R.id.playBtn);
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!isCompletePlay) {
if(videoPlayer.isPlaying()) {
videoPlayer.pause();
bgm.pause();
playBtn.setImageResource(R.drawable.btn_play_big);
}
else {
videoPlayer.start();
bgm.start();
playBtn.setImageResource(R.drawable.btn_pause_big);
}
}
else
{
pausePosition = -1;
playVideo(path);
}
}
});
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
}
@Override
protected void onPause() {
if(videoPlayer != null && !isCompletePlay) {
pausePosition = videoPlayer.getCurrentPosition();
playBtn.setImageResource(R.drawable.btn_play_big);
videoPlayer.pause();
}
if(bgm != null) bgm.pause();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if(!isCompletePlay) {
if(bgm != null) bgm.start();
playBtn.setImageResource(R.drawable.btn_pause_big);
playBtn.setEnabled(true);
//재생 중이고 Surface 가 죽지 않았을 경우 플레이한다.
//Surface 가 Destroy이 되면, surfaceCreated 에서 다시 생성된 후 플레이 되도록 한다.
if(pausePosition != -1 && !isSurfaceDestroy) playVideo(path);
}
}
@Override
protected void onDestroy() {
releaseMediaPlayer();
doCleanUp();
System.gc();
if(bgm != null){
bgm.release();
bgm = null;
}
super.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
arrangeVideo();
}
private void arrangeVideo() {
WindowManager wm = getWindowManager();
if(wm == null) return;
LinearLayout ll = (LinearLayout)findViewById(R.id.playBtnLayout);
if(wm.getDefaultDisplay().getRotation() == Surface.ROTATION_90 || wm.getDefaultDisplay().getRotation() == Surface.ROTATION_270) {
Log.d("dd", "landscape");
ll.setVisibility(View.GONE);
hideStatusBar();
}
else {
Log.d("dd", "portrat");
ll.setVisibility(View.VISIBLE);
showStatusBar();
}
//
int videoWidth = videoPlayer.getVideoWidth();
int videoHeight = videoPlayer.getVideoHeight();
Log.d("dd", "video :" + videoWidth + "/" + videoHeight);
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
Log.d("dd", "screen : " + screenWidth + "/" + screenHeight);
android.view.ViewGroup.LayoutParams lp = mPreview.getLayoutParams();
//portrat
if(screenWidth < screenHeight) {
lp.width = screenWidth;
lp.height = (int)(((float)videoHeight / (float)videoWidth) * (float)screenWidth);
}
else {
lp.width = (int)(((float)videoWidth / (float)videoHeight) * (float)screenHeight);
lp.height = screenHeight;
}
Log.d("dd", lp.width + "/" + lp.height);
mPreview.setLayoutParams(lp);
}
private void hideStatusBar() {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
}
private void showStatusBar() {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
}
private void releaseMediaPlayer() {
if (videoPlayer != null) {
videoPlayer.release();
videoPlayer = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d("dd", "surfaceChanged called");
if(videoPlayer != null) {
videoPlayer.setDisplay(surfaceholder);
arrangeVideo();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isSurfaceDestroy = false;
//서페이스가 생성되면 영상재생을 실행한다.
playVideo(path);
Log.d("dd", "surfaceCreated called");
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
isSurfaceDestroy = true;
Log.d("dd", "surfaceDestroyed called");
}
@Override
public void onVideoSizeChanged(MediaPlayer arg0, int width, int height) {
Log.v("dd", "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e("dd", "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
playBtn.setEnabled(true);
playBtn.setImageResource(R.drawable.btn_pause_big);
}
}
@Override
public void onPrepared(MediaPlayer arg0) {
Log.d("dd", "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
playBtn.setEnabled(true);
playBtn.setImageResource(R.drawable.btn_pause_big);
}
}
@Override
public void onCompletion(MediaPlayer arg0) {
Log.i("dd", "complete movie");
playBtn.setEnabled(true);
playBtn.setImageResource(R.drawable.btn_play_big);
if(bgm != null) bgm.pause();
pausePosition = -1;
isCompletePlay = true;
}
@Override
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
}
private void playVideo(String path) {
doCleanUp();
if(videoPlayer == null) videoPlayer = new MediaPlayer();
videoPlayer.reset();
mIsVideoSizeKnown = false;
mIsVideoReadyToBePlayed = false;
playBtn.setEnabled(false);
try {
AssetFileDescriptor afd = getAssets().openFd("example.mp4");
videoPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
videoPlayer.setDisplay(holder);
videoPlayer.prepareAsync();
videoPlayer.setOnBufferingUpdateListener(this);
videoPlayer.setOnCompletionListener(this);
videoPlayer.setOnPreparedListener(this);
videoPlayer.setOnVideoSizeChangedListener(this);
videoPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IllegalArgumentException e) {
Log.e("dd", e.getMessage());
} catch (IllegalStateException e) {
Log.e("dd", e.getMessage());
//e.printStackTrace();
} catch (IOException e) {
Log.e("dd", e.getMessage());
//e.printStackTrace();
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback() {
Log.v("dd", "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
arrangeVideo();
if(pausePosition != -1)videoPlayer.seekTo(pausePosition);
pausePosition = -1;
videoPlayer.start();
// MediaPlayer 객체 생성
if(bgm != null) {
bgm.release();
bgm = null;
}
bgm = new MediaPlayer();
AssetFileDescriptor afd;
try {
afd = getAssets().openFd("background_music.mp3");
bgm.setDataSource(afd.getFileDescriptor());
bgm.prepare();
bgm.setLooping(true);
bgm.setAudioStreamType(AudioManager.STREAM_MUSIC);
bgm.setVolume(0.5f, 0.5f);
bgm.start();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
핵심.
1. 디바이스의 회전을 알기 위해 메니페스트 파일을 설정하는 것
2. 스크린의 가로세로 길이를 구하는 것(ex. getWindowManager().getDefaultDisplay().getWidth())
3. SurfaceView는 가로세로 크기를 wrap_content 으로 하나 match_parent 로 하나 큰 의미가 없다는 것. 소스의 크기에 좌우되게 하라.
4. StatusBar를 보이거나 숨기기
5. 재생 도중 홈 버튼을 누르거나 전원 버튼을 눌러서 앱이 멈추었다가, 다시 실행할 때 멈췄던 부분부터 다시 재생하게 하기. 이때 Surface 가 죽었는지 조심해야 한다.
추천 : 476
추천
목록