weaslflink
Goto Top

CGI Befehle via Webseite an IPCAM senden

Hallo Zusammen,

ich hoffe ihr könnt mir weiterhelfen. Vorab ich kenne mich nicht gut mit JavaScript aus.

Mein Vorhaben ist, meine IP-Kamera über meine Webseite steuern zu können. Mein Problem hierbei ist, dass ich nicht genau weiß wie ich es hin bekomme, dass die Befehle zur Kamerasteuerung nur ausgeführt werden und nicht als Seite geladen werden.

Die Befehle der Kamera sehen z.b so aus
Schwenken Rechts :
http://[IP-der-Kamera]/cgi-bin/hi3510/ptzctrl.cgi?-act=right
Schwenken Stoppen:
http://[IP-der-Kamera]/cgi-bin/hi3510/ptzctrl.cgi?-act=stop
usw.

Wenn ich nun hieraus einen Hyperlink erstelle werde ich zur Seite weitergeleitet mit folgender Rückmeldung
call ptz funtion success
und die Kamera schwenkt bis der "Stop"-Befehl ausgeführt wird.

Ich habe es auch mit einem unsichtbaren IFRAME probiert, hat jedoch leider nicht funktioniert, da hier die Kamera anscheinend nicht angesprochen wurde. Der Vollständigkeit halber wurde folgender Code verwendet.
 
<p><iframe name="response" src="" style="visibility:hidden"</iframe></p>  
<a href="http://192.168.186.42/cgi-bin/hi3510/ptzctrl.cgi?-act=stop" target="response">Stop</a>  
......

In Zuge meiner Recherche habe ich herausgefunden, dass es mit Javascript und Ajax funktionieren sollte, da man hier die Adresse ansprechen aber die Antwort unterdrücken kann.

Das I-Tüpfelchen des ganzen wäre eine "Step" Funktion, soll heißen:
Befehl Schwenken
warte X Sekunden
Befehl Stop

Bevor jetzt die "Hater" kommen :D, Ich erwarte und möchte keine Copy-Paste Antwort, sondern das ganze auch wenig verstehen face-wink

Ich bedanke mich im Voraus für die Hilfe

Content-Key: 294924

Url: https://administrator.de/contentid/294924

Printed on: April 26, 2024 at 05:04 o'clock

Mitglied: 126919
Solution 126919 Feb 02, 2016, updated at Feb 04, 2016 at 15:04:02 (UTC)
Goto Top
Cherio @weaslflink,

hier ein möglicher Code welcher mit den ausreichend erläuternden Kommentaren versehen wurde:
Da ich hier deine Kamera natürlich nicht für einen Test da habe face-wink ist der Code nur unter Vorbehalt funktionsfähig auch wegen eventuellen Sicherheitsrestriktionen der CAM. Aber mit den beigefügten Kommentaren im Code und der jQuery API Dokumentation solltest du das hinbekommen zumal du ja richtigerweise etwas davon lernen willst face-smile. Als Grundlage also schon mal ein Anfang für dein Projekt ...
<!doctype html>
<html>
<head>
<meta charset="utf-8">  
<title>Ajax CAM Test</title>
<style type="text/css">  
	body { font-family:Verdana, Geneva, sans-serif; font-size: 13px}
	table.control td {
	text-align: center;
	line-height:30px;
	height: 30px;
	width: 30px;
}
#status {
	color:red;
	font-weight:bold;	
}
</style>
</head>

<!-- jQuery Library laden (kann natürlich bei Bedarf auch lokal heruntergeladen und dann eingebunden werden) -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>  

<script type="text/javascript">  
/* Funktion die die Befehle entgegen nimmt und an die Kamera schickt
Parameter 1 = Ein String welchen Befehl den die Kamera ausführen soll
Parameter 2 = Wenn dieser Wert größer 0 ist, dann wird der Stop-Befehl mit der angegebenen Anzahl an Sekunden verzögert ausgeführt.
*/
function SendCommand(cmd, step){
	// URL der Kamers (ohne Parameter)
	var url = 'http://[IP der CAM]/cgi-bin/hi3510/ptzctrl.cgi';  
	// Aktion welche in der Variablen 'cmd' steht via GET-Request an die Kamera senden  
	$.get(url,{'-act': cmd}).done(function(data){  
		$('#status').text("Current command: " + cmd); // Bei erfolg Status im DIV ausgeben  
		// Wenn ein step angegeben wurde starte timer und führe dann den Stop-Befehlaus
		if(step != 0){
			window.setTimeout(function(){
				// Stop-Aktion an CAM senden
				$.get(url,{'-act': 'stop'}).done(function(data){  
					$('#status').text("Stopped"); // Status nach Aktion ausgeben  
				});	
			},step * 1000); //Timeout von Sekunden in Millisekunden umrechnen
		}
	}).fail(function(data){
		$('#status').text("Failure to send command: " + data.statusText); //Bei einem Fehler Status im DIV ausgeben  
	});
}
</script>
<body>
<table width="90" height="90" border="0" cellpadding="0" cellspacing="0" class="control">  
  <tr>
    <td>&nbsp;</td>
    <td><a href="#" onClick="SendCommand('up',2)">Up</a></td>  
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td><a href="#" onClick="SendCommand('left',2)">Left</a></td>  
    <td><a href="#" onClick="SendCommand('stop',0)">Stop</a></td>  
    <td><a href="#" onClick="SendCommand('right',2)">Right</a></td>  
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><a href="#" onClick="SendCommand('down',2)">Down</a></td>  
    <td>&nbsp;</td>
  </tr>
</table>
<!-- Status DIV in dem Meldungen der Ajax Requests erscheinen -->
<div id="status"></div>  
</body>
</html>
Hoffe das der Code dir etwas hilft, viel Spass beim Schwenken face-smile

fk
VMWare , Silicon Valley
Member: weaslflink
weaslflink Feb 03, 2016 at 06:19:39 (UTC)
Goto Top
Guten Morgen Flachkoepper ,

Vielen Dank für deine rasche Antwort. Ich werde mich gleich mal versuchen den Code nachfolgen und ausprobieren.
Ich melde mich sobald ich nicht weiter komme bzw es funktioniert hat face-wink

Lg weaslflink
Member: weaslflink
weaslflink Feb 03, 2016 at 10:15:51 (UTC)
Goto Top
Hallo Flachkoepper ,

also ich bekomme es nicht ganz zum laufen. Das merkwürdige ist, dass ich keine Meldungen im DIV Container Status angezeigt bekomme.

