MediaPlayer + Proxy で気を付けること

暗号化された楽曲ファイルを複合化しながら再生しようとした場合、
MediaPlayerとファイル間にProxyをはさんでやるのはよく見かける方法だと思います。
しかし、MediaPlayerはRangeRequestを送ってくる(端末がある)ので、
Proxyはそれに対応出来ようにしておかないとえらい目にあいます。
ちなみにRangeRequestを送ってくるMediaPlayerですが、
手元にある端末ではNexus7(OS5.0)からこの動きになっています。

具体的に、まずリクエスト読み込み部分でRangeタグの有無をチェックしましょう。

InputStream is = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is), 2048);
String line;
while (!TextUtils.isEmpty((line = reader.readLine()))) {
  if (line.contains("Range:")) {
    String[] rangetag = (line.split("="))[1].split("-");
    mRangeRequest = Long.parseLong(rangetag[0]);
  }
  result.append(line);
}

そんでもってレスポンスを返す部分で、

String headers = "";
long length = dataSource.getContentLength();  // コンテンツサイズ
String mime = dataSource.getContentType();// コンテンツタイプ
if (mRangeRequest > 0) {
  headers += "HTTP/1.1 206 Partial Content\r\n";
  headers += "Content-Type: " + mime + "\r\n";  
  headers += "Accept-Ranges: bytes\r\n";
  headers += "Content-Length: " + (length - mRangeRequest) + "\r\n";
  headers += "Content-Range: bytes " + mRangeRequest + "-" + (length - 1) + "/" + length + "\r\n";
  headers += "Connection: Keep-Alive\r\n";
  headers += "\r\n";
} else {
  headers += "HTTP/1.1 200 OK\r\n";
  headers += "Content-Type: " + mime + "\r\n";
  headers += "Accept-Ranges: bytes\r\n";
  headers += "Content-Length: " + length + "\r\n";
  headers += "Connection: Keep-Alive\r\n";
  headers += "\r\n";
}

Rangeタグの有無によってレスポンスヘッダを変えてあげましょう。
また、レスポンスヘッダを作った後は、実際にコンテンツを書き込んでいく部分があると思いますが、Rangeタグがあった場合は、InputStream#skip を使って必要な分だけスキップしましょう。

if (mRangeRequest > 0) {
  long n = mRangeRequest;
  while (n > 0) {
    long amt = in.skip(n);
    if (amt == 0) {
      if (in.read() == -1) {throw new EOFException();}
      n--;
    } else {
      n -= amt;
    }
  }
}

コメント

このブログの人気の投稿

Activity以外からstartActivityする

in app billing v3 でサンドボックステストするときの話

@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree