ESP12-E Video-Streaming-Fenster, Text und Schaltflächen werden nicht wie erwartet angezeigt


8

Ich habe eine Arducam Mini 2MP-Kamera an ein ESP8266 (12-E) -Modul angeschlossen und versuche, Video-Streaming in einem Fenster mit einigen Text- und Steuerschaltflächen zu implementieren, die sich alle auf derselben Browser-Registerkarte / -Seite befinden. Ich habe zwei HTML-Seiten für den Server erstellt. Die erste ist die Homepage ohne Bild-Streaming, nur eine einfache Seite mit Textschaltflächen und etwas CSS. Die zweite HTML-Seite liefert die fortlaufenden Frames (Streaming-Video) zusammen mit Text und Schaltflächen an den Browser. Wenn die Homepage an den Browser gesendet wird, wird alles so angezeigt, wie ich es erwartet habe. Wenn die zweite HTML-Webseite bereitgestellt wird, passieren jedoch einige seltsame Dinge, wenn der Browser (Firefox oder Chrome) die Antwort vom Server erhält (esp12-e).

Normalerweise würde ich ein kleines Fenster erwarten, in dem fortlaufende Bilder angezeigt werden, die von der Kamera aufgenommen wurden, mit etwas Text über diesem Fenster und einigen Steuertasten darunter. Aber stattdessen passieren zwei Dinge.

  1. Auf der Registerkarte des Browsers wird nur das Video-Streaming-Fenster angezeigt. Um dieses Fenster herum befindet sich jedoch nur eine graue Hintergrundfarbe. Keine Schaltflächen kein Text. Wenn ich den HTML-Inspektor in "head" öffne, gibt es einige Zeilen HTML-Code, die die graue Hintergrundfarbe und einige CSS-Inhalte erzeugen, die ich nicht auf meinem Server geschrieben habe. Irgendwie erstellt der Browser diese Codezeilen automatisch und fügt sie meinem ursprünglichen HTML-Code hinzu.
  2. In meinem ursprünglichen HTML-Code habe ich in "body" zusammen mit dem Code für das Streaming-Fenster den Code für die Text- und Schaltflächenelemente, die angezeigt werden. Im Browser verschwinden diese Teile jedoch. Wenn ich den Inspektor öffne, existieren diese Elemente nicht! Ich habe bisher verschiedene Ansätze versucht, um diese Situation zu vermeiden, indem ich das Streaming-Fenster in die Registerkarte des Browsers isolierte / einbettete. Diese Ansätze sind: iframe, Daten-URI, mehrteiliges / x-gemischtes Ersetzen, Formular. Leider trat bei all diesen Ansätzen das gleiche Ergebnis auf (graue Hintergrundfarbe, Streaming-Fenster in der Mitte des Bildschirms und verschwundene Schaltflächen und Text).

Ich weiß nur, dass der Browser diese Nebenwirkungen "sieht", wenn er das vom Server eingehende Bild "sieht". Wenn ich ein HTML nur mit Text und Schaltflächen erstelle, wird es gut angezeigt. Ich mache hier etwas falsch, aber ich kann nicht finden, was es ist.

Unten füge ich 2 Bilder von dem hinzu, was ich auf der Registerkarte des Browsers erhalte, und den HTML-Code, den ich vom esp-12e-Server für eine Fotoaufnahme sende

void serveWebpage(WiFiClient client){

  String answer = "HTTP/1.1 200 OK\r\n";     
  answer += "Content-Type: text/html\r\n\r\n";
  answer +="<!DOCTYPE HTML>\r\n"; 

  answer += "<html>\r\n";
  answer +="<head><title> Monitor </title></head>\r\n";

  answer += "<body>\r\n";
  answer += "<h1 style=\"position:relative; left:25px;\"> &#9875     Observation Panel &#9875</h1>\r\n";     // Header Text

  answer += "<a href=\"/videoStream\"><button type=\"button\"  style=\"position:absolute; top:340px;";   // First Button
  answer += "left:95px; color:blue; height:70px; width:90px; font-weight: bold; border-style:outset;";
  answer += "border-width:2px; border-color:black;\"> Video Stream </button></a>\r\n";

  answer += "<a href=\"PhotoCapture\"><button type=\"button\"  style=\"position:absolute; top:340px;";   // Second Button
  answer += "left:195px; color:blue; height:70px; width:90px; font-weight: bold; border-style:outset;";
  answer += "border-width:2px; border-color:black;\"> Video Stream </button></a>\r\n";

  answer += "<div>\r\n";
  answer += "<img src='data:image/jpeg; charset=utf-8; base64,";   // Here the image is wrapped with data URI to display it in the browser


       myCAM.clear_fifo_flag();    // this part is taken from the arducam library exammples. It captures the image and sends it to browser
       myCAM.start_capture();       

       while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));  // wait here until capture has completed
       size_t len = myCAM.read_fifo_length();

       myCAM.CS_LOW();         
       myCAM.set_fifo_burst();     

       #if !(defined (ARDUCAM_SHIELD_V2) && defined (OV2640_CAM))
       SPI.transfer(0xFF);
       #endif   

       static const size_t bufferSize = 4096; //4096
       static uint8_t buffer[bufferSize] = {0xFF};

       while (len) {                
         size_t will_copy = (len < bufferSize) ? len : bufferSize;
         SPI.transferBytes(&buffer[0], &buffer[0], will_copy);
         if (!client.connected()) break;

         client.write(&buffer[0], will_copy);
         len -= will_copy;
       }
  myCAM.CS_HIGH();

  answer +="9k=' />"; // closing the <img> 
  answer +="</div>\r\n";
  answer +="</body>\r\n";
  answer +="</html>\r\n\r\n";

  client.print(answer);  
}  

