9408 PoE: Probleme bei der Integration in eine Webseite per HTML5

Hallo liebe Community,

ich komme leider nicht weiter und habe bereits einige Artikel im Forum gelesen, hänge jedoch nach wie vor an meinem Problem fest: Ich habe eine 9408 PoE Kamera bei mir lokal installiert und die Portfreigabe auf Port 80 gemacht. Auch der DDNS-Link extern funktioniert und ich kann auf das die Instar-Oberfläche zugreifen. Jetzt habe ich die Integration gemäß der Wiki-Anleitung gemäß HTML5 gemacht und erhalte nach wie vor einfach kein Bild der Kamera auf meiner Webseite. Ich habe die lokale IP-Adresse verwendet, habe danach aber auch die DDNS-Adresse getestet. Auch ohne Erfolg. Port 80 ist in der Index.html konfiguriert, Zugangsdaten der Kamera auch mehrfach gegengetestet. Scheint alles richtig, aber ich bekomme schlichtweg kein Bild auf der Webseite. Die Webseite ist einwandfrei erreichbar und reagiert auch auf Änderungen im HTML-Content. Scheint also auch nicht das Problem zu sein.

Kann mir bitte jemand über die Straße helfen?

Danke vorab & viele Grüße,
Rainer

Hallo Rainer,

ich habe noch keine eigene Webseite für meine Kameras erstellt, würde aber mal den Port ändern. Z.B. 8081.
Du hast im Wiki anscheinend diesen Link besucht?

Viele Grüße und viel Spaß im Forum!

2 Likes

Für den externen Zugriff wird auf jeden Fall die DDNS Adresse benötigt. Und, wenn die Webseite HTTPS nutzt, braucht man auch den HTTPS Zugriff auf die Kamera - sprich Port 443 anstelle von Port 80 (Der HTTPS Port der Kamera kann auch in der Netzwerk Konfiguration angepasst und muss dann entsprechend im Router durchgeleitet werden).

Für der oben verlinkten Anleitung für den Web-Socket Stream muss in dem Fall auch wss („secure websocket“) anstelle von ws ausgewählt werden.

Um rauszufinden ob das wirklich das aktuelle Problem ist, kann man nach dem Aufruf der Webseite einen Blick in die Browser Konsole werfen - da sollte eine entsprechende Fehlermeldung zu finden sein.

Hallo estimator,
danke für deinen Beitrag. Ich hatte ursprünglich diese Anleitung hier verfolgt:

Aber selbst mit der Anleitung die du geteilt hast, komme ich nicht weiter. Bei beiden Integrationen verwende ich den DDNS-Link, den mir mein Instar Camera Tool generiert. Dieser funktioniert auch problemlos direkt bei mir im Browser oder auf dem Smartphone via Internet. Somit funktioniert auch die Portfreigabe auf Port 80. Zur Webseite: Ich verwende derzeit einfach nur die HTML-Datei, die im Download-Paket dabei ist, konfiguriere sie und nutze sie zum Test als Index.html. Somit ist nicht einmal https eingebunden. Ich will zunächst einfach nur ganz simpel diese Webseite zum Laufen bekommen, dann implementiere ich das Ganze in die Ziel-Webseite. Aber wie gesagt: DDNS eingetragen Port 80 freigegeben und getestet. Zugangsdaten der Kamera eingetragen und geht leider nicht ;-). Ich komme gerade nicht mehr weiter…

Du musst auf jeden Fall den WQHD-Link benutzen. Hast Du gemäß @INSTAR auch den wss benutzt?
Die Straße wird immer breiter… :wink:

In was für einen Webserver?

Ich hoste direkt bei 1&1 (Ionos)

Hier mal meine Konfiguration der wsclient.js:

// Add your camera configuration here
var ws_protocol = "wss";
var ws_hostname = "http://meine-ddns-id.ddns3-instar.de";
var ws_port     = "80";
var ws_endpoint = "/ws";
var cam_username = "admin";
var cam_password = "pw";

// Add media mime type
// 0 => 'video/mp4; codecs="avc1.4D001E, mp4a.40.2"'
// 1 => 'video/mp4; codecs="avc1.4D001E"'
// 2 => 'video/mp4; codecs="hev1.2.4.L120.B0, mp4a.40.2"'
// 3 => 'video/mp4; codecs="hev1.2.4.L120.B0"'
var codec_mime = 0;

var queue = [];
var video = null;
var webSocket   = null;
var sourceBuffer = null;
var streamingStarted = false;

