본문 바로가기

안드로이드

Media Player에 대한 설명

[1-1] MediaPlayer
 1. 사용
   MediaPlayer player = new MediaPlayer();
   player.setDataSource();
   player.prepare(); 
   player.start();

 2. 앱단과 엔진단의 쌍방향 호출형태
   app -( 특정명령 )> MediaPlayer로 호출
   Engine  - (NuPlayer)의 처리결과(에러, prepare완료, 재생완료, 알람 등) -> App으로 전달

 3. new MediaPlayer의 코드
   looper 생성 ( 큐잉된 메세지들 처리 )
    -> EventHandler생성 ( Async로 작동하는 API 에서 Engine->app으로 보내는 메세지들 큐잉)
    -> Message


[1-2] MediaPlayer API 설명
 1.데이터 셋팅( 무조건 Sync로 작동한다. )
   file데이터 셋팅
    -  SetDataSource(fd, offset, length)     
   streaming데이터 셋팅 
    -  nativeSetDataSource( httpServiceBinder, path, keys, values)

 2. prepare() , prepareAsync
  SetDataSource에서 전달받은 source로  FileFormat 을 만들고, 재생을 준비한다.
  Async일때, 엔진에서 처리가 완료되면 onPrePared event를 통해 app에 이벤트를 전달한다.

 3. start()
  surface에 비디올르 그리고, 오디오를 출력한다.
  surface 객체 : 비디오를 그릴 수 있도록 준비된 도화지이다.
  surface를 코덱으로 넘기고, 
  미디어 코덱은 outputBuffer을 채워서  decoding 된것을 받으면 그려달라고 요청 할 수 있다.
 4. getCurrentPosition
  app 이 현재 재생위치를 받아와서 재생바를 그릴 수 있게 한다.
 
 5. getDuration
 해당 파일의 재생 길이를 보내줄 수 있다.

 6.SeekTo
  파라미터에 해당하는 시간 위치로 이동한다. 
  가장 가까운 SyncFrame(IDR)을 쓸것인지 등 설정가능하다.

 7. Reset
  리소스를 다 사용했을때 재사용 가능하도록 초기화 해준다.
 
 8. Release 
  재사용 불가능하도록 해제한다.


[1-3] MediaPlayer의 Engine->App 호출 API
 1. onPrepared 
  preparedAsync가 완료됨을 알린다. setOnPreparedListner를 등록해야 callback받을 수 있다.

 2. onInfo
  엔진이 가지고 있는 다양한 재생 정보들을 app으로 보낸다. (다음 비디오가 재생되엇다는 알람, 첫번째 비디오가 렌더링 되었다는정보, 스트리밍에서 버퍼링이 시작되었다는 메세지,  버퍼링이 종료되었다는 메세지, 오디오,비디오가 처리중 중지됨 등)

 3. onError 
  매번 polling 을 하고 있을 수 없으니, 에러 리스너도 있다. 

===============================================

[2] 미디어플레이어의 진화
 1-1. MediaPlayer : Media컨텐츠를 재생할 수 있는 api
 1-2. AudioTrack : PCM Stream을 재생할 수 있는 API ( 미디어, 게임 등에서 활용)
 1-3. MediaRecoder : 녹화를 통해 Media 컨텐츠 생성
    2-1. MediaMetadataRetriever : Media콘텐츠 속성들이나 Thumbnail을 추출할 수 있는 API 이다.
        3-1. MediaCodec : Codec을 직접 사용할 수 있는 API
        3-2. MediaExtractor : Extractor( FileFormat을 직접 사용할 수 있다)

[2-1]미디어 플레이어의 단점
 너무 편리하게 인터페이스만 뚫어놓다 보니
 App단에서 조작할 수 있는 부분이 제한적이다.
 앱단은 애자일하게 나아가야 하는데, 미디어플레이어의 오류수정을 기다리고 있어야한다.
 간단한 앱들은 미디어 플레이어를 쓰고있다.
 전력소모가 크다.

[2-2] ExoPlayer의 출시
 App단에서 모든것을 조작할 수 있다.
 App의 Market Source에 플레이어 소스코드가 다 포함된다.
 유튜브 같은 빠른 수정이나 다양한 기능추가가 필요한 서비스앱기업들은 이것을 쓰고있다.
  

[2-3] NuPlayer
 각 모듈을 메세지 기반으로 Async하게 Looper(Thread)로 분리했다.
 잦은 IPC를 없애서 전력 소모량을 줄였다.
 
 1. 구성 모듈 
  - NuPlayerSource : <Generic> 소스를 읽어들여서 AnotherPacketSource에 스트림을 오디오,비디오 따로넣는다.
  - NuPlayerDecoderBase : Stream을  MediaCodec에 보내서 decoding 된 Frame을 받아낸다. 그리고 Renderer로 전달.
  - NuPlayerRenderer : Surface에 그려내고, AudioTrack으로 전달시킨다. MediaClock 으로 AVSync를 맞춘다.

  위 세개는 모두 AHandler 기반이며, Alooper를 이용한 AMessage전달 방식을 통해서 상호 Event 를 전달한다.

 2. Offload재생 방식
  AP 가 슬립, DSP 재생 을 통해 전력 소모를 줄인다.




[3] AudioTrack 의 PCM 재생방식
 open - 
 write - pcm 데이터(buffer)를 AudioTrack에 write ( blocking 유/무 )
 start - Stream재생시작
 pause - Stream 재생중지
 stop  - AudioTrack 에 남아있는 buffer를 모두 재생하고 멈춤
 flush - AudioTrack에 있는 buffer를 모두 비움
 getTimeStamp


[3-1] AudioTrack의 Offload 재생방식
 write - AudioTrack open 하고, callBackFunction 셋팅됨
 start - Stream재생시작, start호출하면 open함수 호출시 전달했던 callback Function 으로 buffer요청이 전달됨
 pause - Stream 재생중지
 stop  - player에서 더이상 전달할 오디오 bitstream이 없을 경우 호출된다. 
           AudioTrack은 stop 을 받으면, 더이상 callback을 호출하지 않음
 flush - 전달했던 buffer를 모두 비움
 getTimeStamp
       - offload를 통해 출력된 frame에 대한 시간 정보를 제공