Video Window_missing Schaltflächen und Text HTML-Code, den ich geschrieben habe, um vom Server esp-12e bereitgestellt zu werden

Ich habe endlich einige Fortschritte gemacht, aber nicht zu 100%. Ich habe es geschafft, JPEG-Bilder im Iframe anzuzeigen, indem ich Daten im JPEG-Format aus einem Bild mit Daten-URI-Methode in das Iframe-Element eingebettet habe.

    string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > "; 

Mein Fehler war, dass ich die Anführungszeichen nicht in der richtigen Reihenfolge verwendet habe und die Bilddaten im Browser als Text interpretiert wurden. Dann habe ich versucht, dasselbe mit der Funktion zu tun, mit der ich das aufgenommene Bild von der Kamera an den Browser sende. Leider ist das gleiche Problem aufgetreten und ich kann es diesmal nicht beheben. Etwas passiert, wenn ich eine Zeichenfolge mit mehreren Anführungszeichen an den Browser sende, weil sie als Text und nicht als JPEG-Datenformat wie folgt interpretiert wird: / 9j / 4AAQ ...... Ich habe ein Bild aus dem Inspektor meines Browsers hochgeladen (mit dem des Browsers) empfangene Daten, wenn ich die Funktion für die gesendeten Bilddaten der Kamera verwende, um leichter herauszufinden, was ich meine. Irgendwelche Ideen dazu?

Daten werden aufgrund mehrerer Anführungszeichen (?) Fehlerhaft interpretiert.

Hier ist ein Rückblick auf das, was ich bisher abgeschlossen habe.Ich habe einen HTML-Code mit einem darin enthaltenen Iframe und einigen Schaltflächen erstellt. Sowohl der Iframe als auch die Schaltflächen werden auf derselben Registerkarte des Browsers korrekt angezeigt. Jetzt habe ich in iframe das srcdoc-Attribut eingefügt und die JPEG-Rohdaten direkt dort eingefügt (eines Beispiel-JPEG-Bildes), da sie codiert sind (base64), aber der Browser hat diese JPEG-Daten als einfachen Text interpretiert und sie im iframe als Text angezeigt. Dann habe ich das Bild-Tag in srcdoc verwendet, um die rohen JPEG-Daten in den Iframe zu verpacken. Dies funktionierte nach einigen Fehlern, die ich mit den Anführungszeichen in der iframe-Zeichenfolge gemacht hatte. Dann entfernte ich die JPEG-Rohdaten aus dem Bild-Tag und ersetzte sie durch die Funktion, die JPEG-Daten von der Kamera bringt. Ich sende den ersten Teil der Antwortzeichenfolge (Öffnen von Iframe- und IMG-Tags). dann sende ich die Daten von der Kamera und schließlich sende ich den zweiten Teil der Antwortzeichenfolge (Schließen von iframe- und img-Tags). Normalerweise sollte es funktionieren, da ich das gleiche Verfahren wie zuvor befolgt habe. Aber der Browser konnte das Bild nicht interpretieren ... wieder.

Im Folgenden habe ich zum Vergleich die Codeteile für das codierte Beispielbild (das vom Browser als Bild interpretiert wurde) und dann die Kamerafunktion (die sie als ungerade Zeichen und nicht als Bild interpretierte) hinzugefügt. Beide sollten auf die gleiche Weise funktionieren, aber nur die ersten funktionieren.

Codiertes Beispielbild:

    answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" >  <p> Error </p> </iframe>\r\n ";

