[英]How to check if my all promises are fulfilled
目前我正在寫一段代碼。 我想在視頻開始播放時啟動網絡攝像頭,並在視頻暫停時停止攝像頭,但在加載攝像頭之前我想檢查我的所有模型是否已加載。 我想加載一次模型,直到頁面刷新。 這完全是一個單獨的案例,如果用戶頁面引用它將再次加載。 現在,如果我點擊視頻中的播放按鈕,它就會啟動我的相機。 我如何配置它,如果用戶暫停按鈕它只會禁用相機並按下播放按鈕它只會加載相機(不會再次加載我的模型)。
<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>
................................... 索引.php
現在我的 script.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.all 塊中加載。
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
處理程序中執行此操作,您可以將事件偵聽器添加到視頻元素以在同一位置開始和停止視頻 - 然后用戶可以隨意開始和停止視頻。 但是,您可能想要擺脫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
方法將返回帶有status
和value
字段的承諾數據。 status
給你 fullfilled 或 rejected 和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 提示的答案
在成功加載模型后和每次啟用相機之前將變量設置為真將檢查該變量是真還是假。
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");
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.