Streaming de Webcam accessible via player Flash

Le but est de mettre en place le streaming d'une webcam (Logitech QuickCam Messenger, 046d:08da) accessible au travers d'un simple lecteur flash àla youpr0n/dailymocheun.

Une solution permettant la captation sonore est également proposée. Par ailleurs, une solution n'utilisant pas de lecteur flash externe est également proposée.

Assertions

Vous utilisez un FFmpeg compilé comme il faut, et qui propose à la fois ffmpeg et ffserver. C'est le cas sous Debian (Squeeze), Ubuntu (9.04) et Mandriva (2009.1 et 2010.0).

La captation (webcam) et la diffusion (ffserver) ont lieu sur la même machine. Il est possible de le faire entre différentes machines, il conviendra cependant d'adapter les adresses (URI, et ACL).

Le serveur FFserver est accessible depuis l'extérieur sur le port 8002.

Configuration FFserver

La configuration est assez simple. L'objectif est de mettre en place trois éléments :

  • Un « faux » stream, /status.html, qui donnera des informations sur le service FFserver ;
  • Un stream d'alimentation, feed, qui sera chargé de récupérer la captation vidéo ;
  • Un stream de diffusion en FLV, alimenté par le précédent stream.

Si besoin, on peut sortir plusieurs streams (dans plusieurs formats, plusieurs bitrate, etc.) à partir d'un même feed.

Port 8002
MaxHTTPConnections 8
MaxClients 8

<Stream status.html>
Format status
ACL allow localhost
</Stream>

<Feed webcam.ffm>
File /tmp/webcam.ffm
FileMaxSize 100k
ACL allow 127.0.0.1
</Feed>

<Stream webcam.flv>
Feed webcam.ffm
Format flv
VideoCodec flv
VideoFrameRate 8
VideoBitRate 256
VideoQMin 1
VideoQMax 5
NoAudio
VideoSize 320x240
</Stream>

Par défaut, le fichier de configuration est /etc/ffserver.conf

Le lecteur pourra ajouter la directive « NoDaemon » au début de la configuration s'il souhaite ne pas perdre la main sur le processus.

Le démarrage du processus se fait en appelant le binaire ffserver. Si la configuration est stockée ailleurs que dans /etc/ffserver.conf, alors le paramètre -f sera à renseigner.

Un fichier de configuration complet d'exemple est donné dans le git : http://git.ffmpeg.org/?p=ffmpeg;a=blob_plain;f=doc/ffserver.conf;hb=HEAD

Récupération du flux vidéo

L'objectif de ce second point est d'opérer la captation, et d'envoyer le flux au serveur FFserver. Nous utilisons pour cette étape ffmpeg :

ffmpeg -an -f video4linux2 -s 320x240 -r 8 -qscale 5 -i /dev/video0 http://localhost:8002/webcam.ffm

Nous capturons donc le flux en l'API V4L2, à une taille de 320×240, et 8 images/s. Ceci est fait depuis le device /dev/video0. Le résultat est envoyé sur le serveur FFserver, pour alimenter le feed qui a été défini. Ici, c'est webcam.ffm.

Certaines Webcam nécessite parfois d'utiliser la compatibilité V4L1 (dont la QuickCam messenger, avec le driver zc3xx). Il faut donc utiliser LD_PRELOAD avec /usr/lib/libv4l/v4l1compat.so (Debian). On obtient :

LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so ffmpeg -an -f video4linux2 -s 320x240 -r 8 -qscale 5 -i /dev/video0 http://localhost:8002/webcam.ffm

Lecteur Flash et page Web (solution standalone)

Le but est de s'affranchir de la dépendance sur Flowplayer. L'idée est de générer l'animation Flash directement depuis FFserver, et de l'inclure dans notre page web.

Nouveau stream dans FFserver

<Stream webcam.swf>
Feed webcam.ffm
Format swf
VideoCodec flv
VideoFrameRate 8
VideoBitRate 256
VideoQMin 1
VideoQMax 5
NoAudio
VideoSize 320x240
</Stream>

Page Web adaptée

<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  
	<link rel="stylesheet" type="text/css" href="style.css">
	<title>Webcam</title>
