안드로이드 개발 질문/답변
(글 수 358)
안녕하세요.
미디어파일(mp4)을 재생하면
Survace View에 영상화면이 display되는데요.
이상태에서 메뉴 Activity를 띄우면
Surface View가 destory되고
메뉴Activity에서 이전키를 누르면
다시 미디어 파일 재생 Activity로 오는데
화면이 안나오네요.
소리가 나오는걸 봐서 mp4파일은 계속 재생중에 있습니다.
- Surface View가 destroy되어서 문제인것 같은데..
방법이 없을까요?
PS: 공지사항 다 읽었습니다.
미디어파일(mp4)을 재생하면
Survace View에 영상화면이 display되는데요.
이상태에서 메뉴 Activity를 띄우면
Surface View가 destory되고
메뉴Activity에서 이전키를 누르면
다시 미디어 파일 재생 Activity로 오는데
화면이 안나오네요.
소리가 나오는걸 봐서 mp4파일은 계속 재생중에 있습니다.
- Surface View가 destroy되어서 문제인것 같은데..
방법이 없을까요?
PS: 공지사항 다 읽었습니다.
2009.09.20 01:38:44
흠 일단 SurfaceView가 있는 상태에서 다른 Activity를 뛰울 경우에 onResume, onPause 등에서 동영상 플레이하던 것을 중지하고 다시 시작하는 작업이 필요합니다. 만약 현재 Play상태가 유지되기를 원하신다면 아마도 간단한 비디오 플레이 옵션 정도의 것을 처리하시기 위해 Activity를 뛰우셨을텐데 이런 경우는 SubActivity가 아니라 Dialog로 처리하시는게 좋을것 같네요.
2009.09.20 13:48:33
회색님 빠른 답변 감사드립니다.
영상재생중에 home key를 누를 경우에도 surface view가 destory되기때문에
다시 영상재생activity로 와도 영상이 나오지 않더군요..
그리고 영상재생중에 sms가 오면 사용자에게 알려주고 sms 어플을 띄워야 하기 때문에..
surface view가 destory되고 다시 create되어서 영상화면을 계속 보여줘야 하기 때문에...지금 이고생을..
미디어 플레이어 쪽에 SetDisplay(SurfaceHolder)함수가 있던데..
framework 단으로 내려가서 좀더 삽질을 해봐야할것 같습니다.
어느정도 결과가 나오면 이글 댓글에 달아놓겠습니다.
혹 좋은 생각이 있으시면 어떠한 것이라도좋으니 댓글 부탁드립니다.
영상재생중에 home key를 누를 경우에도 surface view가 destory되기때문에
다시 영상재생activity로 와도 영상이 나오지 않더군요..
그리고 영상재생중에 sms가 오면 사용자에게 알려주고 sms 어플을 띄워야 하기 때문에..
surface view가 destory되고 다시 create되어서 영상화면을 계속 보여줘야 하기 때문에...지금 이고생을..
미디어 플레이어 쪽에 SetDisplay(SurfaceHolder)함수가 있던데..
framework 단으로 내려가서 좀더 삽질을 해봐야할것 같습니다.
어느정도 결과가 나오면 이글 댓글에 달아놓겠습니다.
혹 좋은 생각이 있으시면 어떠한 것이라도좋으니 댓글 부탁드립니다.
2009.09.20 15:33:13
최근 SDK에서는 작업을 안해봤는데 예전에 G1에서 처리해봤던 겁니다. 그런거라면 간단히 생각해서 Activity의 onPause시에 MediaPlayer Pause시키고 현재 정보(재생여부, 현재시간) 기록해둡니다. onResume시에 저장되어있는 정보 확인하고 Surface 가 다시 생성되었을때 계속 재생 진행하면 됩니다. Surface나 Activity의 라이프 사이클만 잘 이해하시고 처리하면 별로 큰 문제는 없을겁니다.
2009.09.20 16:08:34
회색님.빠른 답변 감사드립니다.
말씀하신 내용은
영상재생어플리케이션이 BG TASK로 동작중일때는 재생이 안되고
FG TASK가 되었을경우에만 동작한다는것이군요..
멀티미디어플레이어가 BG TASK일때도 PLAY는 계속시키고 싶은데...
지금 만들고 있는것이 DMB PLAYER인데요..
녹화파일이나 미디어파일도 재생시키는 기능을 포함하고 방송시청도 하는 어플입니다.
방송시청중에 home key를 눌러서 idle로 가더라도 시청중인방송(라디오도 있겠지요.)은 계속 들으면서
SMS를 보낸다던지 등등...그러면서 BG TASK인 DMB Player가 FG TASK로 올라왔을때
방송화면을 계속 보내어야 하는것이 관건입니다.
그래서 미디어파일로 현재 테스트중에 있는데..위와 같이 bg로 갔다가 fg로 올때 미디어재생화면이 걸리네요..
차라리 player가 BG일 경우에는 동작하지 않고 FG에서만 동작한다면..좋겠는데..
mp3플레이어 같은경우에
bg이더라도 음악은 계속 들으니까..
dmb player도 그렇게 시나리오가 잡혔습니다.
bg이더라도 방송시청이나 녹화파일 재생은 문제가 없는데
fg로 올라왔을때 시청화면 또는 재생화면이 걸려 버리네요...ㅜㅜ
얘기가 길었는데요..요지는
BG이더라도 재생화면은 계속 play가 되어야 하고
FG로 왔을때 재생화면이 나와야 한다는것 입니다.
지금까지 확인한바로는
생성된 surface view를 mediaplayer쪽에 넘겨주고나서
activity에서 surface view가 한번 destory되면
mediaplayer는 계속 돌아가고 있지만 화면에 display해줄 방법이 없네요.
방법이 없네요.
framework단에서 mMediaPlayer.setDisplay(mSurfaceHolder);
이 함수를 좀더 뒤져 볼려고 합니다.
말씀하신 내용은
영상재생어플리케이션이 BG TASK로 동작중일때는 재생이 안되고
FG TASK가 되었을경우에만 동작한다는것이군요..
멀티미디어플레이어가 BG TASK일때도 PLAY는 계속시키고 싶은데...
지금 만들고 있는것이 DMB PLAYER인데요..
녹화파일이나 미디어파일도 재생시키는 기능을 포함하고 방송시청도 하는 어플입니다.
방송시청중에 home key를 눌러서 idle로 가더라도 시청중인방송(라디오도 있겠지요.)은 계속 들으면서
SMS를 보낸다던지 등등...그러면서 BG TASK인 DMB Player가 FG TASK로 올라왔을때
방송화면을 계속 보내어야 하는것이 관건입니다.
그래서 미디어파일로 현재 테스트중에 있는데..위와 같이 bg로 갔다가 fg로 올때 미디어재생화면이 걸리네요..
차라리 player가 BG일 경우에는 동작하지 않고 FG에서만 동작한다면..좋겠는데..
mp3플레이어 같은경우에
bg이더라도 음악은 계속 들으니까..
dmb player도 그렇게 시나리오가 잡혔습니다.
bg이더라도 방송시청이나 녹화파일 재생은 문제가 없는데
fg로 올라왔을때 시청화면 또는 재생화면이 걸려 버리네요...ㅜㅜ
얘기가 길었는데요..요지는
BG이더라도 재생화면은 계속 play가 되어야 하고
FG로 왔을때 재생화면이 나와야 한다는것 입니다.
지금까지 확인한바로는
생성된 surface view를 mediaplayer쪽에 넘겨주고나서
activity에서 surface view가 한번 destory되면
mediaplayer는 계속 돌아가고 있지만 화면에 display해줄 방법이 없네요.
방법이 없네요.
framework단에서 mMediaPlayer.setDisplay(mSurfaceHolder);
이 함수를 좀더 뒤져 볼려고 합니다.
2009.09.20 20:46:25
화면이 active 되지 않은 상태에서도 계속 play 되게 하려면 surface가 바뀔때 처리해 주면 될 것 같은데요.
님께서 생각하신대로 SurfaceHolder.Callback interface
2009.09.21 02:00:58
일단 기존 MediaPlayer구성이 모바일 TV와 같은 시나리오는 고려되지 않았을것 같다는 생각이 드는군요. 정말 프레임워크쪽가지 들어가보셔야할듯 :(
2009.09.21 11:13:35
MMPlayer 에서 다른 activity 를 호출하면 surface view 가 destroy 됩니다.
이 때 load 한 activity 에서 이전 MMplayer 로 돌아갈 때 surfaceCreated() 가 호출이 되는데요,
Surfaceholder를 하기 처럼 다시 받아오면 잘 됩니다.
도움이 되셨으면 좋겠네요.
public void surfaceCreated(SurfaceHolder holder) {
this.holder = mPreview.getHolder();
}
2009.09.21 12:24:23
iRoid님 outsidus님 회색님 !
답변 고맙습니다.
바로 테스트해본후 결과 댓글 달겠습니다.
에뮬레이터1.5버젼을 사용하고 있는데..
에뮬레이터가 속도가 많이 느리더군요..실제 타겟이 속도가 더 빠르다는..
그래서 일단 아래와 같이 테스트했는데..
제가 보기엔 사용자에게 충분히 받아드릴수 있을정도의 performance였습니다.
플레이어가 BG로 되더라도 계속 play는 하게 한다(사운드출력되고 있음)
플레이어가 FG로 올라올때
surface view가 create될때 현재 진행시간 저장, mediaplayer를 새로 만들고
저장된 시간만큼 seek, 그리고 start.
잠시 소리 지연이 있지만 사용자에게 충분히 받아들여질수 있을정도 이고여..
iRoid님과 outsidus님의 의견처럼 테스트해보겠습니다.
답변 고맙습니다.
바로 테스트해본후 결과 댓글 달겠습니다.
에뮬레이터1.5버젼을 사용하고 있는데..
에뮬레이터가 속도가 많이 느리더군요..실제 타겟이 속도가 더 빠르다는..
그래서 일단 아래와 같이 테스트했는데..
제가 보기엔 사용자에게 충분히 받아드릴수 있을정도의 performance였습니다.
플레이어가 BG로 되더라도 계속 play는 하게 한다(사운드출력되고 있음)
플레이어가 FG로 올라올때
surface view가 create될때 현재 진행시간 저장, mediaplayer를 새로 만들고
저장된 시간만큼 seek, 그리고 start.
잠시 소리 지연이 있지만 사용자에게 충분히 받아들여질수 있을정도 이고여..
iRoid님과 outsidus님의 의견처럼 테스트해보겠습니다.
2009.09.21 14:58:30
iRoid님의 도움을 받고자 테스트파일을 첨부합니다.
소스를 보시면 아시겠지만
View가 생성될때 getholder를 하고 있는데
surfaceCreated될때 다시 getholder를 하라니 잘 이해가 되지 않습니다.
소스를 보시고 도움좀 주시면 감사하겠습니다.
실행되고 나서 view를 touch하면 mp4파일이 play되는데...
testmp4.mp4를 /sdcard/에 넣어 놓으시면됩니다.
테스트 파일은 아래 댓글에 있습니다
2009.09.21 15:21:34
iRoid님이 말씀하신대로
다시 해봤는데...안됩니다...
surfaceview가 create되고 나서
mp4파일을 재생 시킬때.
mMediaPlayer.setDisplay(holder);
위와같이 SurfaceHolder를 넘겨주고 쭈욱 진행이되는데요..
즉,
mediaplayer에서 넘겨받은 holder의 surface에 디코딩된 mp4영상파일을 뿌리는것 같은데..
activity(어플)에서 surface view가 destroy되고
새로 create되는데 이전 surface holder를 가져온다고 해서 영상화면이 나올지 의문스럽습니다.
숱하게 테스트 해봤는데..잘안되고...미치겠네요...
iRoid님이 방법을 말씀해주셨다는건
된다는 말씀인데....좀 도와주세요 ;p
다시 해봤는데...안됩니다...
surfaceview가 create되고 나서
mp4파일을 재생 시킬때.
mMediaPlayer.setDisplay(holder);
위와같이 SurfaceHolder를 넘겨주고 쭈욱 진행이되는데요..
즉,
mediaplayer에서 넘겨받은 holder의 surface에 디코딩된 mp4영상파일을 뿌리는것 같은데..
activity(어플)에서 surface view가 destroy되고
새로 create되는데 이전 surface holder를 가져온다고 해서 영상화면이 나올지 의문스럽습니다.
숱하게 테스트 해봤는데..잘안되고...미치겠네요...
iRoid님이 방법을 말씀해주셨다는건
된다는 말씀인데....좀 도와주세요 ;p
2009.09.21 18:36:46
제가 이제서야 댓글 다신 걸 읽었네요 ^^;;
Play 상태에서 menu activity 를 띄우는 코드까지 작성이 되신건가요?
방금 첨부해 주신 코드로 재생해 보니 menu 키가 동작하지 않더라고요.
예를 들어 코드 잠깐 보니 onCreateOptionsMenu 같은 작업이 되어 있지 않더라고요..
어떤 시퀀스로 동작시키셨을 때 문제가 되는지 정확히 적어 주시면
제가 내일 확인해보고 댓글 드리겠습니다. ^^
2009.09.22 09:26:57
아..네..
Home Key를 누르거나 Send Key를 누를경우
Surface view가 destroy되는데..
다시 mp4재생 activity로 돌아올 경우의 테스트입니다.
감사합니다. iRoid님.
Home Key를 누르거나 Send Key를 누를경우
Surface view가 destroy되는데..
다시 mp4재생 activity로 돌아올 경우의 테스트입니다.
감사합니다. iRoid님.
2009.09.22 19:21:51
관련해서 분석을 해 보았습니다.
onPause() 시에 현재 위치 등을 저장했다가 이어서 재생하는 방식의 경우에는 정상적으로 동작하는데요
background 에서도 계속 sound 가 나오고 있는 상태에서, surface 만 control 해 줘서는 정상적으로 media player 가
동작하지 않는 구조로 되어 있는 듯 합니다.
Android native media player 의 경우에도 Home 키 등을 눌렀을 경우 activity 를 destory 시키고
해당 positon 에서 이어서 동작하도록 되어 있네요.
background 관련해서는 좀 더 분석해 보고 댓글 달도록 하겠습니다.
많은 도움 못드려서 죄송요 ^^
background 에서 계속 동작하게 하는 부분에 대해서는 저도 좀
2009.09.23 10:45:09
iRoid님 감사합니다.
제가 솔루션을 하나 찾았는데요..
CODEC쪽에서 해결을 한건지..
저도 오늘 분석할려고 합니다.
이 솔루션은 해당 테스트로 해보니 제대로 동작하네요..
아마도
activity에서 surface view를 사용하는 기존의 방식이 아닌것 같다는 추측만..
자세한건 소스를 좀 들여다 봐야 할것 같습니다.
결과가 나오면 댓글 달겠습니다.
제가 솔루션을 하나 찾았는데요..
CODEC쪽에서 해결을 한건지..
저도 오늘 분석할려고 합니다.
이 솔루션은 해당 테스트로 해보니 제대로 동작하네요..
아마도
activity에서 surface view를 사용하는 기존의 방식이 아닌것 같다는 추측만..
자세한건 소스를 좀 들여다 봐야 할것 같습니다.
결과가 나오면 댓글 달겠습니다.
2009.09.24 00:00:31
Open Core쪽에서 video 출력부분을 검토하고 있는데....
뭔가 키를 찾았다고 생각했는데..
문을 열고 들어가니...커다란 벽이 가로막고 있는 느낌입니다...
결국 이부분을 기존 안드로이드의 mediaplayer에서 해결하려면
Packet Video를 뜯어봐야 하네요...
이 문제에 대한 답이 당분간 나오기 힘들것 같습니다.
;|
뭔가 키를 찾았다고 생각했는데..
문을 열고 들어가니...커다란 벽이 가로막고 있는 느낌입니다...
결국 이부분을 기존 안드로이드의 mediaplayer에서 해결하려면
Packet Video를 뜯어봐야 하네요...
이 문제에 대한 답이 당분간 나오기 힘들것 같습니다.
;|
2009.09.24 16:34:03
답이 나왔습니다.
최종 확인은 아직 못했지만
그동안 얻은 답은 아래와 같습니다.
mMediaPlayer.setDisplay(holder)는
PV의 PlayerDriver단으로 명령을 던져주지 않고
mMediaPlayer.prepare()가 실행되어야
PV의 PlayerDriver가 동작하면서 AndroidSurfacePutput으로 가서
실제 영상을 display할 outport가 잡히게되네요.
제가 1.5버젼 안드로이드 소스를 가지고 있는데..
이 소스의 mediaPlayer.java의 setdiaplay()함수에는 그렇게 되어 있네요.
회사에서 작업중인 1.6소스를 받아보니까
setdiaplay()안에 PlayerDriver단으로 내려가게끔 코드가 조금 변경 되어있는데.
원래 1.6 릴리즈가 그렇게 된건지...아니면 회사내 관련팀에서 누군가가 작업을 한건지... ;)
anyway 해결될것 같습니다.
첨부한 고도리님의 번역서를 보시면 조금 이해가 가실듯...
윗단에서 놀기만 했는데...
한동안 PV의 OpenCore 공부를 해야겠습니다.
최종 확인은 아직 못했지만
그동안 얻은 답은 아래와 같습니다.
mMediaPlayer.setDisplay(holder)는
PV의 PlayerDriver단으로 명령을 던져주지 않고
mMediaPlayer.prepare()가 실행되어야
PV의 PlayerDriver가 동작하면서 AndroidSurfacePutput으로 가서
실제 영상을 display할 outport가 잡히게되네요.
제가 1.5버젼 안드로이드 소스를 가지고 있는데..
이 소스의 mediaPlayer.java의 setdiaplay()함수에는 그렇게 되어 있네요.
회사에서 작업중인 1.6소스를 받아보니까
setdiaplay()안에 PlayerDriver단으로 내려가게끔 코드가 조금 변경 되어있는데.
원래 1.6 릴리즈가 그렇게 된건지...아니면 회사내 관련팀에서 누군가가 작업을 한건지... ;)
anyway 해결될것 같습니다.
첨부한 고도리님의 번역서를 보시면 조금 이해가 가실듯...
윗단에서 놀기만 했는데...
한동안 PV의 OpenCore 공부를 해야겠습니다.