4 minutes
Creating a Laravel package for chunked video upload
Creating a Laravel package for chunked video upload involves several steps. The package will include the necessary backend logic for handling chunked uploads and provide an easy way to integrate the functionality into any Laravel application.
Step 1: Create the Package Structure
Create the Package Directory:
mkdir -p packages/YourVendor/ChunkedVideoUpload cd packages/YourVendor/ChunkedVideoUpload
Initialize Composer:
composer init
Setup the Directory Structure:
packages/YourVendor/ChunkedVideoUpload ├── src │ ├── ChunkedVideoUploadServiceProvider.php │ ├── Controllers │ │ └── VideoUploadController.php │ ├── routes │ │ └── web.php ├── composer.json └── README.md
Step 2: Setup Composer
Edit the composer.json
file to include the necessary information and autoloading:
{
"name": "your-vendor/chunked-video-upload",
"description": "A Laravel package for chunked video uploads",
"type": "library",
"autoload": {
"psr-4": {
"YourVendor\\ChunkedVideoUpload\\": "src/"
}
},
"require": {
"php": ">=7.4",
"illuminate/support": ">=8.0"
},
"extra": {
"laravel": {
"providers": [
"YourVendor\\ChunkedVideoUpload\\ChunkedVideoUploadServiceProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
Step 3: Create the Service Provider
In src/ChunkedVideoUploadServiceProvider.php
:
<?php
namespace YourVendor\ChunkedVideoUpload;
use Illuminate\Support\ServiceProvider;
class ChunkedVideoUploadServiceProvider extends ServiceProvider
{
public function boot()
{
// Load routes
$this->loadRoutesFrom(__DIR__ . '/routes/web.php');
// Publish configuration
$this->publishes([
__DIR__ . '/config/chunkedvideoupload.php' => config_path('chunkedvideoupload.php'),
]);
}
public function register()
{
// Merge configuration
$this->mergeConfigFrom(
__DIR__ . '/config/chunkedvideoupload.php', 'chunkedvideoupload'
);
}
}
Step 4: Create the Controller
In src/Controllers/VideoUploadController.php
:
<?php
namespace YourVendor\ChunkedVideoUpload\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;
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', uniqid()); // Generate 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 5: Define Routes
In src/routes/web.php
:
<?php
use Illuminate\Support\Facades\Route;
use YourVendor\ChunkedVideoUpload\Controllers\VideoUploadController;
Route::post('/upload-chunk', [VideoUploadController::class, 'uploadChunk']);
Step 6: Configuration File
In src/config/chunkedvideoupload.php
:
<?php
return [
'chunk_size' => 1 * 1024 * 1024, // 1MB
];
Step 7: Register the Package
In your Laravel project’s composer.json
, add the repository and require the package:
"repositories": [
{
"type": "path",
"url": "packages/YourVendor/ChunkedVideoUpload"
}
],
"require": {
"your-vendor/chunked-video-upload": "*"
}
Run composer update
to install the package.
Step 8: Publish the Configuration
Run the following command to publish the configuration file:
php artisan vendor:publish --provider="YourVendor\ChunkedVideoUpload\ChunkedVideoUploadServiceProvider"
Step 9: Use the Package
In your Laravel application, you can now use the chunked upload functionality by sending POST requests to /upload-chunk
.
Step 10: Frontend Integration
For the frontend, you can use the React component provided earlier to handle chunked uploads:
import React, { useState } from 'react';
const ChunkedVideoUpload = () => {
const [file, setFile] = useState(null);
const handleFileChange = (event) => {
setFile(event.target.files[0]);
};
const uploadFile = async () => {
if (!file) {
alert('Please select a file first');
return;
}
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!');
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={uploadFile}>Upload</button>
</div>
);
};
export default ChunkedVideoUpload;
Step 11: Testing
Ensure that your /upload-chunk
endpoint is reachable and working correctly by uploading a large video file using the React component.
This setup provides a modular and reusable package for handling chunked video uploads in Laravel, along with a React component for the frontend.