js截取视频第一帧_在JS中从视频中提取帧

I'm trying to build a function that extracts frames from a video in JavaScript. Here the code I came up with. The function receives a source and a callback. From there, I create a video with the source and I want to draw frames of the video in the canvas with a set interval.

Unfortunately, the frames returned are all transparent images.

I tried a few different things, but I can't make it work. Can someone help?

Thanks.

const extractFramesFromVideo = function(src, callback) {

var video = document.createElement('video');

video.src = src;

video.addEventListener('loadeddata', function() {

var canvas = document.createElement('canvas');

var context = canvas.getContext('2d');

canvas.setAttribute('width', video.videoWidth);

canvas.setAttribute('height', video.videoHeight);

var frames = [];

var fps = 1; // Frames per seconds to

var interval = 1 / fps; // Frame interval

var maxDuration = 10; // 10 seconds max duration

var currentTime = 0; // Start at 0

while (currentTime < maxDuration) {

video.currentTime = currentTime;

context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);

var base64ImageData = canvas.toDataURL();

frames.push(base64ImageData);

currentTime += interval;

if (currentTime >= maxDuration) {

console.log(frames);

callback(frames);

}

}

});

}

export default extractFramesFromVideo;

解决方案

After tweaking your code to wait for the seeked event, and fixing a few bits and pieces, it seems to work fine:

async function extractFramesFromVideo(videoUrl, fps=25) {

return new Promise(async (resolve) => {

// fully download it first (no buffering):

let videoBlob = await fetch(videoUrl).then(r => r.blob());

let videoObjectUrl = URL.createObjectURL(videoBlob);

let video = document.createElement("video");

let seekResolve;

video.addEventListener('seeked', async function() {

if(seekResolve) seekResolve();

});

video.addEventListener('loadeddata', async function() {

let canvas = document.createElement('canvas');

let context = canvas.getContext('2d');

let [w, h] = [video.videoWidth, video.videoHeight]

canvas.width = w;

canvas.height = h;

let frames = [];

let interval = 1 / fps;

let currentTime = 0;

let duration = video.duration;

while(currentTime < duration) {

video.currentTime = currentTime;

await new Promise(r => seekResolve=r);

context.drawImage(video, 0, 0, w, h);

let base64ImageData = canvas.toDataURL();

frames.push(base64ImageData);

currentTime += interval;

}

resolve(frames);

});

// set video src *after* listening to events in case it loads so fast

// that the events occur before we were listening.

video.src = videoObjectUrl;

});

}

Usage:

let frames = await extractFramesFromVideo("https://example.com/video.webm");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值