2012-01-10 2 views
2

임의의 InputStream을 MediaPlayer 객체의 데이터 소스로 사용하고 싶습니다.임의의 스트림을 MediaPlayer의 소스로 사용

이유는 내가 사용하고있는 InputStream이 원격 서버의 미디어 리소스에 대한 인증 된 HTTPS 연결이라는 것입니다. 이 경우 URL을 전달하는 것은 인증이 필요하므로 분명히 작동하지 않습니다. 그러나 인증을 별도로 수행하여 리소스에 대한 InputStream을 얻을 수 있습니다. 문제가 발생하면 어떻게해야합니까?

명명 된 파이프를 사용하고 해당 FileDescriptor를 MediaPlayer의 setDataResource 메서드에 전달하는 옵션에 대해 생각했습니다. 안드로이드에서 NDK를 사용하지 않고 명명 된 파이프를 만드는 방법이 있습니까?

다른 제안 사항이 있으면 언제든지 환영합니다.

+0

이것이 차이가 있는지 확인할 수는 없지만 운이 좋다면 우리는 Uri가''https : // username : password @ server.com/stream.data'' 인증을 지원할 수도 있습니다. 인증이 기본 인증과 다른 경우 이는 매우 명백합니다. – harism

+0

아니요, 인증은 암호를 기반으로하지 않습니다. – smichak

답변

1

또 다른 해결책은 로컬 호스트에 프록시 HTTP 서버를 시작하는 것입니다. 미디어 플레이어는 setDataSource (컨텍스트 컨텍스트, Uri uri)를 사용하여이 서버에 연결합니다. 이 솔루션은 이전 버전보다 효과적이며 재생을 결함으로 만들지 않습니다.

+1

후손을 위해, 다음은 프록시 서버의 예입니다. http://stackoverflow.com/a/5432091/931277 – dokkaebi

3

나는 해결책을 찾았다 고 생각합니다. 관심있는 다른 사람들이 직접 시도해보고 장치 모델 및 SDK 버전으로 결과를보고 해 주시면 감사하겠습니다.

나는 비슷한 게시물을 보았지만, 어쨌든 최신이며 SDK의 최신 버전에서 작동하는 것처럼 보인다. 지금까지 Android 2.3.6을 실행하는 Nexus One에서 작동한다.

이 솔루션은 입력 스트림을 로컬 파일로 버퍼링하는 데 의존합니다 (외부 저장소에이 파일이 있지만 내부 저장소에도 파일을 배치 할 수 있음) MediaPlayer 인스턴스에 해당 파일의 설명자를 제공 할 수 있습니다 .

AudioPlayback 않는 일부 AsyncTask를하는 doInBackground 방법에서 다음을 실행 :

@Override 
protected 
Void doInBackground(LibraryItem... params) 
{ 
    ... 

    MediaPlayer player = new MediaPlayer(); 
    setListeners(player); 

    try { 
     _remoteStream = getMyInputStreamSomehow(); 
     File tempFile = File.createTempFile(...); 
     tempFile.deleteOnExit(); 
     _localInStream = new FileInputStream(tempFile); 
     _localOutStream = new FileOutputStream(tempFile); 
     int buffered = bufferMedia(
      _remoteStream, _localOutStream, BUFFER_TARGET_SIZE  // = 128KB for instance 
     ); 

     player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     player.setDataSource(_localInStream.getFD()); 
     player.prepareAsync(); 

     int streamed = 0; 
     while (buffered >= 0) { 
      buffered = bufferMedia(
       _remoteStream, _localOutStream, BUFFER_TARGET_SIZE 
      ); 
     } 
    } 
    catch (Exception exception) { 
     // Handle errors as you see fit 
    } 

    return null; 
} 

bufferMedia 방법 버퍼 nBytes 바이트 또는 입력의 끝에 도달 할 때까지 :

private 
int bufferMedia(InputStream inStream, OutputStream outStream, int nBytes) 
throws IOException 
{ 
    final int BUFFER_SIZE = 8 * (1 << 10); 
    byte[] buffer = new byte[BUFFER_SIZE];   // TODO: Do static allocation instead 

    int buffered = 0, read = -1; 
    while (buffered < nBytes) { 
     read = inStream.read(buffer); 
     if (read == -1) { 
      break; 
     }   
     outStream.write(buffer, 0, read); 
     outStream.flush(); 
     buffered += read; 
    } 

    if (read == -1 && buffered == 0) { 
     return -1; 
    } 

    return buffered; 
} 

setListeners 방법 다양한 MediaPlayer 이벤트에 대한 핸들러를 설정합니다. 가장 중요한 것은 재생 완료시 이 호출되는 OnCompletionListener입니다. 버퍼 언더런의 경우 (즉, 느린 네트워크 연결로 인해) 플레이어 은 로컬 파일의 끝에 도달하고 PlaybackCompleted 상태로 이동합니다. 필자는 _localInStream의 위치 인 을 입력 스트림의 크기와 비교하여 이러한 상황을 확인합니다. 위치가 작은 경우, 재생이 이제 정말 을 완료하고 난 MediaPlayer를을 재설정 :

private 
void setListeners(MediaPlayer player) 
{ 
    // Set some other listeners as well 

    player.setOnSeekCompleteListener(
     new MediaPlayer.OnSeekCompleteListener() 
     { 
      @Override 
      public 
      void onSeekComplete(MediaPlayer mp) 
      { 
       mp.start(); 
      } 
     } 
    ); 

    player.setOnCompletionListener(
     new MediaPlayer.OnCompletionListener() 
     { 
      @Override 
      public 
      void onCompletion(MediaPlayer mp) 
      { 
       try { 
        long bytePosition = _localInStream.getChannel().position(); 
        int timePosition = mp.getCurrentPosition(); 
        int duration = mp.getDuration(); 

        if (bytePosition < _track.size) {       
         mp.reset(); 
         mp.setDataSource(_localInStream.getFD()); 
         mp.prepare(); 
         mp.seekTo(timePosition); 
        } else {        
         mp.release(); 
        } 
       } catch (IOException exception) { 
        // Handle errors as you see fit 
       } 
      } 
     } 
    ); 
} 
관련 문제