am Code habe ich Zeile 33 geändert
von
$.get(url,{'-act': cmd}).done(function(data){
zu
$.get(url,{'?-act'=: cmd}).done(function(data){
da der http request http://192.168.*.*/cgi-bin/hi3510/ptzctrl.cgi?-act=stop"ist.

Kann man den Code irgendwie debuggen um Zeile für Zeile durchzugehen ?

lg weaslflink
Mitglied: 126919
Solution 126919 Feb 03, 2016, updated at Feb 04, 2016 at 15:04:00 (UTC)
Goto Top
Zitat von @weaslflink:

Das merkwürdige ist, dass ich keine Meldungen im DIV Container Status angezeigt bekomme.
JavaScript zufällig über NoScript und Konsorten deaktiviert ?
am Code habe ich Zeile 33 geändert
von
$.get(url,{'-act': cmd}).done(function(data){
zu
$.get(url,{'?-act'=:
Falsch. Das Fragezeichen und das Gleichheitszeichen dürfen hier nicht stehen weil das jQuery automatisch macht, dieser Parameter enthält nur ein reines Array der Daten die aus Eigenschaft : Wert Paaren bestehen! Das sind ja die GET-Parameter die an die CAM mit der URL als Get-Request gesendet werden.

Kann man den Code irgendwie debuggen um Zeile für Zeile durchzugehen ?
Nutze die Developer-Tools der Browser (F12) die enthalten einen JavaScript Debugger.

Du solltest auch sicherstellen das die CAM Remote XMLHTTPRequests per Same-Origin Policy überhaupt zulässt. Das lässt sich im HTTP-Response Header überprüfen, den du dir ebenfalls mit den Developer-Tools anzeigen lassen kannst.

Das es einfach wird habe ich ja nicht gesagt. Du musst dir schon mal die Doku dazu genauer ansehen, dann hättest du auch obige fehlerhafte Anpassung nicht gemacht, du wolltest ja etwas Arbeit face-smile dann ran ans Lesen...
Member: weaslflink
weaslflink Feb 04, 2016 at 14:32:26 (UTC)
Goto Top
Hey,
hatte gestern leider keine Zeit mehr alles auszuprobieren, hatte mich aber noch ein bisschen in die Materie eingelesen.
Ich hatte so ein Brett vorm Kopf. F12 klar ! Hätte man eigentlich auch von selbst drauf kommen können aber ok face-big-smile.

Zu meinem aktuellen Stand:

Ich hab meinen Webserver (Raspberry PI 2) nur über https laufen, daher musste ich auch die jQuery API über https laden.
Bekomme jetzt auch eine Meldung im DIV Container angezeigt nur leider nicht die erwünschte.

Das jetzige Problem ist, dass ich mixed Content habe weil die Kamera nur über http erreichbar ist und mein Server nur über https.
Mein Lösungsansatz wäre entweder die Kamera über https zu tunneln oder, da bin ich gerade dabei zu recherchieren, ob ich das auch über jQuery hin bekomme, was natürlich die bessere Lösung ist.

Weaslflink
Mitglied: 126919
126919 Feb 04, 2016 updated at 17:00:29 (UTC)
Goto Top
angezeigt nur leider nicht die erwünschte.
Wie gesagt keine Kamera (Du sprichst ja immer nur von "Kamera" und nennst noch nicht mal den Typ) keine Info dazu, kein Test, sorry ... Ich schätze die SameOrigin Policy greift bei dieser.

Ich würde die Kommunikation mit der Kamera nicht direkt über das Frontend via JavaScript vornehmen sondern die Kommunikation ein PHP-Script indirekt erledigen lassen welches die Befehle via curl an die Cam sendet und dein JavaScript dann via Ajax die Befehle an dein PHP-Script sendet, damit erschlägst du zwei Fliegen mit einer Klappe und die Probleme mit SSL und der JavaScript SameOrigin-Policy sind Geschichte.
Member: weaslflink
weaslflink Feb 10, 2016 updated at 10:41:55 (UTC)
Goto Top
Hallo,
dein Tipp mit der Kommunikation über ein PHP-Scrip hatte mich auf eine Idee gebracht. Warum nicht via shell_exec die Kamera steuern.
Das ganze habe ich so umgesetzt.

control.php
 
<?php
$cmd=$_GET["cmd"];  
$stop="stop";  
$url="http://[IP-KAMERA]/cgi-bin/hi3510/ptzctrl.cgi?-act=";  
$del="rm ptz*";  
	shell_exec("wget $url$cmd && sleep 1 && wget $url$stop && $del");  
?>

Ich musste hier am Ende nochmal den Befehl "rm ptz*" einfügen da mir der wget Befehl logischerweise eine Datei mit der Antwort der Kamera erstellt.

Die HTML-Datei über welche der Stream und Steuerung eingebunden schaut so aus (nur Steuerungsteil).
livefeed.html
 
<a href="control.php?cmd=right" target="control">Rechts</a>  
<a href="control.php?cmd=down" target="control">Unten</a>  
<a href="control.php?cmd=left" target="control">Links</a>  
<a href="control.php?cmd=up" target="control">Oben</a>  
<p></p>
<iframe name="control" style="display:none"></iframe>  


Man kann das alles bestimmt noch etwas sauber und schöner schreiben aber es funktioniert und das ist die Hauptsache face-smile

Ich bedanke mich nochmal bei dir für deine großartige Hilfe Flachkoepper.

Lg Weaslflink