// Init the Media Source and add event listener
function initMediaSource() {
    video = document.querySelector('video');
    video.onerror = elementError;
    video.loop = false;
    video.addEventListener('canplay', (event) => {
        console.log('Video can start, but not sure it will play through.');
        video.play();
    });
    video.addEventListener('paused', (event) => {
        console.log('Video paused for buffering...');
        setTimeout(function() { video.play(); }, 2000);
    });
    
    /* NOTE: Chrome will not play the video if audio is defined here
    * and the stream does not include audio */
    // var mimeCodec = 'video/mp4; codecs="avc1.4D001E, mp4a.40.2"';
    // var mimeCodec = 'video/mp4; codecs="avc1.4D001E"';
    // var mimeCodec = 'video/mp4; codecs="hev1.2.4.L120.B0, mp4a.40.2"';
    // var mimeCodec = 'video/mp4; codecs="hev1.2.4.L120.B0"';

    if (codec_mime.value = 0) {
            var mimeCodec = 'video/mp4; codecs="avc1.4D001E, mp4a.40.2"';
        } else if (codec_mime.value = 1) {
            var mimeCodec = 'video/mp4; codecs="avc1.4D001E"';
        } else if (codec_mime.value = 2) {
            var mimeCodec = 'video/mp4; codecs="hev1.2.4.L120.B0, mp4a.40.2"';
        } else {
            var mimeCodec = 'video/mp4; codecs="hev1.2.4.L120.B0"';
    }

    if (!window.MediaSource) {
        console.error("No Media Source API available");
        document.getElementById("incomingMsgOutput").value += "error: No Media Source API available" + "\r\n";
        return;
    }
    
    if (!MediaSource.isTypeSupported(mimeCodec)) {
        console.error("Unsupported MIME type or codec: " + mimeCodec);
        document.getElementById("incomingMsgOutput").value += "error: Unsupported MIME type or codec" + "\r\n";
        return;
    }
    
    var ms = new MediaSource();
    video.src = window.URL.createObjectURL(ms);
    ms.addEventListener('sourceopen', onMediaSourceOpen);
    
    function onMediaSourceOpen() {
        sourceBuffer = ms.addSourceBuffer(mimeCodec);
        sourceBuffer.addEventListener("updateend",loadPacket);
        sourceBuffer.addEventListener("onerror", sourceError);
    }
    
    function loadPacket() { // called when sourceBuffer is ready for more
        if (!sourceBuffer.updating) {
            if (queue.length>0) {
                data = queue.shift(); // pop from the beginning
                appendToBuffer(data);
            } else { // the queue runs empty, so we must force-feed the next packet
                streamingStarted = false;
            }
        }
        else {}
    }
    
    function sourceError(event) {
        console.log("Media source error");
    }
    
    function elementError(event) {
        console.log("Media element error");
    }
}

// Append AV data to source buffer
function appendToBuffer(videoChunk) {
    if (videoChunk) {
        sourceBuffer.appendBuffer(videoChunk);
    }
}

// Event handler for clicking on button "Connect"
function onConnectClick() {
     // Makes sure that user typed username and message before sending
     if ((ws_protocol === '') || (ws_hostname === '') || (ws_port === '') || (ws_endpoint === '') ||(cam_username === '') || (cam_password === '')) {
        return false;
    } else {
        initMediaSource();
        openWSConnection(cam_username, cam_password, ws_protocol, ws_hostname, ws_port, ws_endpoint);
        }    
}

// Event handler for clicking on button "Disconnect"
function onDisconnectClick() {
    webSocket.close();
    video.pause();
}

