Page 1 sur 3

Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 25 déc. 2017, 19:20
par Chrominator
Les flux MJPEG disparaissent des caméras, on trouve souvent un ou plusieurs flux RTSP sans possibilité de les dériver en MJPEG.
J'ai réussi à afficher le flux RTSP d'une caméra dans monitor, mais je n'ai pas conservé cette solution trop gourmande en bande passante à mon goût.
De plus, la conversion du flux par FFMPEG (dans mon cas) prend trop de ressources pour un pi, trop de frames sont perdues.

J'ai plutôt cherché du côté des snapshots, ces images qu'on peut récolter à la volée grâce à une API de la caméra.
Après tout c'est comme ça que c'est affiché dans Domoticz à première vue.

Le résultat fonctionne plutôt bien.
Évidemment le nombre d'images par seconde dépend de la vitesse du réseau, de celle de l'ordinateur qui affiche monitor et de celle de la caméra.
Mais même sur un smartphone en 3G c'est utilisable.

Si vous souhaitez utiliser cette modification, voici la marche à suivre.
Je vous conseille de lire une première fois en entier ce qui suit, puis de vous lancer. ;)

On se situe dans le répertoire qui contient monitor, d'habitude c'est /home/pi/domoticz/www/monitor/


1. Modifier /home/pi/domoticz/www/monitor/js/frontpage.js

Autour de la ligne 15, on trouve l'appel à quelques fonctions.
Ajoutez l'appel à la fonction GetSnapCams qu'on créera un peu plus loin.
snapcam1.PNG
snapcam1.PNG (13.1 Kio) Consulté 12374 fois
Vers la ligne 535, ajoutez aussi un appel à la fonction GetSnapCams.
snapcam2.PNG
snapcam2.PNG (7.34 Kio) Consulté 12374 fois

juste avant function SceneToggle, insérer GetSnapCams.
Le point d'insertion devrait être à la ligne 1553.
Cette nouvelle fonction introduit un nouveau type de toggle, Snapcam.
On l'utilisera dans /home/pi/domoticz/www/monitor/js/frontpage.settings.js pour traiter les snapshots de notre caméra.

Code : Tout sélectionner

