How to stream an large file from S3 to a laravel view

寵の児 提交于 2020-08-24 09:17:05

问题


I have this mostly working but having a tough time finalizing it.

For now I have a simple route:

Route::get('file/{id}/', 'FileController@fileStream')->name('file');

this route connects to an action in the FileController:

public function fileStream($id){

    $audio = \App\Audio::where('id', $id)->first();

    $client = S3Client::factory([
        'credentials' => [
            'key'    => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
        ],
        'region' => env('S3REGION'),
        'version' => 'latest',
    ]);


    // Register the stream wrapper from an S3Client object
    $client->registerStreamWrapper();

    if ($stream = fopen('s3://[bucket_name]/'. $audio->audio_url, 'r')) {
        while (!feof($stream)) {
            echo fread($stream, 1024);
        }
        fclose($stream);
    }    
}

This works to the browser: if I go to a url: /file/1 it looks up the right file, and in a clean browser window I get:

And then in my view I am trying to output the audio like:

   <audio>
      <source src="{{ url('file', ['id' => $section->id]) }}" type="{{ $section->audio_mime_type}}"></audio>
   </audio>

But no player is getting output to the screen.

TIA


回答1:


You should use Laravel Streamed response

return response()->streamDownload(function () use ($audio) {
    if ($stream = fopen('s3://[bucket_name]/'. $audio->audio_url, 'r')) {
        while (!feof($stream)) {
            echo fread($stream, 1024);
            flush();
        }
        fclose($stream);
    }    
}, 'file-name.ext');



回答2:


//Get Url from s3 using 
$fileUrl = \Storage::disk('s3')->url($filePath);
$fileName = 'name_of_file.extension';
//Set headers
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.$fileName);

if (!($stream = fopen($response, 'r'))) {
  throw new \Exception('Could not open stream for reading file: 
   ['.$fileName.']');
}
// Check if the stream has more data to read
while (!feof($stream)) {
  // Read 1024 bytes from the stream
  echo fread($stream, 1024);
}
// Be sure to close the stream resource when you're done with it
fclose($stream);



回答3:


Use Laravel/Symfony Response class. Echoing the response could not be setting the right headers.

Even if the headers are set up correctly, you are relying on the echo in the controller action, therefore you should do exit(0); at the end of the controller. Bear in mind that this is rather ugly and it kills the script, you should always aim to use Response classes mentioned above.



来源:https://stackoverflow.com/questions/51622582/how-to-stream-an-large-file-from-s3-to-a-laravel-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!