如何检查我的所有承诺是否实现



目前我正在写一段代码。当视频开始播放时,我想启动网络摄像头,当视频暂停时停止摄像头,但在加载摄像头之前,我想检查是否加载了所有模型。我想加载模型一次,直到页面刷新。这完全是一个单独的情况,如果用户页面刷新,它将再次加载. 现在如果我点击视频中的播放按钮它就会启动我的摄像头。我如何配置它的方式,如果用户暂停按钮,它只禁用相机和按播放按钮,它只加载相机(不加载我的模型再次)。

<html>
<head>
<title>Video detecting and emotion storing in database</title>
<script type="text/css" defer src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"></script>
<script type="text/css" src="style.css"></script>
<script defer type="text/javascript" src="script/face-api.min.js"></script>
<script defer type="text/javascript" src="script/script.js"></script>
<style>
#livecam{
height: 400px;
width: 600px;
float: right;
}
</style>
</head>
<body>
<div class="container">
<video id="myvideo" src="laravel.mp4" controls height="400" width="600" >
</video>
<video id="livecam" autoplay muted height="400" width="600" ></video>
</div>
</body>
</html>

.....................................index . php

现在我的脚本。js

var video = document.getElementById('myvideo');
const liveview = document.getElementById('livecam');
const height = 400;
const width = 600;

Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
faceapi.nets.faceExpressionNet.loadFromUri('/models')
])
video.onplaying = function(){
enablewebcam();
alert("Video is playing");
};
video.onpause = function(){
disablecam();
}
function enablewebcam(){
navigator.mediaDevices.getUserMedia({video:{width:600, height:400},
audio:false}).then((stream) => {
liveview.srcObject = stream;
})
};

function disablecam(){
liveview.srcObject = null;
}

要检查您的模型是否已经在启用网络摄像头之前加载,您可以使用在模型加载后设置为true的标志变量。然后,在您的enablewebcam函数中,您可以在启用摄像头之前检查该标志的值:

let modelsLoaded = false;
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
faceapi.nets.faceExpressionNet.loadFromUri('/models')
]).then(() => {
modelsLoaded = true;
});
function enablewebcam() {
if (modelsLoaded) {
navigator.mediaDevices.getUserMedia({ video: { width: 600, height: 400 }, audio: false }).then((stream) => {
liveview.srcObject = stream;
});
}
}

也可以使用faceapi.nets.tinyFaceDetector.isLoaded()函数检查tinyFaceDetector模型是否已加载。如果有,你可以假设所有的模型都被加载了,因为它们都是在同一个Promise中加载的。所有块。

function enablewebcam() {
if (faceapi.nets.tinyFaceDetector.isLoaded()) {
navigator.mediaDevices.getUserMedia({ video: { width: 600, height: 400 }, audio: false }).then((stream) => {
liveview.srcObject = stream;
});
}
}

无论哪种方式,您都可以使用video.onpause事件在视频暂停时停止网络摄像头,正如您已经在代码中所做的那样。

为了确保当用户点击播放时模型已经加载,延迟添加controls属性,直到获取模型之后。

如果您在Promise.all调用的then处理程序中这样做,您可以向video元素添加事件侦听器,以便在同一位置开始和停止视频-然后用户可以随意开始和停止视频。然而,您可能想要摆脱alert消息。

这个代码片段已经被删减用于测试,但不幸的是不能在Stack overflow上工作:

"use strict";
var video = document.getElementById('myvideo');
const liveview = document.getElementById('livecam');
const height = 400;
const width = 600;
Promise.all([
// production
// faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
// faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
// faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
// faceapi.nets.faceExpressionNet.loadFromUri('/models')
// testing
Promise.resolve(true),
Promise.resolve(true),
Promise.resolve(true),
Promise.resolve(true)
])
.then( ()=> {
video.onplaying = function(){
enablewebcam();
alert("Video is playing");
};
video.onpause = function(){
disablecam();
}
// show video controls:
video.setAttribute("controls", "");
function enablewebcam(){
navigator.mediaDevices.getUserMedia({video:{width:600, height:400},
audio:false})
.then((stream) => {
liveview.srcObject = stream;
})
.catch( err => { 
console.log("no cam, ", err.message)
});
};
function disablecam(){
liveview.srcObject = null;
}
})
.catch(err => {
console.log(err);
alert("Something went wrong");
});
video { border: thin solid blue}
<div class="container">
<video id="myvideo"
src="https://i.imgur.com/LTc02xw_lq.mp4"
height="400" width="600">
</video>
<video id="livecam" autoplay muted height="400" width="600" ></video>
</div>

您可以创建一个承诺数组,因为Promise类有一个all方法,该方法接收一个承诺数组,并在它们全部完成后返回结果。如果你认为其中一个承诺可能失败,你应该使用allSettled,因为如果其中一个承诺失败,all方法会返回Pending。

allSettled方法将返回带有statusvalue字段的promises数据。status给你完成或拒绝,value给你承诺数据。

这样的一个例子是:

// Your array of promises
promises = [
...
]
// 'all' method
Promises.all(promises)
.then(data => console.log(data))
// 'allSettled' method
Promises.allSettled(promises)
.then(data => console.log(data))

所以我找到了答案提示由Ritik

在成功加载模型后将变量设置为true,并且每次在启用相机之前都会检查该变量是否为true或false。

Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('/mmodels'),
faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
faceapi.nets.faceExpressionNet.loadFromUri('/models')
]).then(function(){
modeloadedstatus = true;
})

每次启用相机前检查modeloadedstatus

video.onplaying = function(){
if(modeloadedstatus) {
enablewebcam();
console.log(modeloadedstatus)
alert("Video is playing");
} else{
alert("Error in model loading");
}
};

最新更新