Construire une caméra de sécurité activé par le mouvement, avec WebRTC, toile et orientation de l’appareil

Original: http://www.webdirections.org/blog/build-a-motion-activated-security-camera-with-webrtc-canvas-and-device-orientation/


   Par: John
Tweet: @johnallsopp
7 juin 2013
Commentaires actuellement fermés.

En tant que développeur web, vous avez probablement vu les technologies HTML5 et des API comme deviceOrientation et WebRTC (Web Real Time Communications) émergent, et pensé wow ils l’air cool, mais ils ne sont que pour le disque de jeu de base, la vidéoconférence, et d’autres choses , pas pour tout le développement de ma journée . Je suis fermement convaincu que profiter de ces capacités va ouvrir un potentiel fantastique pour les développeurs, à la fois pour les sites web existants, ainsi que de toutes nouvelles expériences Web. Dans cet article, je veux parler de celui-ci.

Lorsque nous avons emménagé dans le bureau Web de Directions, nous avions un vieux iMac (je veux dire vieux) mis en place comme une caméra de sécurité activé par le mouvement. Un des gars qui ont utilisé de partager le bureau avec nous avions construit une application très simple qui quand il détecte un mouvement (je suppose que par analyse des images), il a envoyé une photo à une adresse e-mail indiquée. Malheureusement, le Mac et l’application sont allés quand le gars a déménagé. Je dis malheureusement, parce que quelques mois, nous avons pu vraiment pu faire avec cette capture d’aider celui qui est venu par une nuit à 3h du matin, défoncé la porte, et a pris plusieurs dispositifs.

Mais alors, il me vint à ce quelque chose que nous pouvons construire dans le navigateur. Tout ce que nous aurions besoin de faire était de

