【视频处理】js获取视频某一帧(某一秒)作为封面图

1511次浏览

前言

我之前分享过一篇文章 【音视频处理】纯js实现上传视频,截取关键帧作为封面,上传后端保存 ,这个文章可以获取视频第一帧作为封面图,但是视频第一帧有时候是黑的,怎么办呢?今天介绍一个获取视频任何一帧的方法。

方法

其实原理都是一样的,都是用canvas绘制

代码如下:

const handleGetVideoThumb = function (url, options = {}) {
  if (typeof url != 'string') {
    return;
  }

  // 默认参数
  const defaults = {
    seekTime :1,
    onLoading: () => {},
    onLoaded: () => {},
    onFinish: (thumbData) => {},
  };

  const params = Object.assign({}, defaults, options);

  // 基于视频元素绘制缩略图,而非解码视频
  const video = document.createElement('video');
  // 静音
  video.muted = true;

  // 绘制缩略图的canvas画布元素
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d', {
    willReadFrequently: true,
  });

  // 绘制缩略图的标志量
  let isTimeUpdated = false;
  // 几个视频事件
  // 1. 获取视频尺寸
  video.addEventListener('loadedmetadata', () => {
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;

    // 开始执行绘制
    draw();
  });
  // 2. 触发绘制监控
  video.addEventListener('timeupdate', () => {
    isTimeUpdated = true;
  });

  // 获取视频数据
  params.onLoading();
  // 请求视频地址,如果是本地文件,直接执行
  if (/^blob:|base64,/i.test(url)) {
    video.src = url;
  } else {
    fetch(url)
      .then((res) => res.blob())
      .then((blob) => {
        params.onLoaded();
        // 赋予视频
        video.src = URL.createObjectURL(blob);
      });
  }

  // 绘制方法
  const draw = () => {
    const thumbData = [];
    const duration = video.duration;
    video.currentTime = params.seekTime;

    const onSeeked = () => {
      context.clearRect(0, 0, canvas.width, canvas.height);
      context.drawImage(video, 0, 0, canvas.width, canvas.height);
      canvas.toBlob((blob) => {
        thumbData.push(URL.createObjectURL(blob));
        params.onFinish(thumbData);
      }, 'image/jpeg');
    };

    video.addEventListener('seeked', onSeeked);
  };
};

使用

handleGetVideoThumb ('xxx.haorooms.com/video.mp4',{
seekTime :5,// 截取第5s视频
onFinish:(data)=>{

   // 图片数据,可以上传

  }
})

这样就完成了,简单记录一下。

Tags: jsvideo

相关文章: