Laravel大视频文件异步上传及Queue实现方案咨询
Absolutely feasible! Laravel Queues were built specifically for handling long-running, non-blocking tasks like large video uploads—this is exactly the kind of problem they solve. Let’s walk through how to implement this, including the key details you need to know.
Short answer: Yes, 100%. Making users wait 5-10 minutes for an upload creates a terrible experience, and offloading this work to a queue lets them continue using your site while the heavy lifting runs in the background. Laravel’s queue system integrates seamlessly with its task scheduling and notification features, so this workflow is straightforward to build.
1. Configure Your Queue Driver
First, set up your queue backend. Laravel supports several drivers (Redis, Database, Amazon SQS, etc.). Redis is ideal for speed, but Database works great if you don’t have Redis set up yet.
- Update your
.envfile:QUEUE_CONNECTION=redis # or database - If using the Database driver, create the required queue tables:
php artisan queue:table php artisan migrate
2. Create a Video Upload Job
Generate a dedicated job class to handle the upload processing:
php artisan make:job ProcessVideoUpload
This creates a file in app/Jobs/ProcessVideoUpload.php. Open it and update the handle() method with your upload logic. Here’s a practical example:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Mail; use App\Mail\VideoUploadCompleted; class ProcessVideoUpload implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $tempFilePath; protected $userId; protected $userEmail; /** * Create a new job instance. */ public function __construct(string $tempFilePath, int $userId, string $userEmail) { $this->tempFilePath = $tempFilePath; $this->userId = $userId; $this->userEmail = $userEmail; } /** * Execute the job. */ public function handle(): void { // 1. Move file from temporary to permanent storage $permanentPath = 'videos/user_' . $this->userId . '/' . basename($this->tempFilePath); Storage::move($this->tempFilePath, $permanentPath); // 2. Optional: Add video processing (transcoding, thumbnail generation, etc.) // Use packages like FFmpeg here if you need to manipulate the video // 3. Update your database (mark video as uploaded, store the path, etc.) // Example: App\Models\Video::create(['user_id' => $this->userId, 'path' => $permanentPath]) // 4. Send completion email to the user Mail::to($this->userEmail)->send(new VideoUploadCompleted($permanentPath)); // 5. Clean up the temporary file to save storage space Storage::delete($this->tempFilePath); } }
3. Build the Frontend & Backend Upload Flow
You can’t pass raw files directly to the queue (queues serialize data, and files can’t be serialized). Instead, use a two-step process:
Frontend Steps:
- User selects a video file.
- Upload the file to a temporary storage location via an AJAX request (e.g., to a
/api/upload-tempendpoint). - The endpoint returns the temporary file path (or cloud storage object key) to the frontend.
- The frontend then calls a second endpoint (e.g.,
/api/process-video) with the temp path, user ID, and user email.
Backend Temp Upload Endpoint Example:
// routes/api.php Route::post('/upload-temp', function (Request $request) { $request->validate([ 'video' => 'required|file|mimes:mp4,mov,avi|max:102400', // Adjust max size as needed ]); $tempPath = $request->file('video')->store('temp_videos'); return response()->json(['temp_path' => $tempPath]); });
Backend Dispatch Job Endpoint:
// routes/api.php Route::post('/process-video', function (Request $request) { $request->validate([ 'temp_path' => 'required|string', 'user_id' => 'required|integer', 'user_email' => 'required|email', ]); // Dispatch the job to the queue ProcessVideoUpload::dispatch( $request->temp_path, $request->user_id, $request->user_email ); return response()->json(['message' => 'Upload started! You\'ll get an email when it\'s done.']); });
4. Run the Queue Worker
To process queued jobs, start a queue worker:
php artisan queue:work
For production, use a process manager like Supervisor to ensure the worker stays running even if the server restarts. Laravel’s official docs have detailed steps for setting this up.
When dispatching the job, send these key pieces of data (not the raw file):
- Temporary file path/object key: The location where the uploaded file is temporarily stored.
- User ID: To associate the video with the correct user in your database.
- User email: To send the completion notification.
- Optional: Video metadata (original filename, file size) for database records or the notification email.
- User selects a video and clicks "Upload".
- Frontend uploads the video to a temporary storage endpoint, gets a temp path in return.
- Frontend sends the temp path, user ID, and email to the job dispatch endpoint.
- Laravel adds the
ProcessVideoUploadjob to the queue. - Queue worker picks up the job, moves the file to permanent storage, processes it (if needed), updates the database, and sends an email.
- User receives an email once the upload is complete, without waiting around.
内容的提问来源于stack exchange,提问作者Luke Brandon Farrell

