J'ai une caméra arducam mini 2MP connectée à un module ESP8266 (12-E) et j'essaie d'implémenter le streaming vidéo à l'intérieur d'une fenêtre avec du texte et des boutons de contrôle autour, le tout dans le même onglet / page de navigateur. J'ai créé deux pages HTML à utiliser par le serveur. La première est la page Web d'accueil sans streaming d'images, juste une simple page avec des boutons de texte et du CSS. La deuxième page HTML sert les images continues (streaming vidéo) ainsi que du texte et des boutons au navigateur. Lorsque la page d'accueil est envoyée au navigateur, tout s'affiche comme je m'y attendais. Mais, lorsque la deuxième page Web HTML est servie, mais des choses étranges se produisent lorsque le navigateur (Firefox ou Chrome) reçoit la réponse du serveur (esp12-e).
Normalement, je m'attendrais à une petite fenêtre affichant des images continues prises de l'appareil photo avec du texte sur cette fenêtre et des boutons de contrôle en dessous. Mais, au lieu de cela, deux choses se produisent.
- Seule la fenêtre de streaming vidéo s'affiche dans l'onglet du navigateur mais autour de cette fenêtre il n'y a qu'une couleur de fond grise. Pas de boutons, pas de texte. Lorsque j'ouvre l'inspecteur HTML, à l'intérieur de "head", il y a quelques lignes de code HTML qui créent la couleur grise d'arrière-plan et des trucs CSS que je n'ai pas écrits sur mon serveur. D'une manière ou d'une autre, le navigateur crée automatiquement ces lignes de code et les ajoute dans mon code HTML d'origine.
- Dans mon code HTML d'origine, à l'intérieur de "body", avec le code de la fenêtre de streaming, j'ai le code pour le texte et les éléments de bouton qui seront affichés. Mais dans le navigateur, ces parties disparaissent. Lorsque j'ouvre l'inspecteur, ces éléments n'existent pas! Jusqu'à présent, j'ai essayé différentes approches pour éviter cette situation en isolant / incorporant la fenêtre de streaming dans l'onglet du navigateur. Ces approches sont: iframe, données URI, multipart / x-mixed replace, form. Malheureusement, le même résultat s'est produit pour toutes ces approches (couleur de fond gris, fenêtre de streaming au milieu de l'écran et boutons et texte disparus).
La seule chose que je sais, c'est que lorsque le navigateur "voit" l'image entrante du serveur, il produit ces effets secondaires. Lorsque je crée un HTML uniquement avec du texte et des boutons, il s'affiche très bien. Je fais quelque chose de mal ici mais je ne trouve pas ce que c'est.
Ci-dessous, je joins 2 photos de ce que j'obtiens dans l'onglet du navigateur et le code HTML que j'envoie du serveur esp-12e pour une capture photo
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);
}
J'ai finalement fait quelques progrès mais pas à 100%. J'ai réussi à afficher des images jpeg dans l'iframe en incorporant des données au format jpeg à partir d'une image avec la méthode URI de données à l'intérieur de l'élément Iframe.
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
Mon erreur est que je n'ai pas utilisé les guillemets dans le bon ordre et les données d'image ont été interprétées comme du texte dans le navigateur. J'ai ensuite essayé de faire la même chose avec la fonction que j'utilise pour envoyer l'image capturée de l'appareil photo vers le navigateur. Malheureusement, le même problème s'est posé et je ne peux pas le résoudre cette fois. Quelque chose se produit lorsque j'envoie une chaîne avec plusieurs guillemets au navigateur car elle les interprète comme du texte et non comme un format de données jpeg comme ceci: / 9j / 4AAQ ...... J'ai téléchargé une photo de l'inspecteur de mon navigateur (montrant le navigateur reçu des données lorsque j'utilise la fonction pour les données de trame envoyées par l'appareil photo) pour comprendre plus facilement ce que je veux dire. Des idées à ce sujet?
Voici un examen de ce que j'ai accompli jusqu'à présent.J'ai créé un HTML avec un Iframe à l'intérieur et aussi quelques boutons. L'iframe et les boutons sont affichés correctement dans l'onglet du même navigateur. Maintenant, à l'intérieur de l'iframe, j'ai mis l'attribut srcdoc et inséré les données JPEG brutes directement dedans (d'un exemple d'image JPEG) car elles sont encodées (base64) mais le navigateur a interprété ces données JPEG en texte brut et les a affichées dans l'iframe en tant que texte. Ensuite, j'ai utilisé la balise image dans srcdoc pour envelopper les données JPEG brutes dans l'iframe. Cela a fonctionné après quelques erreurs que j'ai faites avec les guillemets dans la chaîne iframe. Ensuite, j'ai supprimé les données jpeg brutes de la balise d'image et les ai remplacées par la fonction qui apporte les données jpeg de la caméra. J'envoie la première partie de la chaîne de réponse (ouverture des tags iframe et img), puis j'envoie les données de la caméra et enfin j'envoie la deuxième partie de la chaîne de réponse (fermeture des balises iframe et img). Normalement, cela devrait fonctionner puisque j'ai suivi la même procédure que précédemment. Mais le navigateur n'a pas pu interpréter l'image ... à nouveau.
Ci-dessous, j'ai ajouté les parties de code pour l'échantillon d'image codé (que le navigateur a interprété comme image), puis la fonction appareil photo (qui les a interprétées comme des caractères impairs et non comme une image), à titre de comparaison. Les deux devraient fonctionner de la même manière mais seulement les premiers travaux.
Exemple d'image codée:
answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" > <p> Error </p> </iframe>\r\n ";
Fonction appareil photo sendFrame ():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
Donc, je pense que j'ai trouvé ce qui se passe mal avec les données jpeg entrants de l'appareil photo La fonction de la caméra apporte les données jpeg (au serveur, puis au client) dans un format que les interprète du navigateur sous forme de texte ou quelque chose comme ça parce qu'il contient personnages étranges (vérifiez la dernière image que j'ai postée).
Aussi pour écrire le code html j'utilise des guillemets "et '(ou" et \') pour créer le code iframe et tout le reste à l'intérieur iframe.
Et voici la chose: parce que certaines données jpeg de l'appareil photo sont interprétées comme des citations par le navigateur, elles interagissent avec les citations que je mets à l'intérieur d'iframe pour envelopper la balise img et les données provenant de la caméra et c'est pourquoi cela gâche tout dans iframe (je pense)
Est-il possible de convertir les données d'image provenant de la fonction appareil photo en base64, afin qu'elles n'interagissent pas avec les guillemets enveloppants des balises iframe et image?
Content-Type