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
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');
//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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With