You need to enable JavaScript to run this app. Laravel 中如何不使用 FFmpeg 为上传视频生成缩略图?
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 中如何不使用 FFmpeg 为上传视频生成缩略图?

不依赖FFmpeg的Laravel视频缩略图实现方案

方案一:前端生成后随视频上传(推荐,无额外后端依赖)

这是最常用的实现方式,完全不需要在服务器端安装任何视频处理工具,截帧操作在用户浏览器完成,还能减轻服务器压力。
核心实现逻辑:

  • 页面监听视频上传文件选择事件,用原生HTML5 video 元素加载本地视频文件
  • 等视频元数据加载完成后,跳转到指定的截帧时间点(比如0.5秒或视频时长的1/3处,避开开头黑帧)
  • 用Canvas将当前视频帧绘制为图片,导出为JPG/PNG格式的Blob文件
  • 将视频文件和缩略图文件一起通过FormData提交到Laravel后端

核心代码示例

前端JS逻辑

const fileInput = document.querySelector('input[name="video"]');
fileInput.addEventListener('change', async (e) => {
  const videoFile = e.target.files[0];
  if (!videoFile) return;

  // 生成本地视频URL
  const videoUrl = URL.createObjectURL(videoFile);
  const video = document.createElement('video');
  video.src = videoUrl;

  // 等待视频元数据加载完成
  await new Promise((resolve) => video.addEventListener('loadedmetadata', resolve));
  // 设置截帧位置为1/3时长处,避免黑帧
  video.currentTime = video.duration / 3;

  // 等待视频跳转完成
  await new Promise((resolve) => video.addEventListener('seeked', resolve));

  // 初始化Canvas生成缩略图
  const thumbWidth = 320;
  const thumbHeight = video.videoHeight * (thumbWidth / video.videoWidth);
  const canvas = document.createElement('canvas');
  canvas.width = thumbWidth;
  canvas.height = thumbHeight;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, 0, 0, thumbWidth, thumbHeight);

  // 导出为图片Blob
  const thumbBlob = await new Promise((resolve) => {
    canvas.toBlob(resolve, 'image/jpeg', 0.8);
  });

  // 组装FormData提交到后端
  const formData = new FormData();
  formData.append('video', videoFile);
  formData.append('thumbnail', thumbBlob, 'video_thumb.jpg');
  // 后续走上传请求逻辑即可
  URL.revokeObjectURL(videoUrl);
});

Laravel后端接收逻辑

// 控制器上传方法内
$validated = $request->validate([
    'video' => 'required|file|mimes:mp4,mov,webm|max:102400', // 视频最大100MB
    'thumbnail' => 'required|file|mimes:jpg,png|max:2048' // 缩略图最大2MB
]);

// 存储文件到公共磁盘
$videoPath = $request->file('video')->store('videos', 'public');
$thumbPath = $request->file('thumbnail')->store('thumbnails', 'public');

// 数据入库
\App\Models\Video::create([
    'video_path' => $videoPath,
    'thumb_path' => $thumbPath,
    'user_id' => auth()->id()
]);

方案二:后端生成(强制服务器处理场景)

如果业务要求必须在服务器端生成缩略图,不能依赖前端处理,可以采用第三方视频处理API的方案:

  • 视频上传到Laravel服务器后,将视频文件流传递给第三方视频处理接口
  • 接口完成截帧后返回缩略图的二进制内容或存储地址
  • 后端接收返回的缩略图后,存储到本地或对象存储即可
    该方案不需要服务器安装FFmpeg依赖,缺点是依赖第三方服务可用性,会产生额外的接口调用成本。

注意事项

  • 前端截帧方案优先要求用户上传H.264编码的MP4格式视频,避免不同浏览器的格式兼容问题
  • 可以灵活调整截帧时间点,优先选择内容辨识度高的位置,避免黑帧或空白帧
  • 如果存在用户禁用JS的场景,可以提供手动上传自定义缩略图的备选入口

内容的提问来源于stack exchange,提问作者Bhargav Chudasama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 19:06:04