마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

서피스뷰(SurfaceView)에서 동영상 재생관련 질문입니다.

–1 추천

안녕하세요. 안드로이드 초보자 학생입니다.

다름이 아니고 이번에 안드로이드 동영상재생 관련 어플을 하나 만들고있습니다.

 

어플의 구조는 이렇습니다.

처음화면에 SurfaceView가 있습니다.

그 위에 버튼이 있는데, 녹화, 녹화중지, 재생목록입니다.

녹화 버튼을 누르면 녹화가 되고, 녹화중지를 누르면 특정 경로에 녹화된 파일이 저장됩니다.

재생목록버튼을 누르면 해당 경로로 가서 파일들을 모두 보여주고, 해당 파일을 클릭하면 이전 화면으로 돌아와 재생이 되어야합니다.

그런데 해당 파일을 누르면 이전 액티비티로 돌아와서 영상이 재생되지 않습니다.:(

진저브레드(갤럭시 Ace)버전에서는 소리만 나오고 화면이 나오질 않으며, 아이스크림샌드위치 이상의 휴대폰(갤럭시S3)로 테스트했을때는 Logcat에 에러가 수두룩하게 나오면서 실행이 되지 않습니다.

에러내용 : [The Surface has been released.]

무엇이 문제인지 선배님들의 조언좀 부탁드립니다(T_T);

 

 

[MainActivity.java]

여기서 호출하는 PlayActivity.java에서는 그저 파일을 보여주고, 해당 파일 클릭시 path를 인텐트에 담아 MainActivity로 보내주는 역할만 합니다.

그리고 액티비티간의 Focus이동 없이 재생을 하면 재생이 잘 됩니다.

package org.androidtown.castone_videorec;

import ..

public class MainActivity extends Activity {
	
	public static final String TAG = "Capstone_VideoRecorder";
	private static String EXTERNAL_STORAGE_PATH = "";
    private static String RECORDED_FILE = "video_recorded";
    private static int fileIndex = 0;
    private static String filename = "";
    public static final int REQUEST_CODE_ANOTHER = 1001;
    
	MediaPlayer mPlayer;
	MediaRecorder mRecorder;
	MediaController mc;
	SurfaceView surface;
	SurfaceHolder holder;
	
	
	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// check external storage
        String state = Environment.getExternalStorageState();
        if (!state.equals(Environment.MEDIA_MOUNTED)) {
        	Log.d(TAG, "External Storage Media is not mounted.");
        } else {
        	EXTERNAL_STORAGE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+"/capstone_dir";
        	File path = new File(EXTERNAL_STORAGE_PATH);
        	if (!path.isDirectory()){
        		path.mkdirs();
        	}
        }
        
		// =======================================================
		//  1. 서피스뷰 객체 생성/설정
		// =======================================================
		surface = (SurfaceView) findViewById(R.id.videoSurface);
		holder = surface.getHolder();
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		Log.i("onCreate","surfaceView height : "+surface.getHeight());
		
		// =======================================================
		//  2. 화면 레이아웃 변수설정.
		// =======================================================
        final FrameLayout frame = (FrameLayout) findViewById(R.id.videoLayout);
        final LinearLayout btnLayout = (LinearLayout) findViewById(R.id.btnLayout);
		final Button btnRecord = (Button) findViewById(R.id.btnRecord); 
		final Button btnStopRecord = (Button) findViewById(R.id.btnStopRecord);
		final Button btnPlayList = (Button) findViewById(R.id.btnPlayList);
		
		// =======================================================
		//  3. [화면] OnClick Event 추가 (버튼활성화 비활성화)
		// =======================================================
		frame.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {			
				
				frameOnClick(btnLayout);
			}
		});
		
		// =======================================================
		//  4. [녹화]버튼 OnClick Event 추가
		// =======================================================
		btnRecord.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				btnRecordOnClick(holder);
			}
		});
		
		// =======================================================
		//  5. [녹화중지]버튼 OnClick Event 추가
		// =======================================================
		btnStopRecord.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				btnStopRecordOnClick();				
			}
		});
		
		// =======================================================
		//  6. [재생가능목록] OnClick Event 추가
		// =======================================================
		btnPlayList.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				btnPlayListOnClick();
			}
		});
		
		Button btnPlay = (Button) findViewById(R.id.btnPlay);
		btnPlay.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				mPlayer = new MediaPlayer();

				try{
	            	mPlayer.setDataSource("/mnt/sdcard/capstone_dir/video_recorded0.mp4");
	            	mPlayer.setDisplay(holder);
	
	            	mPlayer.prepare();
	            	mPlayer.start();
				} catch (Exception e) {
					Log.e(TAG, "Video play failed.", e);
				}
			}
		});
	} 

	/*********************************************************
	 * 프레임 온클릭이벤트 함수.
	 *********************************************************/
	public void frameOnClick(LinearLayout btnLayout){
		..중략..
	}
	
	/*********************************************************
	 * 녹화버튼 온클릭이벤트 함수.
	 *********************************************************/
	public void btnRecordOnClick(SurfaceHolder holder){

		..중략..
	}
	
	/*********************************************************
	 * 녹화중지 온클릭이벤트 함수
	 *********************************************************/
	public void btnStopRecordOnClick(){
		..중략..
	}
	
	/*********************************************************
	 * 재생목록 온클릭이벤트 함수.
	 *********************************************************/
	public void btnPlayListOnClick(){
		
		// 인텐트 객체를 만듭니다.
		Intent intent = new Intent(getBaseContext(), PlayActivity.class);
		
		// 액티비티를 띄워주도록 startActivityForResult() 메소드를 호출합니다.
		startActivityForResult(intent, REQUEST_CODE_ANOTHER);
	}
	
	/*********************************************************
	 * 파일명 만드는함수 (Sequential)
	 *********************************************************/
	private String createFilename() {
		..중략..
    }
	
	
	/*********************************************************
	 * 메뉴버튼 클릭이벤트 함수.
	 *********************************************************/
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		..중략..
	}
	
	/*********************************************************
	 * PlayActivity 호출 후 리턴함수
	 *********************************************************/
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Log.i("onActivityResult","onActivityResult has been called. [" + surface.isEnabled() + "]");		
		
		//Toast.makeText(getApplicationContext(), "hello1", 1).show();
		if (requestCode == REQUEST_CODE_ANOTHER) {
			
			if (resultCode == RESULT_OK) {
				String mPath = data.getExtras().getString("vPath");
				
                if (mPlayer == null) {
                	Log.i("onActivityResult","mRecorder is null.");
                	mPlayer = new MediaPlayer();
                }
                try {
                	Log.i("onActivityResult","surfaceView height : "+surface.getHeight());
                	
                	Log.i("test", "path : " + mPath);
                	mPlayer.setDataSource(mPath);
                	mPlayer.setDisplay(holder);

                	mPlayer.prepare();
                	mPlayer.start();
                } catch (Exception e) {
                    Log.e(TAG, "Video play failed.", e);
                }
               
			}
		}
	}
	
	protected void onPause() {
		
		Log.i("onPause","onPause() has been called.");
	
        if (mRecorder != null) {
        	Log.i("onPause","mRecorder is not null.");
        	mRecorder.release();
        	mRecorder = null;
        }

        if (mPlayer != null) {
        	Log.i("onPause","mPlayer is not null.");
        	mPlayer.release();
        	mPlayer = null;
        }
        
        super.onPause();
        
    }
}

 

다른팀 (110 포인트) 님이 2013년 2월 26일 질문
다른팀님이 2013년 2월 26일 수정

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...