avatar

麦兜的小站

MDO.INK

  • 首页
  • 随笔
  • 知识库
  • 归档
  • 动态
  • 标签
  • 关于
Home 从视频流中提取每一帧图像
文章

从视频流中提取每一帧图像

Posted 2025-06-24 Updated 2025-06- 24
By power 已删除用户
13~17 min read

举个例子,选择一个文件,根据这个视频文件,把那些一帧一帧的画面,给做一个图片显示出来。

可以通过以下步骤构建视频帧提取功能:

  1. 文件选择交互:

    • 在页面中添加文件选择控件
    • 为控件绑定change事件监听器
    • 当用户选择视频文件后触发处理逻辑
  2. 视频帧处理:

    • 使用HTML5 Video元素和Canvas API
    • 通过视频时间轴逐帧捕获画面
    • 将捕获的帧转换为图像数据
const inp = document.querySelector('input[type=file]');

inp.onchange = e => {
  const file = e.target.files[0]
  capptureFrame(file, 1) 
}


function capptureFrame(file, time = 0) {
  return {
    url: '', 
    blob: '' 
  }
}

通过e.target.files[0]拿到选择的文件。

根据这个选择的文件,来生成某一帧的画面,要写这么一个辅助方法,叫capptureFrame。

具体实现:

  • 首先,把这个video元素。

  • 接着,跳到这个video元素指定的时间点。

  • 然后,把它画到canvas里面。

为什么:

因为,能够得到整个canvas里面画的二进制数据,以及,通过这个数据,生成一些UI和地址。

function capptureFrame(file, time = 0) {
  const vdo = document.createElement('video');


  vdo.src = URL.createObjectURL(file);
  console.log(vdo.src);
}

object url(它是一个blob协议开头):

通过这样的地址,访问到本地计算机里边的一些资源,直接粘贴到地址栏blob:http://127.0.0.1:5500/f16b2abc-61f1-43d3-a0c8-c36b7e04c20f,可以直接访问该视频。

一旦网页关闭了,它就会跟着消失了,就失效了。

function capptureFrame(file, time = 0) {
  const vdo = document.createElement("video");


  vdo.currentTime = time; 
  vdo.autoplay = true; 
  vdo.src = URL.createObjectURL(file); 
  console.log(vdo.src); 
}

可能浏览器的自动播放策略会禁止它自动播放,那么自动播放可能会失败。

在浏览器中处理视频自动播放限制的最佳实践如下:给它自动静音,也不需要他的声音。

vdo.muted = true;

画canvas

vdo.oncanplay = () => {
  const cvs = document.createElement('canvas');
  cvs.width = vdo.videoWidth;
  cvs.height = vdo.videoHeight;
  const ctx = cvs.getContext('2d');
  ctx.drawImage(vdo, 0, 0, cvs.width, cvs.height);
  document.body.appendChild(cvs);
}

选择一个文件,看这个视频的第一秒的画面,是不是就画到页面上去了。

把这个canvas里边的东西导出,导出成一个图片地址,以及一个二进制对象。

canvas里边本身就有一个函数叫做toBlob,异步,传一个回调,把这个转换的一个二进制对象:

cvs.toBlob((blob) => {
  const url = URL.createObjectURL(blob);
  console.log(url);
})

循环前10s

inp.onchange = (e) => {
  const file = e.target.files[0];


  for (let i = 0; i < 10; i++) {
    captureFrame(file, i).then((res) => {
      console.log(res);
      const img = document.createElement("img");
      img.src = res.url;
      document.body.appendChild(img);
    });
  }
};

全部代码

// 文件选择 和 事件处理

const inp = document.querySelector('input[type=file]');

inp.onchange = e => {
  const file = e.target.files[0];

  captureFrame(file, 1).then(res => {
    console.log(res);
  });


  for (let i = 0; i < 10; i++) {
    captureFrame(file, i).then(res => {
      const img = document.createElement("img");
      img.src = res.url;
      document.body.appendChild(img);
    });
  }
};

// 帧提取函数

function captureFrame(file, time = 0) {
  return new Promise((resolve, reject) => {
    const vdo = document.createElement("video");
    vdo.currentTime = time; 
    vdo.autoplay = true;    
    vdo.muted = true;       
    vdo.src = URL.createObjectURL(file); 

    vdo.oncanplay = () => {
      const cvs = document.createElement("canvas");
      cvs.width = vdo.videoWidth;   
      cvs.height = vdo.videoHeight;
      const ctx = cvs.getContext("2d");
      ctx.drawImage(vdo, 0, 0, cvs.width, cvs.height); 


      cvs.toBlob((blob) => {
        const url = URL.createObjectURL(blob);
        resolve({
          url,  
          blob  
        });
      });
    };
  });
}

效果

知识库
License:  CC BY 4.0
Share

Further Reading

Jul 31, 2025

如何实现接口幂等性

通俗的说,用户在系统中有操作,不管重复多少次,都应该产生一样的效果或返回一样的结果的。 幂等性的概念 幂等(Idempotent)是一个数学与计算机学的概念,常见于抽象代数中。 f(n)=1^n//无...

Jul 19, 2025

10个npm工具包

有了npm之后,前端人员真的是过上好日子了。我们可以直接把别人写好的工具包拿来用,非常的方便。 1.day.js-轻量日期处理 npminstalldayjs importdayjsfrom'd...

Jul 17, 2025

How to set up PHP7.4 on MacOS.

Thisisallverywellandgood.Apartfromonesmallinsignificantthing… TheversionofPHPinuseiscurrently7.4. Th...

OLDER

轻量级 Nacos 性能炸裂!r-nacos

NEWER

Laravel 5.4 Storage link

Recently Updated

  • 如何实现接口幂等性
  • 10个npm工具包
  • How to set up PHP7.4 on MacOS.
  • Automa:一键自动化,网页数据采集与工作流程优化专家Automa:解锁自动化
  • Mac 下用 brew 搭建 LNMP

Trending Tags

thinkphp clippings

Contents

©2025 麦兜的小站. Some rights reserved.

Using the Halo theme Chirpy