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.
- 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.
- 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;\"> ⚓ Observation Panel ⚓</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);
}
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?
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?
Content-Type
Bild