
Laravel 11: How to Download Files from External URLs and Servers
In this article , we will learn the process of streaming and downloading videos in Laravel.The ability to download the video on the web is increasing now-a-days. We will cover how to fetch videos headers , manage HTTP responses and download videos directly.
Setting Up the Controller Method
We need to create a method in our controller to handle video download requests. This method will use Laravel's Http facade to fetch the video headers, check if the video is available, and then stream it to the user.
``` public function downloadVideo() { $videoUrl = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; $response = Http::head($videoUrl); if (!$response->successful()) { return response()->json(['error' => 'Failed to fetch video headers'], 500); } // Get content type and content length $contentType = $response->header('Content-Type', 'application/octet-stream'); $contentLength = $response->header('Content-Length'); // Set headers for the response return response()->stream(function () use ($videoUrl) { $stream = fopen($videoUrl, 'r'); while (!feof($stream)) { echo fread($stream, 8192); flush(); } fclose($stream); }, 200, [ 'Content-Type' => $contentType, 'Content-Disposition' => 'attachment; filename="video.mp4"', 'Content-Transfer-Encoding' => 'binary', 'Content-Length' => $contentLength, ]); } ```Let's go through the code step by step:
Fetching Video Headers:
```php $response = Http::head($videoUrl); ```We use the Http::head method to send a HEAD request to the video URL. This request retrieves the headers of the video file without downloading the entire file. It is a quick way to check if the video is accessible and to get its metadata.
Checking the Response:
```php if (!$response->successful()) { return response()->json(['error' => 'Failed to fetch video headers'], 500); } ```We verify if the response from the HEAD request is successful. If it's not, we return a JSON response with an error message and a 500 status code, indicating a server error.
Retrieving Content Type and Length
```php $contentType = $response->header('Content-Type', 'application/octet-stream'); $contentLength = $response->header('Content-Length'); ```We extract the Content-Type and Content-Length headers from the response. These headers are necessary to properly set up the download response.
Streaming the Video
```php return response()->stream(function () use ($videoUrl) { $stream = fopen($videoUrl, 'r'); while (!feof($stream)) { echo fread($stream, 8192); flush(); } fclose($stream); }, 200, [ 'Content-Type' => $contentType, 'Content-Disposition' => 'attachment; filename="video.mp4"', 'Content-Transfer-Encoding' => 'binary', 'Content-Length' => $contentLength, ]); ```Using the response()->stream method, we stream the video content to the user. We open a read stream to the video URL and read the content in small chunks (8192 bytes) to handle large files efficiently.
The flush function ensures that each chunk is sent to the user immediately, providing a smooth streaming experience. The headers we set ensure the file is recognized as a downloadable attachment.