Reputation: 31
I have the following code with a setInterval() method. However there is one function in between i.e audio.play(). Whenever setInterval is called the whole function is called again and so the audio plays again and again. Is there any way of run the setInterval() method but have an exception for the audio.play part? Here is the code
setInterval(async () => {
//api stuff
const detections = await faceapi
.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
const resizedDetections = faceapi.resizeResults(detections, displaySize);
const happy =resizedDetections[0].expressions.happy;
//The Issue starts from here
if(happy>0.9)
{
audio.src="audios/happy_audio.wav";
audio.play();
}
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
},1000)
})
Upvotes: 1
Views: 139
Reputation: 2000
I got it. So you want to stop the interval as soon as the happy index is > 0.9
let intervalID = setInterval(async () => {
//api stuff
const detections = await faceapi
.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
const resizedDetections = faceapi.resizeResults(detections, displaySize);
const happy =resizedDetections[0].expressions.happy;
//The Issue starts from here
if(!audio.paused && happy>0.9)
{
audio.src="audios/happy_audio.wav";
audio.play();
clearInterval(intervalID); // to stop next interval
return; // to stop current interval
}
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
},1000)
})
Upvotes: 0
Reputation: 13409
As it was already said in comments, better is to move outside setInterval
the code you want to run once.
But if you really want to keep it inside, then you can use a boolean variable which will allow to run only once.
Here is how:
let isFirstRun = true;
setInterval(async () => {
//api stuff
const detections = await faceapi
.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
const resizedDetections = faceapi.resizeResults(detections, displaySize);
const happy =resizedDetections[0].expressions.happy;
//The Issue starts from here
if(isFirstRun) {
isFirstRun = false;
if(happy>0.9)
{
audio.src="audios/happy_audio.wav";
audio.play();
}
}
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
},1000)
})
Upvotes: 0
Reputation: 8670
If you want it not to play while it is playing you could check and see if the audio is currently playing by checking the paused
property in the conditional:
setInterval(async () => {
//api stuff
const detections = await faceapi
.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
const resizedDetections = faceapi.resizeResults(detections, displaySize);
const happy =resizedDetections[0].expressions.happy;
//The Issue starts from here
if(!audio.paused && happy>0.9)
{
audio.src="audios/happy_audio.wav";
audio.play();
}
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
},1000)
})
if you just want it to fire once use a flag:
let flag = false;
setInterval(async () => {
//api stuff
const detections = await faceapi
.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
const resizedDetections = faceapi.resizeResults(detections, displaySize);
const happy =resizedDetections[0].expressions.happy;
//The Issue starts from here
if(flag && happy>0.9)
{
audio.src="audios/happy_audio.wav";
audio.play();
flag = true;
}
faceapi.draw.drawDetections(canvas, resizedDetections);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
},1000)
})
Note I'm not a big fan of variable flags that are globally scoped. In the above case I would recommend a closure, or binding your asynchronous function to an Object that houses the flag, but as an example this should be sufficient :)
Upvotes: 1