Chunked video upload is useful for handling large files by splitting them into smaller parts, uploading each part individually, and then combining them back together on the server. Here’s how you can implement chunked video upload in Laravel:

Step 1: Frontend Setup

You can use JavaScript to handle the chunking of the video file. Here’s an example using vanilla JavaScript:

<!DOCTYPE html>
<html>
<head>
    <title>Chunked Video Upload</title>
</head>
<body>
    <input type="file" id="fileInput" />
    <button onclick="uploadFile()">Upload</button>

    <script>
        async function uploadFile() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];
            const chunkSize = 1 * 1024 * 1024; // 1MB chunks
            const totalChunks = Math.ceil(file.size / chunkSize);

            for (let i = 0; i < totalChunks; i++) {
                const start = i * chunkSize;
                const end = Math.min(start + chunkSize, file.size);
                const chunk = file.slice(start, end);

                const formData = new FormData();
                formData.append('file', chunk);
                formData.append('chunk', i);
                formData.append('totalChunks', totalChunks);

                await fetch('/upload-chunk', {
                    method: 'POST',
                    body: formData,
                });
            }

            alert('Upload complete!');
        }
    </script>
</body>
</html>

Step 2: Backend Setup

In your Laravel project, you will need to handle these chunks and store them temporarily until all chunks are received. Then, you can merge them into a single file.

1. Create a Controller

Create a controller to handle the chunk uploads:

php artisan make:controller VideoUploadController

2. Define the Routes

Add the following route to your routes/web.php:

use App\Http\Controllers\VideoUploadController;

Route::post('/upload-chunk', [VideoUploadController::class, 'uploadChunk']);

3. Handle Chunk Uploads in the Controller

In your VideoUploadController, add the following method:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class VideoUploadController extends Controller
{
    public function uploadChunk(Request $request)
    {
        $chunk = $request->file('file');
        $chunkIndex = $request->input('chunk');
        $totalChunks = $request->input('totalChunks');
        $fileId = $request->input('fileId'); // Optionally use a unique identifier for the file

        // Temporary storage for chunks
        $tempDir = storage_path('app/temp_uploads');
        if (!file_exists($tempDir)) {
            mkdir($tempDir, 0777, true);
        }

        // Save the chunk
        $chunk->move($tempDir, $fileId . '-' . $chunkIndex);

        // If this is the last chunk, combine all chunks
        if ($chunkIndex == $totalChunks - 1) {
            $finalPath = storage_path('app/videos/' . $fileId . '.mp4');
            $outputFile = fopen($finalPath, 'ab');

            for ($i = 0; $i < $totalChunks; $i++) {
                $chunkPath = $tempDir . '/' . $fileId . '-' . $i;
                $chunkData = file_get_contents($chunkPath);
                fwrite($outputFile, $chunkData);
                unlink($chunkPath); // Remove chunk after merging
            }

            fclose($outputFile);

            return response()->json(['message' => 'File upload complete'], 200);
        }

        return response()->json(['message' => 'Chunk uploaded'], 200);
    }
}

Step 3: Configuration

Ensure your storage directories have the correct permissions and are writable by the web server.

Step 4: Testing

Upload a large video file through your frontend and verify that the backend correctly receives, processes, and combines the chunks into a single video file.

This example provides a basic implementation. Depending on your requirements, you might need to add more error handling, validation, and security measures.

Further reading

Making a package