function GetSnapCams()
{
	//	for( var ii = 0, len = $.PageArray.length; ii < len; ii++ ) {
	    var ii = 0, len = $.PageArray.length;
		jsKata.nofreeze.forloop(
			  // the condition
			  function() { return ii < len - 1;  }, 
			  // the incrementor
			  function() { ii++; },
			  // this is what will be executed
			  function fct() {	
					if ( $.PageArray[ii][1] === 'Snapcam' ) { 				//Special nummer, link in cell (test)
																			
							var vlabel=     $.PageArray[ii][2];             // cell number from HTML layout
							var src_1 = 	$.PageArray[ii][3];				// Local network
							var src_2 = 	$.PageArray[ii][4];				// www
							
							if(src_2 === '' || typeof src_2 === 'undefined'){
								src_2 = [location.href.replace( "index.html", "" ).replace(/\/$/, ''),'/icons/offline.jpg'].join('');
							}	
						
							$(['#',vlabel].join('')).html(['<canvas id="video-canvas" class=\'camera\'></canvas>'].join(''));
							var canvas = document.getElementById('video-canvas'),
								context = canvas.getContext('2d'),
								imageObj = new Image(),
								imageSrc = src_1 + "&",
								unique = new Date();
								
							var img_width = canvas.width;
							var img_height = canvas.height;
							console.log('context.drawImage(imageObj, 0, 0, ' + img_width + ', ' + img_height + ');');
							imageObj.onload = function(){
								context.drawImage(imageObj, 0, 0, img_width, img_height);
								unique = new Date();
								imageObj.src = imageSrc + unique.getTime();
							};
							imageObj.onerror = function(){
									console.log('on error: '+this.src);
								   this.src = src_2 + "&" + unique.getTime();
									console.log('on error: '+this.src);
							};
							
							imageObj.src = imageSrc;
							
							$(['#',vlabel,' canvas'].join('')).click(function(){
																	var elem = document.getElementById("popup_camera");
																	var height = window.getComputedStyle(elem,null).getPropertyValue("height");
																	var width = window.getComputedStyle(elem,null).getPropertyValue("width");
																	console.log('canvas dimension according to css. height=' + height + ' - width=' + width);
																	$('#popup_camera').html(['<canvas id="video-canvas2" width="' + width + '" height="' + height + '"></canvas>'].join(''));
																	var canvas = document.getElementById('video-canvas2'),
																		context = canvas.getContext('2d'),
																		imageObj = new Image(),
																		imageSrc = src_1 + "&",
																		unique = new Date();
														
																	var img_width = canvas.width;
																	var img_height = canvas.height;
																	console.log('Zoom context.drawImage(imageObj, 0, 0, ' + img_width + ', ' + img_height + ');');
																	
																	imageObj.onload = function(){
																		context.drawImage(imageObj, 0, 0, img_width, img_height);
																		unique = new Date();
																		imageObj.src = imageSrc + unique.getTime(); 
																	};
														
																	imageObj.onerror = function(){
																			console.log('on error: '+this.src);
																		   this.src = src_2 + "&" + unique.getTime();
																			console.log('on error: '+this.src);
																	};
																	
																	imageObj.src = imageSrc;
																	lightbox_open('camera', 25400);
																});
							
															
							if ($(['#desc_',vlabel].join('')).length > 0) {
								$(['#desc_',vlabel].join('')).empty();
							}
					}
					
					
		});	
}
2. Utilisez un utilitaire pour compacter le code de /home/pi/domoticz/www/monitor/js/frontpage.js.
J'ai utilisé celui de https://javascript-minifier.com/, ça a très bien fonctionné.
Il vous suffit de récupérer le code compacté et le mettre dans le répertoire de /home/pi/domoticz/www/monitor/js/ sous le nom frontpage.min.js
Pour ceux qui ne voudraient pas se lancer dans la modif de sources, je joins ici le fichier modifié d'après la version de monitor sous Github actuellement et datée du 30 mai 2017.
frontpage.min.zip
(8.99 Kio) Téléchargé 544 fois
Si vous avez modifié le source /home/pi/domoticz/www/monitor/js/frontpage.js, enregistrez le aussi avec celui qui est comprimé, pour des raisons de cohérence.
Le voici aussi pour ceux qui ne veulent pas toucher les sources.
frontpage.zip
(14.02 Kio) Téléchargé 525 fois
3. Modifier le fichier /home/pi/domoticz/www/monitor/js/frontpage_settings.js comme vous le faites d'habitude pour une caméra, mais utilisez le toggle Snapcam à la place de camera.
Les autres paramètres sont identiques, l'un pour le flux LAN, l'autre pour le flux WAN. Bien sûr, charge à vous d'utiliser l'API qui permet d'obtenir un snapshot.
Ça ressemble à ceci sur une caméra Foscam :

Code : Tout sélectionner

http://<ip de la caméra>:<port>/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=<nom utilisateur>&pwd=<mot de passe>
Normalement ça devrait afficher votre caméra sur la page monitor que vous avez modifié.
Vider le cache devrait éviter de perdre trop de temps à savoir pourquoi ça ne marche pas.

Vous pouvez vous arrêter là si vous êtes satisfaits.
Évidemment, comme à l'origine, un popup avec l'image agrandie apparaît quand on clique dessus.

Perso, ma caméra affichant l'image en 16:9, la déformation me gênait dans monitor qui affiche en 640/480.
Si vous souhaitez jouer sur le format, il faut tripoter le fichier /home/pi/domoticz/www/monitor/css/global.css et chercher à la ligne 305 #popup_camera.
Attention #popup_camera est référencé plusieurs fois, celui qui est intéressant est celui de la ligne 305.
snapcam3.PNG
snapcam3.PNG (9.33 Kio) Consulté 12374 fois
J'ai modifié le mien comme suit, pour ma tablette murale :
snapcam4.PNG
snapcam4.PNG (6.78 Kio) Consulté 12374 fois
Vous êtes toujours là ? :shock:
Voilà, c'est terminé. :lol:

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 26 déc. 2017, 12:10
par fab0030
Super !
Fonctionne parfaitement, tu viens de me faire récupérer un pi sur lequel tournait motion et un port rj (mon switch est full) sur lequel je vais pouvoir mettre mon pont HUE que papa noël m'a offert!!
merci

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 08 janv. 2018, 11:13
par totof60
Bonjour
Merci pour ce tuto.

il y deux phrases que je n'ai pas compris :
Les autres paramètres sont identiques, l'un pour le flux LAN, l'autre pour le flux WAN
Bien sûr, charge à vous d'utiliser l'API qui permet d'obtenir un snapshot
J'ai une camera IP Xiaomi XiaoFang avec le hack

