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);
}
}
});
}
exportdefault extractFramesFromVideo;
在调整您的代码以等待seeked事件并修复一些零碎之后,它似乎工作正常:
asyncfunctionextractFramesFromVideo(videoUrl, fps=25) {
returnnew 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', asyncfunction() {
if(seekResolve) seekResolve();
});
video.addEventListener('loadeddata', asyncfunction() {
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;
awaitnew 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;
});
}
function SicBo(){
return new Promise((resolve,reject) =>{
console.log("开始摇 ")
setTimeout(()=>{
let n = parseInt(Math.random()*6 + 1,10) //1~6
resolve(n)
},1000)
})
}
function SicBo(){
return new Promise((resolve,reject) =>{
console.log("开始摇 ")
setTimeout(()=>{
let n = parseInt(Math.random()*6 + 1,10) //1~6
resolve(n)
},1000)
})
}
async function Roll(){
let n = await SicBo() //一定要写括号,不写括号就不会执行 new Promise
console.log(' 的点数是'+n)
}
Roll() //记得要调用函数
在这个代码中还需要注意的是,resolve(n)得到的结果会返回给let n = await SicBo()里面的n。在let n = await SicBo()这行代码中,等号左边和等号右边是分离的。右边是1秒之前执行的,左边赋值时1s之后执行的,等号两边不是在同一时间执行的,左边要等右边执行完再执行。所以Roll函数也是要等1s才执行的,所以Roll函数是异步的,所以function前面必须加一个async,表示它的特殊性,让引擎对它进行特殊处理,如果不标记,则报错。
try catch 捕获错误
现在加入Promise中会失败的情况 把摇 改成猜大小
function SicBo(bet){
return new Promise((resolve,reject) =>{
console.log("开始摇 ")
setTimeout(()=>{
let n = parseInt(Math.random()*6 + 1,10) //1~6
if(n>3){
if(bet === "big"){
resolve(n) //摇出来是大,你也猜了大
}else{
reject(n) //摇出来是大,你猜了小
}
}else{
if(bet === "small"){
resolve(n)
}else{
reject(n)
}
}
},1000)
})
}
async function Roll(){
let n = await SicBo() //一定要写括号,不写括号就不会执行 new Promise
console.log(' 的点数是'+n)
}
Roll()
运行代码的时候我们会发现只会输出“开始摇 ”,打开控制台可以发现控制台报错。
这个错误的结果就是 的点数,显示Uncaught,所以我们要进行一段try...catch代码。
async function Roll(){
try{
let n = await SicBo('big') //报错的话左边那一半就不会执行,每次都买大
console.log(' 的点数是'+n)
console.log('你猜中了')
}
catch(error){
console.log(' 的点数是'+error)
console.log('你输光了')
}
}