Kamerafunktion sendFrame ():

    answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
    client.print(answer);
    sendFrame();
    answer ="' > \" >  <p> Error </p> </iframe>\r\n ";
    client.print(answer);

Also, ich glaube , ich gefunden habe , was mit der Kamera eingehenden JPEG - Daten schief geht Die Kamera - Funktion , die JPEG - Daten (auf den Server und dann an den Client) bringt in einem Format , dass der Browser interpretiert es als Text oder so ähnlich , denn sie enthält seltsame Charaktere (überprüfen Sie das letzte Bild, das ich gepostet habe).

Auch um den HTML-Code zu schreiben, benutze ich Anführungszeichen "und '(oder" und \'), um den Iframe-Code und alles andere in Iframe zu erstellen.

Und hier ist die Sache: Da einige der JPEG-Daten der Kamera vom Browser als Anführungszeichen interpretiert werden, interagieren sie mit den Anführungszeichen, die ich in iframe eingefügt habe, um das img-Tag und die von der Kamera kommenden Daten zu verpacken. Deshalb bringt es alles durcheinander in iframe (glaube ich)

Gibt es überhaupt eine Möglichkeit, die von der Kamerafunktion kommenden Bilddaten in base64 zu konvertieren, damit sie nicht mit den Umbruchzitaten der Iframe- und Bild-Tags interagieren?


2
Ist es Ihnen möglich, hier ein minimales Codebeispiel für das Problem anzugeben? Ich vermute, dass ohne das jede Antwort nur Spekulation wäre. Ich vermute, dass Sie das Bild möglicherweise nur oder mit dem falschen Content-TypeBild
bereitstellen

Das zweite Bild enthält den Code, aber ich werde noch einen hochladen. Vielen Dank für die Hilfe
Sparky

1
Ich habe auch an den Servercode gedacht, wenn Sie ihn haben. Verwenden Sie eine vorgefertigte Bibliothek wie diese oder haben Sie Ihre eigene Rolle?
Aurora0001

1
Ja, ich habe diesen Code gelesen, aber ich dachte, ich würde ihn selbst erstellen (um ihn besser zu verstehen). Ich werde es gleich hochladen
Sparky

1
Entschuldigen Sie die verspätete Antwort, aber ich habe den Code ein wenig aufgeräumt, um ... lesbar zu sein. Ich habe verschiedene Methoden ausprobiert, wie ich bereits erwähnt habe. Aber jedes Mal kam es zum gleichen Ergebnis. Also muss es etwas anderes sein. Ich bin ein wenig verloren hier
Sparky

Antworten:


4

Sie schreiben die Daten direkt von Ihrer Webkamera in den Stream und danach kommt die leere Antwortvorlage, die Sie erstellen.

Sie können sehen, Sie schreiben nicht den ersten Teil der Antwort auf WLAN und Sie schreiben Daten von der Kamera direkt in das WLAN.

Da Ihre Daten von der Kamera bereits formatiert sind, würde ich empfehlen, Daten zu iframe anstelle des img-Tags hinzuzufügen, wo sie sich jetzt befinden und nicht dazu gehören.

void serveWebpage(WiFiClient client){

  String answer = "HTTP/1.1 200 OK\r\n";     
  answer += "Content-Type: text/html\r\n\r\n";
  answer +="<!DOCTYPE HTML>\r\n"; 

  answer += "<html>\r\n";
  answer +="<head><title> Monitor </title></head>\r\n";

  answer += "<body>\r\n";
  answer += "<h1 style=\"position:relative; left:25px;\"> &#9875     Observation Panel &#9875</h1>\r\n";     // Header Text

  answer += "<a href=\"/videoStream\"><button type=\"button\"  style=\"position:absolute; top:340px;";   // First Button
  answer += "left:95px; color:blue; height:70px; width:90px; font-weight: bold; border-style:outset;";
  answer += "border-width:2px; border-color:black;\"> Video Stream </button></a>\r\n";

  answer += "<a href=\"PhotoCapture\"><button type=\"button\"  style=\"position:absolute; top:340px;";   // Second Button
  answer += "left:195px; color:blue; height:70px; width:90px; font-weight: bold; border-style:outset;";
  answer += "border-width:2px; border-color:black;\"> Video Stream </button></a>\r\n";

  answer += "<div>\r\n";
  answer += "<iframe src="/yourURIforImage"></iframe>\r\n"; 
  answer +="</div>\r\n";
  answer +="</body>\r\n";
  answer +="</html>\r\n\r\n";

  client.print(answer);  
}  

