2016-05-31 9 views
1

ここに私の問題です:私はアンドロイド標準メディアプレーヤーを使用して再現する必要があったMP3ファイルを提供する必要があるlaravelバックエンドを書いています。

私はJWTを使用して認証を処理する必要があるので、すべてのリクエストヘッダーで「承認」フィールドを「ベアラ{トークン}」に設定する必要があります。
laravel経路は「/歌/ {ID}」とこのように処理される:アンドロイド側android with Laravel

public function getSong(Song $song) { 
    $file = new File(storage_path()."/songs/".$song->path.".mp3"); 

    $headers = array(); 
    $headers['Content-Type'] = 'audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'; 
    $headers['Content-Length'] = $file->getSize(); 
    $headers['Content-Transfer-Encoding'] = 'binary'; 
    $headers['Accept-Range'] = 'bytes'; 
    $headers['Cache-Control'] = 'must-revalidate, post-check=0, pre-check=0'; 
    $headers['Connection'] = 'Keep-Alive'; 
    $headers['Content-Disposition'] = 'attachment; filename="'.$song->path.'.mp3"'; 

    $user = \Auth::user(); 
    if($user->activated_at) { 
     return Response::download($file, $song->path, $headers); 
    } 
    \App::abort(400); 
} 

私はこのようにしてMP3ファイルをストリーミングするメディア・プレイヤーを使用している:

media_player = new MediaPlayer(); 
    try { 
     media_player.setAudioStreamType(AudioManager.STREAM_MUSIC); 

     String token = getSharedPreferences("p_shared", MODE_PRIVATE).getString("token", null); 
     Map<String, String> headers = new HashMap<>(); 
     headers.put("Authorization", "Bearer " + token); 

     media_player.setDataSource(
      getApplicationContext(), 
      Uri.parse(ConnectionHelper.SERVER + "/songs/" + song.getId()), 
      headers 
     ); 
    } catch (IOException e) { 
     finish(); 
     Toast.makeText(
       Round.this, 
       "Some error occurred. Retry in some minutes.", 
       Toast.LENGTH_SHORT 
     ).show(); 
    } 
    media_player.setOnCompletionListener(this); 
    media_player.setOnErrorListener(this); 
    media_player.setOnPreparedListener(this); 

しかし、私はコードを実行するたびに、私はERROR_CONNECTION_LOSTを意味し、エラーリスナーに余分なコード-1005を取得します。

答えて

2

問題応答::ダウンロード(...)は、ストリームを生成しませんので、私は私の.mp3ファイルを提供することはできません。

ソリューション: symfonyのHttpFoundation doc.は、ファイルサービスの段落で言うように:

"if you are serving a static file, you can use a BinaryFileResponse" 

私が奉仕する必要があるの.mp3ファイルがサーバーに静的であり、「/ストレージ/歌に保存されています/は「私はBinaryFileResponseを使用することを決めた、と.MP3を提供するための方法はなった:

use Symfony\Component\HttpFoundation\BinaryFileResponse; 

[...] 

public function getSong(Song $song) { 
    $path = storage_path().DIRECTORY_SEPARATOR."songs".DIRECTORY_SEPARATOR.$song->path.".mp3"); 

    $user = \Auth::user(); 
    if($user->activated_at) { 
     $response = new BinaryFileResponse($path); 
     BinaryFileResponse::trustXSendfileTypeHeader(); 

     return $response; 
    } 
    \App::abort(400); 
} 

BinaryFileResponseは自動的にリクエストを処理し、Http 200コードで1回だけリクエストすることでファイルを完全に処理できるようにしたり、低速な接続(Http 206コードでのリクエスト数が増え、200コードでの1回の最終リクエスト)で分割できます。
あなたが使用することができますmod_xsendfileをお持ちの場合は追加することによって、(より速くストリーミング作るために):

BinaryFileResponse::trustXSendfileTypeHeader(); 

アンドロイドのコードは、ファイルをストリーミングするために、変更する必要はありません。