</head><body>

	<div id="page">
		<h1></h1>
		<object width="640" height="480">
			<embed src="http://url-serveur:8002/webcam.swf" width="640" height="480">
		</object>
	</div>
</body></html>

Lecteur Flash et page Web

L'outil FlowPlayer [http://flowplayer.org/] propose un lecteur Flash sous licence GPL. Nous allons donc l'utiliser. Télécharger et extraire le .swf.

Ensuite, une simple page HTML suffira. Cet exemple est repris de celui distribué avec FlowPlayer. Attention à bien adapter si besoin le numéro de version (3.1.4 ici) aux évolutions futures.

On notera la présence de « play: null » dont l'objectif est de masquer le disgracieux cercle censé se présenter le temps du téléchargement. Étant donné que nous avons un flux, …

<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  
	<script type="text/javascript" src="flowplayer-3.1.4.min.js"></script>
	<link rel="stylesheet" type="text/css" href="style.css">
	<title>Webcam</title>
</head><body>

	<div id="page">
		<h1></h1>
		<a  
			 href="http://url-serveur:8002/webcam.flv"  
			 style="display:block;width:640px;height:480px"  
			 id="player"> 
		</a> 
		<script>
$f("player", "flowplayer-3.1.4.swf", {
	play: null,
	plugins: { 
		controls: "flowplayer.controls-3.1.4.swf", 
	}, 
        clip: {  
            autoPlay: true,
            autoBuffering: false, 
            onBeforeFinish: function() { 
                // returning false prevents the default 
                // behavior associated with this event ---> 
                // it will loop instead of stop at finish 
                return false;  
            }  
          },  
        logo: {  
            opacity: 0  
        }  
});
</script>
	
	</div>
</body></html>

Voilà, normalement ça fonctionne ;)

Capation sonore

Détaillons maintenant ce qu'il convient d'ajouter et/ou modifier pour opérer un streaming incluant la captation du son depuis la webcam.

Diffusion FFserver

Nous ajoutons les éléments de configuration suivant dans nos Stream, à la place de NoAudio :

AudioCodec libmp3lame
AudioBitRate 64k
AudioChannels 1
AudioSampleRate 22050

Captation ALSA

Il faut, dans un premier temps, identifier le device ALSA qui correspond à votre webcam. Pour cela, utiliser

arecord -l

Vous obtiendrez une sortie de la sorte :

$ arecord -l
 **** List of CAPTURE Hardware Devices ****
 card 0: Audigy2 [SB Audigy 2 ZS [SB0350]], device 0: emu10k1 [ADC Capture/Standard PCM Playback]
   Subdevices: 1/1
   Subdevice #0: subdevice #0
 card 0: Audigy2 [SB Audigy 2 ZS [SB0350]], device 1: emu10k1 mic [Mic Capture]
   Subdevices: 1/1
   Subdevice #0: subdevice #0
 card 0: Audigy2 [SB Audigy 2 ZS [SB0350]], device 2: emu10k1 efx [Multichannel Capture/PT Playback]
   Subdevices: 1/1
   Subdevice #0: subdevice #0
 card 0: Audigy2 [SB Audigy 2 ZS [SB0350]], device 4: p16v [p16v]
   Subdevices: 1/1
   Subdevice #0: subdevice #0
 card 1: U0x46d0x8da [USB Device 0x46d:0x8da], device 0: USB Audio [USB Audio]
   Subdevices: 1/1
   Subdevice #0: subdevice #0
 card 2: U0x46d0x8da_1 [USB Device 0x46d:0x8da], device 0: USB Audio [USB Audio]
   Subdevices: 0/1
   Subdevice #0: subdevice #0

La partie qui nous intéresse est l'identifiant : U0x46d0x8da pour la première Webcam, U0x46d0x8da_1 pour la seconde.

Il convient maintenant d'agrémenter l'appel à ffmpeg en utilisant ces informations, pour capturer le son de la première webcam :

-f alsa -i hw:U0x46d0x8da

La captation s'opère donc à présent :

LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so ffmpeg -f video4linux2 -s 320x240 -r 8 -i /dev/video0 -f alsa -i hw:U0x46d0x8da http://localhost:8002/webcam.ffm
webcam_ffserver_ffmpeg.txt · Last modified: 2010/01/12 13:29 (external edit)