void serveImage(WifiClient client) {
       myCAM.clear_fifo_flag();    // this part is taken from the arducam library exammples. It captures the image and sends it to browser
       myCAM.start_capture();       

       while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));  // wait here until capture has completed
       size_t len = myCAM.read_fifo_length();

       myCAM.CS_LOW();         
       myCAM.set_fifo_burst();     

       #if !(defined (ARDUCAM_SHIELD_V2) && defined (OV2640_CAM))
       SPI.transfer(0xFF);
       #endif   

       static const size_t bufferSize = 4096; //4096
       static uint8_t buffer[bufferSize] = {0xFF};

       while (len) {                
         size_t will_copy = (len < bufferSize) ? len : bufferSize;
         SPI.transferBytes(&buffer[0], &buffer[0], will_copy);
         if (!client.connected()) break;

         client.write(&buffer[0], will_copy);
         len -= will_copy;
       }
       myCAM.CS_HIGH();
}

und wo Sie überprüfen, auf welche URL Sie mit serveWebpage () geantwortet haben, machen Sie ähnlich wie mit serveImage () und / yourURIforImage.


Ich bin Ihrer Meinung gefolgt und habe unmittelbar nach dem ersten Teil der Antwort einen client.print (Antwort) hinzugefügt. Jetzt kann ich einige Fortschritte sehen. Ich habe das img-Element beibehalten, um zu sehen, was passieren wird. Der Text und die Schaltfläche werden korrekt angezeigt (das ist meiner Meinung nach ein gutes Zeichen), aber die Bilddaten werden vom Browser nicht als Bild interpretiert, sondern als ungerade Zeichen. Warum versteht der Browser die Bilddaten nicht als Bild, da ich die Daten in base64 konvertiert habe? Ich werde einen Iframe hinzufügen und das img-Element löschen, um zu sehen, was passieren wird, und ich werde zurück sein
Sparky

Ich habe ein Iframe-Fenster erstellt und dort versucht, das von der Kamera aufgenommene Bild mit der Daten-URI-Methode einzubetten. Die Bilddaten werden jedoch vom Browser nicht als Bild interpretiert, und im iframe werden seltsame Zeichen angezeigt. Außerdem habe ich srcdoc und nicht src verwendet, um die Bilddaten einzubetten. Irgendwelche Ideen?
Sparky

Damit dies funktioniert, schreiben Sie zuerst eine Methode, die nur das Bild erfolgreich zurückgibt, und rufen Sie dann in einer anderen Methode diese Methode <iframe src = "Pfad zum Bild> </ iframe>
mico

Ja, es ist keine schlechte Idee, aber die Sache ist, dass ich ein Bild von der Kamera folgendermaßen verwendet habe: Ich habe das aufgenommene JPEG-Bild auf meinem PC gespeichert, es dann in base64 codiert und es schließlich in den iframe srcdoc-Daten-URI eingefügt angezeigt werden.
Sparky

Ich habe die Bilddaten auch direkt in srcdoc ohne Bild-Tag abgelegt, aber der Browser interpretiert sie als Zeichen. Ungerade Zeichen, nicht nur Buchstaben oder Zahlen.
Sparky

3

Das Besondere ist Ihre Aussage:

Etwas passiert, wenn ich eine Zeichenfolge mit mehreren Anführungszeichen an den Browser sende, weil sie als Text und nicht als JPEG-Datenformat wie folgt interpretiert wird: / 9j / 4AAQ ......

Ich erinnerte mich, dass es eine bestimmte Möglichkeit gibt, Anführungszeichen in HTML einzubetten: Es werden Escapezeichen benötigt. Ich habe gegoogelt

Einbetten von Anführungszeichen in HTML

Diese Frage wurde auf StackOverflow hier beantwortet:

Wie kann man Anführungszeichen in HTML-Attributen richtig umgehen?

Es sieht so aus, als hätten Sie Anführungszeichen in Anführungszeichen. Ich bin mir also nicht sicher, ob Sie die Escape-Zeichen bereits verwenden oder nicht, aber ich würde vorschlagen, die explizite Option zu verwenden

&quot; 

für Ihre eingebetteten Zitate.


Ich werde es versuchen und ich sage dir, was passiert ist. & quote ist dasselbe wie "oder"? Wenn ich & quote und "und" in derselben Zeichenfolge verwende, wie der Browser sie interpretieren wird. Vielen Dank
Sparky

Nicht sicher. Bei einer Google-Suche wurden jedoch viele Ergebnisse zurückgegeben. Ich würde also wetten, dass die Antwort auf diese Frage schnell gefunden wird, wenn Sie die Suche durchführen.
Grldsndrs
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.