// Open a new WebSocket connection using the given parameters
function openWSConnection(username, password, protocol, hostname, port, endpoint) {
    
    var webSocketURL = null;
    var keepAliveCount = 0;
    
    webSocketURL = protocol + "://" + username + ":" + password + "@" + hostname + ":" + port + endpoint;
    console.log("openWSConnection::Connecting to: " + webSocketURL);

    try {
        // webSocket = new WebSocket(webSocketURL);
        webSocket = new ReconnectingWebSocket(webSocketURL);
        webSocket.debug = true;
        webSocket.timeoutInterval = 3000;
        webSocket.onopen = function(openEvent) {
            var open = JSON.stringify(openEvent, null, 4);
            console.log("WebSocket open");
        };
        webSocket.onclose = function (closeEvent) {
            var closed = JSON.stringify(closeEvent, null, 4);
            console.log("WebSocket closed");
        };
        webSocket.onerror = function (errorEvent) {
            var error = JSON.stringify(errorEvent, null, 4);
            console.log("WebSocket ERROR: " + error);
        };
        webSocket.onmessage = function (messageEvent) {
            var wsMsg = messageEvent.data;
            if (typeof wsMsg === 'string') {
            	if (wsMsg.indexOf("error:") == 0) {
                	document.getElementById("incomingMsgOutput").value += wsMsg + "\r\n";
            	} else {
                	document.getElementById("incomingMsgOutput").value += "echo message: " + wsMsg + "\r\n";
            	}
            } else {
                var arrayBuffer;
                var fileReader = new FileReader();
                fileReader.onload = function(event) {
                    arrayBuffer = event.target.result;
                    var data = new Uint8Array(arrayBuffer);
                    document.getElementById("incomingMsgOutput").value += "received: " + data.length + " bytes\r\n";
                    if (!streamingStarted) {
                        appendToBuffer(arrayBuffer);
                        streamingStarted=true;
                        return;
                    }
                    queue.push(arrayBuffer); // add to the end
                };
                fileReader.readAsArrayBuffer(wsMsg);
                /* NOTE: the web server has a idle-timeout of 60 seconds,
                 so we need to send a keep-alive message regulary */
                keepAliveCount++;
                if (keepAliveCount >= 10 && webSocket.readyState == WebSocket.OPEN) {
                    keepAliveCount = 0;
                    webSocket.send("keep-alive");
                }
            }
        };
    } catch (exception) {
        console.error(exception);
    }
}

// Start livestream
function onSendClickStart() {
    if (webSocket.readyState != WebSocket.OPEN) {
        console.error("webSocket is not open: " + webSocket.readyState);
        return;
    }
    var msg = "livestream";
    webSocket.send(msg);
}

// Stop livestream
function onSendClickStop() {
    if (webSocket.readyState != WebSocket.OPEN) {
        console.error("webSocket is not open: " + webSocket.readyState);
        return;
    }
    var msg = "stop";
    webSocket.send(msg);
}

—> Frage hierzu:
Was ist hiermit gemeint:

  • ws_endpoint = /ws (Die URL, unter der der ws-Stream bereitgestellt wird)

Um welche URL geht es denn hier? Den DDNS-Link habe ich ja bereits eingetragen…?!

Es scheint tatsächlich das ws-Problem zu sein, denn diese Fehlermeldung gibt mein Browser im Developer Mode aus. Kann mit hierzu bitte jemand einen Tipp geben was ich beim ws-Pfad angeben muss?
Vielen Dank gleich vorab!

Ich habe mal Deinen Snapshot entfernt, da dort Login-Daten angegeben waren.

Das ist aufmerksam aber nicht nötig, denn das alles ist nur ein Test-Setup und alle Login-Daten, etc werden danach so wie so geändert. Zudem wird das Projekt keine geheime Überwachsungskamera sondern eine Beobachtung für ein Strochennest, auf das - ohne Einschränkung - jeder Einblick bekommen soll :-).

Fohrde?..

Nein, wir sind in der Südpfalz :slight_smile:

Wenn die Kamera steht kannst Du ja mal den Link posten. :slight_smile:
Ich wundere mich bei den Störchen immer, wie die ungeschützt in luftiger Höhe bei Wind und Wetter leben können. Respekt!

1 Like

Ich poste nochmals mein Problem:

Generell hätte ich gedacht, dass man erst einmal Port Forwarding im Router eintragen sollte, bevor die Kamera von aussen erreichbar sein soll. Den Port 80 würde ich auf z.B. 8081 in der Kamera setzen, dann im Router diesen Port freigeben und dann im Script eintragen.
Dann würde ich erwarten, dass Dein gehostetes Script auch funktionieren müsste. Aber wie gesagt, das habe ich selber noch nicht ausprobiert.

Wahrscheinlich keine URL die Du hier eintragen müsstet. /ws ist wohl eine Art Referenz auf Deine eingetragene URL.

Port forwarding ist konfiguriert und getestet. Läuft alles. Ich habe - wie gesagt - ein Websocket-Problem, zu welchem ich Hilfe brauche.
Ich hänge jetzt nochmals die Fehlermeldung an, die mein Browser zurückgibt:
Image 02.02.25 at 11.40

Das http:// muss raus :point_up_2:t2:

Das Protokoll hier ist wss:// - da hinten darf kein http:// in der Adresse stehen.

Und wenn man WSS nutzt (was notwendig ist wenn man per HTTPS auf die Seite zugreift), dann muss der HTTPS Port zur Kamera durchgeleitet sein - d.h. über Port 80 wird es nicht laufen.

EDIT:

Der WS (und WSS) Endpunkt bei den 2K+ WQHD Kameras ist immer nur /ws - d.h. dieser muss nicht angepasst werden.

1 Like