const Hyperpeer = require('hyperpeer')
const hostname = location.hostname
const serverAddress = `wss://${hostname}:8000`
// The <video> element to use for showing remote video, for this example the remote video is just mirroring the local video stream
const video = document.getElementById('video')
// Get local media video
navigator.mediaDevices.getUserMedia({ video: true })
.then((stream) => {
// Instantiate Hyperpeer with an id, a type, the input media stream and the output <video> element
const myPeerId = 'web_client' + Date.now()
const deepPeer = new Hyperpeer(serverAddress, {
id: myPeerId,
type: 'web_client',
stream: stream,
videoElement: video
})
// Once get the 'online' event get the available peers
deepPeer.on('online', () => {
deepPeer.getPeers()
.then((peers) => {
// Check which peers are Stream Managers and which are Stream Capture (in this version there is only one Stream Manager and at most one Stream Capture)
peers.forEach((peer) => {
if (peer.busy) return
if (peer.type === 'stream_manager') {
availableServers.push(peer)
} else if (peer.type === 'stream_capture') {
availableCameras.push(peer)
}
})
// let's assume you want to inmediately connect to the first Stream Manager available
if (availableServers.length >= 1) {
return deepPeer.connectTo(availableServers[0])
}
})
.catch((error) => { alert(error) })
})
// Once connected indicate to Stream Manager the video stream to process, in this case it's set to 'myPeerId' on order to indicate the local webcam but you can give the id of one of the Stream Capture peers
deepPeer.on('connect', () => {
console.log('Peer-to-peer connection established!')
deepVideoSource = sourcePeerId
deepPeer.send({ type: 'source', peerId: myPeerId })
})
// On data handle the Stream Manager message
deepPeer.on('data', (data) => {
// All message are converted to javascript objects and have a 'type' property. Results have type 'data'
if (data.type == 'data') {
// The information regading each detected face is contained inside an array also called data. Let's create a dictionary where the face id is the key and the value are its attributes
let faces = {}
data.data.forEach((face) => {
faces[face.id] = {
// The face bounding box is in the 'rect' attribute
boundingBox: {
x_topleft: face.rect.x_topleft,
y_topleft: face.rect.y_topleft,
x_bottomright: face.rect.x_bottomright,
y_bottomright: face.rect.y_bottomright
},
// If the face recognition algorithm is running the 'face_recognition' attribute contains either the name of the person or the string 'Unknown'
name: face.face_recognition,
// If the gender algorithm is running the 'gender' attribute is either 'Male' or 'Female'
gender: face.gender,
// If the pitch algorithm is running the 'pitch' attribute is a number representing the horizontal orientation of the face
pitch: face.pitch,
// If the yaw algorithm is running the 'yaw' attribute is a number representing the vertical orientation of the face
yaw: face.yaw,
// If the age algorithm is running the 'age' attribute is a string representing the apparent age of the face
ageRange: face.age,
// If the emotion algorithm is running the 'emotion' attribute is an array of the possible emotions with its probabilities
emotions: face.emotion ? face.emotion.map(e => {
return {
label: e[0],
probability: e[1]
}
}) : [],
// If the glasses algorithm is running the 'glasses' attribute is 'glasses', 'sunglasses' or 'no glasses'
glasses: face.glasses
}
})
// In the current verion Stream Manager expects a message of type 'acknowledge' for each data message sent so it can calculate some stats
let acknowledge = {
type: 'acknowledge',
// It only needs the receive back the 'rec_time' attribute
rec_time: data.rec_time
}
deepPeer.send(acknowledge)
} else if (data.type == 'warning') {
console.error('Deep warning' + JSON.stringify(data))
} else if (data.type == 'error') {
alert('Deep error' + JSON.stringify(data))
}
else {
console.log('Deep message' + JSON.stringify(data))
}
})
deepPeer.on('error', (error) => {
alert('Hyperpeer Error: ' + error)
})
})
.catch((error) => {
alert('mediaDevices error: ' + error)
})