Laravel中上传前压缩视频至指定大小的实现方法咨询
Hey there! Great question—yes, you absolutely can implement video compression in Laravel to shrink that 12MB video down to under 10MB before (or during) upload. Let me walk you through two reliable approaches: frontend compression (best for user experience, since it cuts down upload time) and backend compression (for cases where you need server-side control).
1. Frontend Compression (Upload-Time Shrinking)
Doing compression in the browser means your user doesn’t have to wait to upload the full 12MB file—way better for UX. You can use JavaScript libraries like browser-video-compressor or ffmpeg.wasm to handle this directly in your Laravel Blade view.
Here’s a quick implementation example:
<form id="videoUploadForm" action="{{ route('videos.store') }}" method="POST" enctype="multipart/form-data"> @csrf <input type="file" id="videoFile" accept="video/*"> <button type="submit">Upload Compressed Video</button> </form> <script src="https://unpkg.com/browser-video-compressor@latest/dist/index.umd.js"></script> <script> const videoInput = document.getElementById('videoFile'); const form = document.getElementById('videoUploadForm'); videoInput.addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; // Compress to target ~10MB (tweak params for quality/size balance) const compressedFile = await browserVideoCompressor.compress(file, { quality: 0.6, // Lower values = smaller files, adjust based on your needs maxSize: 10 * 1024 * 1024, // 10MB in bytes width: 1280, // Optional: reduce resolution to cut size further }); // Replace original file with compressed version in the form const dataTransfer = new DataTransfer(); dataTransfer.items.add(compressedFile); videoInput.files = dataTransfer.files; }); </script>
This will automatically shrink the video before the form submits, so only the smaller file gets sent to your Laravel backend.
2. Backend Compression (Server-Side Processing)
If you prefer handling compression on the server (or need to support users with older browsers), you can use PHP-FFMpeg—a powerful library for video manipulation.
First, install the package and ensure FFmpeg is set up on your server:
composer require php-ffmpeg/php-ffmpeg
(Note: Most hosting providers support FFmpeg, but if not, you can install it via apt install ffmpeg or yum install ffmpeg on Linux servers.)
Then, add this compression logic to your Laravel controller:
use FFMpeg\FFMpeg; use FFMpeg\Format\Video\X264; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; public function store(Request $request) { $request->validate([ 'video' => 'required|file|mimes:mp4,mov|max:12000', // Allow up to 12MB original file ]); $videoFile = $request->file('video'); $originalPath = $videoFile->getRealPath(); $outputFileName = 'compressed_' . $videoFile->getClientOriginalName(); $outputPath = storage_path('app/public/' . $outputFileName); // Initialize FFMpeg (update binary paths to match your server setup) $ffmpeg = FFMpeg::create([ 'ffmpeg.binaries' => '/usr/bin/ffmpeg', 'ffprobe.binaries' => '/usr/bin/ffprobe', ]); $video = $ffmpeg->open($originalPath); // Calculate target bitrate to hit ~10MB (based on video duration) $duration = $video->getFFProbe()->format($originalPath)->get('duration'); $targetSizeInBytes = 10 * 1024 * 1024; $targetBitrate = (int)(($targetSizeInBytes * 8) / $duration); // Convert bytes to bits // Configure compression settings $format = new X264(); $format->setKiloBitrate($targetBitrate / 1000); // Convert to kilobits $format->setAudioCodec('aac'); // Compress and save the video $video->save($format, $outputPath); // Store the compressed file in your preferred storage system Storage::putFileAs('public/videos', $outputPath, $outputFileName); return redirect()->back()->with('success', 'Video compressed and uploaded successfully!'); }
This takes the uploaded 12MB video, compresses it to under 10MB, and saves the smaller version. You may need to tweak bitrate or resolution settings based on the original video’s quality and duration.
Bonus: Laravel Media Library Integration
If you’re already using spatie/laravel-medialibrary for file management, you can simplify compression with the spatie/laravel-medialibrary-videoprocessor extension:
composer require spatie/laravel-medialibrary-videoprocessor
Then, define compression rules when adding media to your model:
$model->addMedia($videoFile) ->usingFileName('compressed-video.mp4') ->withCustomProperties(['bitrate' => 1000]) // 1000 kbps to target ~10MB ->toMediaCollection('videos');
Key Tips:
- Test compression settings with different video types (MP4, MOV, etc.) to balance file size and quality.
- For frontend compression, add error handling for browsers that don’t support the library.
- On the backend, ensure your server has enough memory and processing power—video compression can be resource-intensive.
内容的提问来源于stack exchange,提问作者Lila