Merci d'avance pour le coup de pouce

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 08 janv. 2018, 21:25
par Chrominator
Les autres paramètres sont identiques, l'un pour le flux LAN, l'autre pour le flux WAN
Le script frontpage_settings.js admet 2 adresses pour une caméra ; l'une formée des adresses internes au LAN (ex. 192.168.x.x), l'autre pour les adresses utilisables depuis Internet et qui seront routables.
C'est dans la doc de monitor écrite par vil1driver à la section cameras : ../viewtopic.php?f=25&t=331
Bien sûr, charge à vous d'utiliser l'API qui permet d'obtenir un snapshot
Je ne connais pas ta caméra, il y a certainement une URL qui permet d'obtenir un snapshot (un cliché) depuis ta caméra.
Regarde sur Google ou dans la doc de la caméra si tu trouves cette URL camera IP Xiaomi XiaoFang snapshot
Pour illustrer mes propos, je donnais l'URL d'une foscam récente :

Code : Tout sélectionner

http://<ip de la caméra>:<port>/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=<nom utilisateur>&pwd=<mot de passe>

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 09 janv. 2018, 15:36
par vil1driver
Salut,

Notre ami Deennoo à bossé sur une modification du hack de la xiaofang pour nous offrir ce fameux snapshot

Il en parle ici
http://domo-attitude.fr/camera-xiaomi-x ... cz-jeedom/

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 11 janv. 2018, 11:54
par totof60
Merci de vos éclaircissements , je comprends mieux . :P

J'ai hacké ma camera mais sans le hack qui permet les snapshot.

je vais rester comme cela car avec le hack évoqué par Deennoo il n'y a plus de rstp.

merci quand même.

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 11 janv. 2018, 14:00
par fab0030
Bonjour,
Si c'est ok pour monitor, cela me pose un problème avec MQTT.
Je me suis fait quelques lignes qui lorsque quelqu'un sonne j'ai, entre autre, automatiquement l'affichage du popup de la caméra du portier. Je ne vois pas comment intégré cette modif ??

Code : Tout sélectionner

					case "portier_sonnette": // nom du bouton de la télécommande
						
						var oAudio = document.getElementById('myaudio');
						
						if (message.nvalue == 1){		// status On 
		
						mySwipe.slide(1);   // vers page maison (la première page est numéroté 0)
	
						var launched = false;
	
							oAudio.src = "sounds/Ding_Dong.ogg";	// ding dong d'alerte
							oAudio.play();
							oAudio.onended = function() {
												if ( !launched ) {
												launched = true;
												oAudio.src = "sounds/presence_portail.ogg";
												oAudio.play();
											}	
										};
										
							//var source = "http://192.168.1.96:8888";	// source du flux de la caméra
							//$('#popup_camera').html('<img src='+source+' >');	// charge le flux dans la popup caméra
							//lightbox_open('camera', 30000);	// afficher la popup 20 secondes
							
							var source = "http://192.168.1.49:81/snapshot.cgi?user=xxxx&pwd=xxxx";	// source du flux de la caméra
							$('#popup_camera').html('<img src='+source+' >');	// charge le flux dans la popup caméra
							lightbox_open('camera', 30000);	// afficher la popup
														
						}	
						
						if (message.nvalue == 0)		// status Off
							lightbox_close('camera');	// fermer la popup
							
						break;	

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 11 janv. 2018, 18:16
par alain25
Beau travail Chrominator, MERCI, fonctionnement nickel ...

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 12 janv. 2018, 19:18
par Chrominator
Merci, ça fait plaisir :D

Re: Ajouter une caméra sans flux MJPEG dans Monitor

Publié : 25 janv. 2018, 12:04
par berut77
Bonjour,
merci pour le taff et le partage car cela permet d'exploiter et de customiser comme nous le souhaitons.

J'ai testé l'ajout de camera de chez SFR via le snapcam nikel cela fonctionne, après avoir galéré le problème login/pw.
Par contre j'ai déclaré dans le frontpage_setting.js 4 cameras via 4 @ip différentes pour les afficher dans 4 cellules mais j'ai un problème :
- Les images de mes cameras s'affichent alternativement dans la première cellule et les autres sont en offline
- par contre lorsque que je clic sur chaque cellule, dans le popup c'est la bonne caméra !

Quelqu'un aurait-il une idéé ? voici un screen
Cdt
Gabriel
snapcam.PNG
snapcam.PNG (171.45 Kio) Consulté 11911 fois