I'm trying to do object detection, using tensorflow-js, on the webcam stream
Below is my code:
let model;
var modelPromise = new Promise(function(resolve, reject) {
// Load the model.
model = cocoSsd.load();
$(".progress-bar").hide();
if (model) {
resolve("model loaded!");
}
else {
reject(Error("problem loading model"));
}
});
const video = document.querySelector("#vid");
var camPromise = new Promise(function(resolve, reject) {
if('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices){
navigator.mediaDevices.getUserMedia({ audio: false, video: true })
.then(function (stream) {
video.srcObject = stream;
})
.catch(function (err){
alert(JSON.stringify(error));
});
}
});
// create function to detect objects in the image
const detection = (vid, mod) => {
console.log("hi");
mod.detect(vid).then(predictions => {
//drawBBox(predictions); --> write function for this!
console.log(predictions);
});
requestAnimationFrame(() => detection(vid, mod));
};
Promise.all([modelPromise, camPromise])
.then(values => detection(video, model))
.catch(error => console.error(error));
The webcam stream is generated and displayed, but no predictions are being generated by cocoSsd; am I doing something wrong here?
Related
I used to use this function to check the mic:
function checkMicrophone() {
console.log('checkMicrophone executed')
return new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia({
audio: true
}).then(stream => {
console.log('res')
resolve();
}).catch(err => {
console.log('err')
resolve();
});
});
}
checkMicrophone()
And it was working till just today!
What happened it doesn't return the promise nor the err ?
I have a function that fetches the user's location. It was working this way:
const fetchGeoLocation: SearchService["fetchGeoLocation"] = async () => {
const geo = navigator.geolocation;
if (!geo) throw new Error("error.geolocation-unavailable");
const handleError = (err: any) => {
if (err.code === 1) throw new Error("error.geolocation-permission_denied");
if (err.code === 2) throw new Error("error.geolocation-unavailable");
if (err.code === 3) throw new Error("error.geolocation-timeout");
};
const handleSuccess = (position) => {
return { location: [position.coords.longitude, position.coords.latitude] };
};
geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
};
const onUpdateLocation = async () => {
onLoad();
fetchGeoLocation()
.then((res) => onSave(res.data))
.catch(({ message }) => onError(message));
};
Because it was not a promise, the onSave() function triggered before fetchGeolocation ended. So I have to promisify it. Writing this would work:
function fetchGeolocation () {
return new Promise((resolve, reject) =>{
navigator.geolocation.getCurrentPosition(resolve, reject);
});
};
fetchGeolocation()
.then(res => onSave(res)
.catch(err => onError(err.message);
But I would need to handle all the error codes in the catch callback. I want to handle everything inside the fetchGeolocation function. How to do it?
Thanks!
If I followed your idea properly, then the next snippet might help you out:
const fetchGeoLocation: SearchService["fetchGeoLocation"] = async () => {
return new Promise((resolve, reject) => {
const { geolocation } = navigator;
if (!geolocation) reject("error.geolocation-unavailable");
const handleError = ({ code }) => {
if (code === 1) reject("error.geolocation-permission_denied");
if (code === 2) reject("error.geolocation-unavailable");
if (code === 3) reject("error.geolocation-timeout");
};
const handleSuccess = (position) => {
resolve({ location: [position.coords.longitude, position.coords.latitude] });
};
geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
});
};
Notice instead of throw'ing, it's reject'ing the promise with the error string.
I use WebRTC to connected 2 Chrome Browsers. I create offer on the first and send it via signalR to second client like this :
function initiate_call() {
callerPeerConn = new RTCPeerConnection(peerConnCfg);
callerPeerConn.ontrack = function (event) {
console.log('caller recived new stream');
remoteVideo.srcObject = event.streams[0];
console.log(event);
}
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(function (stream) {
localVideo.srcObject = stream;
for (const track of stream.getTracks()) {
callerPeerConn.addTrack(track, stream);
}
return callerPeerConn.createOffer();
})
.then(
function (offer) {
var off = new RTCSessionDescription(offer);
callerPeerConn.setLocalDescription(
new RTCSessionDescription(off),
function () {
// invite to video chat
console.log('send offer');
},
function (err) {
console.log(err.message);
}
)
});
}
When my second browser getting offer he use setLocalDescription and try to create answer than send it to caller like that :
function accept_send_answer(){
calleePeerConn = new RTCPeerConnection(peerConnCfg);
calleePeerConn.ontrack = function (event) {
console.log('callee accept offer and got streams');
remoteVideo.srcObject = event.streams[0];
}
calleePeerConn.setRemoteDescription(offer)
.then(function () {
return navigator.mediaDevices.getUserMedia({ audio: true, video: true });
})
.then(function (stream) {
localVideo.srcObject = stream;
for (const track of stream.getTracks()) {
calleePeerConn.addTrack(track, stream);
}
return calleePeerConn.createAnswer();
})
.then(function (answer) {
// sending answer
console.log("sending ansfer");
var remote_streams = calleePeerConn.getRemoteStreams();
var local_streams = calleePeerConn.getLocalStreams();
console.log("callee remote streams");
console.log(remote_streams);
console.log("callee local streams");
console.log(local_streams);
})
.catch(function (err) {
console.log(err.message);
});
}
UPD
After I changed my code, following the advice of a respected #jib, my local and remote streams on both sides was successfully added to RTCPeerConnection object. I successfully obtain following messanges in console : caller recived new stream and callee accept offer and got streams as well. Last problem is - why this code not working :
calleePeerConn.ontrack = function (event) {
console.log('callee accept offer and got streams');
remoteVideo.srcObject = event.streams[0];
}
video not played.
First, addStream and onaddstream are deprecated, and won't work in other browsers. Use addTrack and ontrack instead.
Second, timing.
You're calling peerConn.createOffer() before peerConn.addStream(stream) so tracks are not picked up.
Same with peerConn.createAnswer() before peerConn.addStream(stream).
Lastly, mixing callbacks and promises confuses the order of things here. Try:
const peerConn = new RTCPeerConnection(peerConnCfg);
peerConn.ontrack = function (event) {
alert('new stream added! ' + event.streams[0]);
}
function initiate_call() {
navigator.mediaDevices.getUserMedia({audio: true, video: true})
.then(function (stream) {
localVideo.srcObject = stream;
for (const track of stream.getTracks()) {
peerConn.addTrack(track, stream);
}
return peerConn.createOffer();
})
.then(function (offer) {
// signaling and invite
return peerConn.setLocalDescription(off);
})
.catch(function (err) {
console.log(err.message);
});
}
function accept_send_answer(offer) {
peerConn.setRemoteDescription(offer)
.then(function () {
return navigator.mediaDevices.getUserMedia({audio: true, video: true});
})
.then(function (stream) {
video.srcObject = stream;
for (const track of stream.getTracks()) {
peerConn.addTrack(track, stream);
}
return peerConn.createAnswer();
})
.then(function (answer) {
//signaling to caller and send answer
return peerConn.setLocalDescription(answer);
})
.catch(function (err) {
console.log(err.message);
});
}
Note that your code (and my reply) still lack critical pieces: ice candidate exchange, and you're not showing your setRemoteDescription(answer) code to complete the negotiation loop.
Note that most examples tend to use the same JS on both sides, like e.g. this working fiddle using iframe postMessage for signaling.
I have a function that downloads a file using got and uses fs.createWritableStream to write file on disk. The code is working smooth but the unit test are being a pain:
download(twilioPath, destFile) {
return new Promise(function(resolve, reject) {
const uri = `${TWILIO_BASE_URL}${twilioPath}`.replace('json', 'mp3')
let file = fs.createWriteStream(`/tmp/${destFile}`)
console.log(got)
let str = got.stream(uri)
console.log(uri)
str.on('error', function(err) {
console.log('Error dl', err)
reject(err)
})
str.pipe(file)
file.on('finish', function() {
console.log('banana')
let cb = function() {
console.log('Download completed')
resolve(file)
}
file.close(cb)
})
})
My resolve or reject is not being called and I don't know how to fix that:
const Recording = require('./Recording')
const Readable = require('stream')
var mockedStream = new Readable();
var mockedWrite = new Readable.Writable()
jest.mock('fs', () => ({
createWriteStream: jest.fn((file_name) => {
return mockedWrite;
})
}));
jest.mock('got', () => {
return {
stream: () => {
return mockedStream
}
}
})
describe('Recording', () => {
test('should download a file from twilio', async () => {
...
mockedStream.emit('error')
mockedWrite.emit('finish')
console.log(result)
....
})
})
I've tried to force emit events but no lucky.
I am following this tutorial to make webrtc work. I would like to return the streams I get in resolve() to the component I call this getDrone() from. I created a returnStreamArray() function as a child promise which I tried to add as a then() to the stream to add it to the array, however I am stuck. I would appreciate any directions.
export default function getDrone() {
return new Promise((resolve, reject) => {
const drone = new Scaledrone('fBAkzbVAOmA2wbU0');
const roomName = 'observable-room';
const configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
let room;
let pc;
const streamArr = [];
...
drone.on('open', error => {
if (error) {
console.error(error);
}
room = drone.subscribe(roomName);
room.on('open', error => {
if (error) {
onError(error);
}
});
..
..
pc.ontrack = event => {
const stream = event.streams[0];
streamArr.push(stream);
};
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(stream => {
streamArr.push(stream);
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}, onError)
.then(returnStreamArray => {
console.log(stream);
});
..
..
});
}
function returnStreamArray() {
return Promise.resolve({
streamArray: streamArr
});
}