Deblan blog

Tag #Webcam

Afficher une webcam sur son site (version Linux)

Il y a déjà un article pour afficher sa webcam sur une page web mais en plus d'être un peu à la rue, il ne fonctionne pas sur Linux.

Nous allons voir comment intégrer une webcam sur son site web sous Linux.

Il nous faut :

  • Un serveur web
  • Un accès SSH
  • Une webcam
  • Un ou deux logiciels en local

Note : je travail sur Debian, il faut donc transposer mes commandes pour votre distribution.

Étape 1 : les logiciels en local
# aptitude update
# aptitude install openssh-client vgrabbj rsync imagemagick screen
  • openssh-client : notre client SSH
  • vgrabbj : il permettra de capturer les images de la webcam
  • rsync : il sera notre outil d'upload d'image et va s'appuyer sur SSH
  • imagemagick : pour faire un traitement sur l'image (ajouter du texte)
  • screen : pour lancer le script sans monopoliser un terminal
Étape 2 : préparation des répertoires de travail

On va créer un répertoire qui accueillera le script et la capture :

# le répertoire du script
$ if [ -d "$HOME/bin" ] || mkdir "$HOME/bin"
# le répertoire de la capture
$ if [ -d "$HOME/.webcam" ] || mkdir "$HOME/.webcam"

Création du fichier :

$ cd "$HOME/bin"
$ touch webcam
$ chmod +x webcam
Étape 3 : Et on édite le script

Je propose de faire ça en simple shell, donc pas de bash mais un bon vieux sh (ou dash sur Debian).

#!/bin/sh

On prépare des variables de configuration :

# Le login et le serveur
SSH_SERVER="simon@exemple.com"
# Des options à passer au client SSH
# -p indique le port de connexion
# -i permet de paramétrer une clé SSH
SSH_OPTIONS=" -p 22 -i $HOME/.ssh/id_dsa" 

# Chemin vers l'image que va générer la webcam
IMG_LOCAL="$HOME/.webcam/webcam.jpg"

# Le chemin de l'image sur le serveur distant
IMG_REMOTE="/services/web/www/exemple.com/public_html/ressources/webcam.jpg"

# Qualité de l'image générée (de 1 à 100 et plus c'est grand, plus c'est zoli)
IMG_QUALITY=75

# Les dimensions de l'image
# sqcif= 128x96,     qsif = 160x120,
# qcif = 176x144,    sif  = 320x240,
# cif  = 352x288,    vga  = 640x480,
# svga = 800x600,    xga  = 1024x768,
# sxga = 1280x1024,  uxga = 1600x1200
IMG_SIZE=sif

# Je vais afficher du texte sur l'image donc je paramètre sa couleur et sa position
IMG_TEXT_COLOR=black
IMG_TEXT_X=8
IMG_TEXT_Y=16

# Le périphérique webcam à utiliser
VIDEO_INPUT=/dev/video0

# Le temps entre deux captures (en secondes)
WAIT=5

# la fonction text va retourner le texte à afficher sur la webcam
text() {
	# ça donnera : login @ mm/jj/aa hh:mm:ss
	echo "$USER @ $(date +'%D %r')"
}

On ajoute une sécurité : ne pas avoir deux scripts qui tente un accès à la webcam en même temps :

LOCK="$HOME/.webcam/.lock"

while [ -f "$LOCK" ]; do
	sleep 1
done

touch "$LOCK"

On termine par les commandes de capture, d'écriture du texte et d'upload :

# On capture l'image
vgrabbj -i "$IMG_SIZE" -f "$IMG_LOCAL" -d "$VIDEO_INPUT" -q "$IMG_QUALITY" -a 3 -n

# On ajoute le texte
mogrify -fill "$IMG_TEXT_COLOR" -pointsize 11 -annotate +"$IMG_TEXT_X"+"$IMG_TEXT_Y" "$(text)" "$IMG_LOCAL"

# On upload 
rsync -avz -e "ssh $SSH_OPTIONS" "$IMG_LOCAL" "$SSH_SERVER":"$IMG_REMOTE"
# Note : certains seront peut-être plus à l'aise avec scp, c'est comme vous voulez

On termine par boucler tout ça :

# on délock l'accès à la webcam
rm -f "$LOCK"

# On fait attendre un peu le script
sleep $WAIT

# On l'exécute lui-même 
"$0"&

# Et on arrête l'exécution courante
exit 0

Le script complet (sans commentaire) :

#!/bin/sh

SSH_SERVER="simon@exemple.com"
SSH_OPTIONS=" -p 22 -i $HOME/.ssh/id_dsa" 

IMG_LOCAL="$HOME/.webcam/webcam.jpg"

IMG_REMOTE="/services/web/www/exemple.com/public_html/ressources/webcam.jpg"

IMG_QUALITY=75
IMG_SIZE=sif
IMG_TEXT_COLOR=black
IMG_TEXT_X=8
IMG_TEXT_Y=16

VIDEO_INPUT=/dev/video0

WAIT=5

text() {
	echo "$USER @ $(date +'%D %r')"
}

LOCK="$HOME/.webcam/.lock"
 
while [ -f "$LOCK" ]; do
	sleep 1
done

touch "$LOCK"

vgrabbj -i "$IMG_SIZE" -f "$IMG_LOCAL" -d "$VIDEO_INPUT" -q "$IMG_QUALITY" -a 3 -n
mogrify -fill "$IMG_TEXT_COLOR" -pointsize 11 -annotate +"$IMG_TEXT_X"+"$IMG_TEXT_Y" "$(text)" "$IMG_LOCAL"
rsync -avz -e "ssh $SSH_OPTIONS" "$IMG_LOCAL" "$SSH_SERVER":"$IMG_REMOTE"

rm -f "$LOCK"

sleep $WAIT
"$0"&
exit 0
Étape 4 : la page html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ma webcam</title>
<script>
// Deux helpers pour attacher un évenement à un object et un selecteur rapide d'élement par id
var addEvent = function(object, eventName, myFunction) {
	if(object.addEventListener) {
		object.addEventListener(eventName, myFunction, false);
	} else if(object.attachEvent) {
		object.attachEvent('on'+eventName, myFunction);
	}
}
var $ = function(id) {
	return document.getElementById(id);
}

// On ne veut pas de clignottement donc entre chaque
// chargement d'image, on attend que celui-ci soit 
// terminé pour mettre à jour l'image dans la page
var image_reload = function(id, time) {
	var img = $(id);
	if(img) {
		var _img = new Image();
		var src = (img.getAttribute('src')).split('?')[0]+'?'+Math.random();
		_img.src = src;
		addEvent(_img, 'load', function() {
			img.setAttribute('src', src);
		});
		window.setTimeout(function() {
			image_reload(id, time);
		}, time);
	}
}

addEvent(window, 'load', function() {
	// id de l'image de la webcam et temps de rafraissement
	image_reload('webcam', 2000); 
});
</script>
<body>

<p><img data-dimension="destroy" id="webcam" src="/ressources/webcam.jpg" alt="" title=""/></p>

</body>
Étape 5 : lancer le script
$ screen
$ ./bin/webcam

C'est terminé :)