Détecter le mouvement (avec l’API DeviceMotion (même si elle est un peu plus complexe que cela dans la pratique comme nous le verrons dans un instant)
Capturer une image à l’aide WebRTC et la toile HTML5
Envoyer l’image par email (nous couvrons pas aujourd’hui, car il est vraiment plus un problème côté serveur, mais il ya toutes sortes de façons dont vous pouvez le faire) à nous-mêmes.

Donc, nous allons commencer. Nous allons commencer par la détection de mouvement.

Détection de mouvement

Vous pensez probablement, il ya une API HTML pour cela, DeviceMotion. Ce qui est exactement ce que je pensais. Le problème est, tout bien pris en charge dans les navigateurs mobiles et tablettes (ces dispositifs ont presque universellement gyroscopes pour détecter leur orientation dans l’espace 3D, et des accéléromètres pour détecter leur accélération en 3D ainsi), il est pas pris en charge dans un navigateur de bureau. Mais, il ya une API connexe, deviceOrientation qui rend l’angle auquel l’appareil est en 3 dimensions, et qui est pris en charge par Chrome, lorsque l’ordinateur portable est en marche sur les capteurs a à fournir ces données (je sais que le MacBook Pro , mais pas Air soutien deviceOrientation). DeviceMotion et deviceOrientation fonctionnent de manière similaire. Ils sont tous les deux événements envoyés à l’objet de la fenêtre quand quelque chose change sur le périphérique. Nous pouvons fournir des écouteurs d’événements pour ces événements, puis répondre à des données qu’ils fournissent.

Créons des gestionnaires d’événements pour chacun de ces types d’événements

si (window.DeviceMotionEvent) {
window.addEventListener (devicemotion’, motionHandler, false)
}

else if (window.DeviceOrientationEvent) {
window.addEventListener (deviceOrientation’, orientationHandler, false)
}

Pour chaque type d’événement, nous nous assurons que l’objet de la fenêtre prend en charge le type d’événement, et si elle ne nous ajoutons un écouteur d’événement à la fenêtre pour le type d’événement.

Ok, alors maintenant notre fenêtre peut recevoir ces événements, regardons quelles sont les informations que nous recevons de chaque événement, et comment nous pouvons détecter si l’appareil est en mouvement.

Comme mentionné, la façon la plus logique de le faire est par le biais DeviceMotion, mais voici la complication. Un appareil idéal pour l’utiliser comme une caméra de sécurité est un vieux portable. Il est alimenté, de sorte que la batterie ne va pas plat, et sur les tablettes, que Chrome pour Android prend en charge getUserMedia, pour faire fonctionner la caméra vidéo de l’appareil. Mais, nous pouvons utiliser deviceOrientation pour détecter le mouvement que nous avons vu sur certains ordinateurs portables dans Chrome. Faisons-le d’abord, puis rapidement regarder comment nous pouvons faire la même chose pour les dispositifs qui supportent les activités de DeviceMotion.

Voici notre gestionnaire d’événements deviceOrientation.

fonction orientationHandler (orientationData) {
var today = new Date ();

if ((today.getTime () lastMotionEvent)> motionInterval) {
checkMotionUsingOrientation (orientationData)
lastMotionEvent today.getTime = ()
}
}

et de même, notre gestionnaire d’événements de DeviceMotion

motionHandler: function (motionData) {
var today = new Date ();

if ((today.getTime () lastMotionEvent)> motionInterval) {
checkMotionUsingMotion (motionData)
lastMotionEvent today.getTime = ()
}
}

Parce que les événements DeviceMotion et deviceOrientation feu de nombreuses fois une seconde, si nous devions répondre à chacun de ces événements unique, nous aurions un ordinateur portable très chaud, et sur les appareils alimentés par batterie, autonomie de la batterie beaucoup plus courte. Donc, ici, nous vérifions l’heure actuelle, et seulement si le temps écoulé depuis notre dernière répondu à cet événement est supérieure à un certain intervalle, nous répondons à l’événement. Vérification de mouvement quelques fois par seconde devrait être plus que suffisant.

Les écouteurs d’événements reçoivent des événements de deviceOrientation, avec des données sur l’événement, y compris des informations sur l’orientation de l’appareil autour de 3 axesalpha, bêta et gamma.

alpha est la rotation de l’appareil autour de l’axe z, une ligne imaginaire passant verticalement à partir du milieu de l’appareil quand il est couché à plat sur le dos. En théorie, alpha = 0 est face à l’est, 90 est orientée plein sud, 180 est orientée vers l’ouest, et 270 est orienté au Nord, mais pour des raisons pratiques, l’alpha est vraiment seulement une précision de mouvements relatifs, les directions pas absolue, et donc par exemple possible ‘t être utilisé pour créer une boussole.
mesures bêta de la rotation autour de l’axe x, une ligne horizontale à travers le dispositif de gauche à droite. 0 est lorsque l’appareil est plat, les valeurs positives sont le nombre de degrés que l’appareil est incliné vers l’avant, et les valeurs négatives, le nombre de degrés il est incliné vers l’arrière
gamma mesure la rotation de l’appareil autour de l’axe y, le long d’une ligne horizontale au plan de la dispositifs clavier (ou écran). Des valeurs positives dans le nombre de degrés il est incliné vers la droite, et des valeurs négatives, le nombre de degrés, il est incliné vers la gauche

the device orientation axes


Orientation de l’appareil axes, l’image ordinateur portable © umurgdk

En réponse à l’événement

Alors, voici comment nous allons répondre à la l’événement, et de déterminer si l’appareil est déplacé.

fonction checkMotionUsingOrientation (orientationData) {
// détecter le mouvement en utilisant un changement dans l’orientation

seuil de var = 0,7; // sensibilité, plus faible est la plus sensible
var inMotion = false;

var = betaChange orientationData.beta lastBeta // changement en version bêta depuis le dernier événement d’orientation
var = gammaChange orientationData.gamma lastGamma // changement de gamma depuis le dernier événement d’orientation

inMotion = (Math.abs (orientationData.beta lastBeta)> = seuil) || (Math.abs (orientationData.gamma lastGamma)> = seuil)
// si le changement est plus grand que le seuil soit bêta ou gamma, nous avons déménagé

si (inMotion) {
// faire quelque chose parce qu’il est en mouvement
}
}

lastBeta = orientationData.beta;
lastGamma = orientationData.gamma;
// maintenant nous nous souvenons des bêta et gamma lectures les plus récentes pour comparer la prochaine fois

L’argument orientationData est notre événement deviceOrientation. Avec le genre de renseignements que nous nous attendons à de toute façon, il dispose de 3 propriétés, alpha, bêta et gamma, avec pas de prix pour deviner ce que ceux-ci contiennent.

Qu’est-ce que notre fonction est fait obtient les valeurs de bêta et gamma de l’événement, et soustrait la différence de la dernière fois que nous avons mesuré ces. Si l’une de ces diffère de plus à un certain seuil, nous avons mis (dans ce cas un peu moins de 1 degré) puis nous avons détecté un mouvement. On termine par le stockage des valeurs de bêta et gamma et les plus récentes. Nous avons pas pris la peine avec les valeurs alpha, parce que Chrome, à l’heure actuelle le seul navigateur à déclarer ces valeurs sur le bureau, ne signale pas les valeurs alpha, et parce que le déplacement d’un dispositif uniquement autour d’un axe est extrêmement difficile, donc si il ya du mouvement autour de bêta ou gamma, alors que est assez bon pour nos fins. Essentiellement, quand l’appareil est posé à plat sur le dos, tout le monde marche dans le voisinage va déclencher cet événement.

Que diriez-vous de faire la même chose lorsque des événements de mouvement de l’appareil sont pris en charge? Cette fois, au lieu de signaler l’orientation dans l’espace des dispositifs, on obtient des informations sur l’accélération dans chacun des mêmes axes, x, y et z.

     motionData.acceleration.x est l’accélération du dispositif, en mètres par seconde par seconde (ms ^ 2), vers la droite (par rapport au dispositif) (valeurs négatives sont donc accélération de la gauche)
motionData.acceleration.y est l’accélération du dispositif, en mètres par seconde par seconde (ms ^ 2), vers l’avant (par rapport au dispositif) (les valeurs négatives sont accélération “à l’envers“)
motionData.acceleration.z est l’accélération du dispositif, en mètres par seconde par seconde (ms ^ 2), vers le haut (par rapport au dispositif) (les valeurs négatives sont vers le bas)

Voici comment nous utiliserions ce pour détecter le mouvement.

checkMotionUsingMotion: function (motionData) {
// agorithm courtoisie
//http://stackoverflow.com/questions/8310250/how-to-count-steps-using-an-accelerometer

seuil de var = 0,2;
var inMotion = false;

var = ACX motionData.acceleration.x;
var Acy = motionData.acceleration.y;
var = lacZ motionData.acceleration.z;

si (Math.abs (ACX)> seuil) {
inMotion = true
}

si (Math.abs (ACY)> seuil) {
inMotion = true
}

si (Math.abs (lacZ)> seuil) {
inMotion = true
}

si (inMotion) {
// faire quelque chose parce qu’il est en mouvement

}
}

Ici, nous prenons l’accélération de chaque axe, et le cas échéant de ces derniers est supérieure à un certain seuil (à nous assurer que nous ne recevons pas de faux positifs) alors nous sommes en mouvement. Vous pouvez voir qu’il est un peu plus simple que d’utiliser deviceOrientation, que nous ne devons calculateany changement.

Prendre la photo

Alors maintenant, nous pouvons détecter lorsque l’appareil est en mouvement, nous voulons que notre caméra de sécurité pour prendre une photo. Comment allons-nous faire cela? Eh bien, une caractéristique de WebRTC est la capacité de capturer de la vidéo avec la caméra vidéo d’un périphérique. À l’heure actuelle, cela est pris en charge dans Firefox et Chrome sur le bureau, et le navigateur BlackBerry 10 (qui prend également en charge les événements de devicemotion, si votre Blackberry 10 téléphone ou Playbook peuvent servir de caméra de sécurité si vous en avez besoin!), Ainsi que Chrome pour Android (si vous devez l’activer avec chrome: // flags). WebRTC est une API très puissant, mais nous allons seulement besoin d’une petite partie de celui-ci.

Nous allons utiliser la méthode getUserMedia de l’objet navigateur. Cela prend un objet d’options, ainsi que d’un succès et une fonction de rappel de l’échec comme ses arguments.

var options = {vidéo: true};
navigator.getMedia (options, gotVideoStream, getStreamFailed);

Notre choix variable est un objet simple, ici on vient de mettre sa vidéo de propriété sur true (si nous voulions audio nous aimerions également définir une propriété audio de vrai).

Nous avons également passé il deux fonctions de rappel, gotVideoStream, qui sera appelée une fois un flux vidéo est disponible, et getStreamFailed, qui est appelée si nous ne recevons pas un flux vidéo (par exemple, si l’utilisateur refuse la demande du navigateur utiliser la caméra vidéo). getUserMedia utilise rappels, plutôt que de retourner une valeur, car il faut du temps pour l’utilisateur de choisir d’autoriser ou non la vidéo soit activé, et que JavaScript est mono-thread, ce serait bloquer notre interface utilisateur pendant que l’utilisateur attend.

Ensuite, nous allons utiliser flux vidéo.

fonction gotVideoStream (flux) {
var = videoElement document.querySelector (“video”);
videoElement.src = window.URL.createObjectURL (flux);
}

OK, il ya un peu passe ici, prenons donc une étape à la fois. Navigator appelle notre fonction de rappel, le passage d’un flux d’argument. Ceci est un objet MediaStream. Nous utilisons ensuite la méthode de createObjectURL de l’objet de l’URL de la fenêtre pour obtenir une URL du flux (de cette façon, nous pouvons alors faire cette URL la valeur de l’attribut src d’un élément vidéo, alors cet élément vidéo montrera la sortie de notre appareil photo dans temps réel!).

Donc, nous avons maintenant une caméra vidéo de travail, qui montre le flux vidéo à partir de notre appareil de dispositifs dans une page Web. Pas de serveurs, pas de plugins! Mais nous ne disposons pas encore tout à fait notre caméra de sécurité. Ce que nous devons faire est de prendre un instantané du flux vidéo, lorsque nous détectons mouvement. Alors, prenons d’abord l’instantané

Prendre un instantané de l’élément vidéo

Ici, nous allons prendre un instantané de l’élément vidéo à un moment donné. Notez que cela fonctionne indépendamment de ce qui se joue dans l’élément vidéo (si vous pouvez faire une capture d’écran de tout jouer dans un élément vidéo HTML5 comme ça). Prêt?

fonctionner takeSnapshot () {
var = document.querySelector toile («toile»);
contexte var = canvas.getContext (2d’);
var = document.querySelector vidéo (“video”);
context.drawImage (vidéo, 0, 0);
}

Voici ce que nous faisons

nous obtenons un élément de toile de la page
nous obtenons son contexte de dessin 2D
on obtient l’élément de vidéo à partir de la page
nous utilisons la méthode de drawImage de canevas pour dessiner la vidéo sur la toile à partir de (0, 0) (en haut à gauche de la toile).

Oui, il est vraiment facile. Tout comme vous pouvez utiliser canvas.drawImage avec un élément img, nous pouvons l’utiliser avec un élément vidéo.

Maintenant, nous avons toutes les pièces, nous allons mettre ensemble pour créer notre caméra de sécurité.

Rappelez-vous cette partie de nos fonctions de détection de mouvement?

si (inMotion) {
// faire quelque chose parce qu’il est en mouvement
}

Voilà où nous en appelons takeSnapshot, et puis l’image actuelle dans l’élément vidéo est capturée à un élément canvas. Vous pouvez aussi enregistrer cette dans localStorage, ou l’envoyer par e-mail à quelqu’un, ou autrement faire quelque chose avec l’image. Je vais laisser les parties à vous.

Et qui est vraiment tout ce qu’il ya à faire.

Je dois aussi une version de travail entièrement disponible sur github. Il est un peu plus compliqué à lire que le code ici, mais il est abondamment commenté, et le code de travail de base est la même. Ou vous pouvez le voir en action ici (assurez-vous que vous utilisez Chrome avec un dispositif qui prend en charge les événements d’orientation, et dispose d’une webcam).

Notes pour ceux qui suivent

Notez bien que, pour le faire fonctionner à partir de votre disque local, vous aurez besoin de le lancer à travers un serveur web (Chrome ne permettra pas à l’appareil photo de type file: // bien que Firefox). Vous aurez également besoin d’un appareil qui prend en charge l’orientation périphériques ou un périphérique événements de mouvement, qui à ma connaissance ne fonctionne actuellement qu’avec un MacBook Pro (non MacBook Air).

Liens pour en savoir plus

Som plus de lecture sur les différentes caractéristiques que nous avons utilisées pour construire notre caméra de sécurité.

La spécification getUserMedia au W3C
Enregistrement audio et vidéo en HTML5 HTML5 Rocks de
Spécification DeviceMotion et orientation événements au W3C
Cette End Up: Utilisation orientation de l’appareil à partir de roches HTML5
Cross-navigateur caméra capture avec getUserMedia / WebRTC
createObjectURL à Mozilla Developer Network

 

Comments are closed.