Tengo una cámara arducam mini 2MP conectada a un módulo ESP8266 (12-E) y estoy tratando de implementar la transmisión de video dentro de una ventana con algunos botones de texto y control alrededor, todo en la misma pestaña / página del navegador. He creado dos páginas HTML para que el servidor las use. La primera es la página web de inicio sin transmisión de imágenes, solo una página simple con botones de texto y algo de CSS. La segunda página HTML sirve los cuadros continuos (transmisión de video) junto con algunos textos y botones para el navegador. Cuando la página de inicio se envía al navegador, todo se muestra de la manera que esperaba. Pero, cuando se sirve la segunda página web HTML, pero suceden algunas cosas extrañas cuando el navegador (Firefox o Chrome) recibe la respuesta del servidor (esp12-e).
Normalmente esperaría una pequeña ventana que muestre cuadros continuos tomados de la cámara con algo de texto sobre esa ventana y algunos botones de control debajo de ella. Pero, en lugar de eso, suceden dos cosas.
- Solo se muestra la ventana de transmisión de video en la pestaña del navegador, pero alrededor de esta ventana solo hay un color de fondo gris. Sin botones ni texto. Cuando abro el Inspector HTML, dentro del "encabezado", hay algunas líneas de código HTML que crean el color gris de fondo y algunas cosas CSS que no he escrito en mi servidor. De alguna manera, el navegador crea estas líneas de código automáticamente y las agrega en mi código HTML original.
- En mi código HTML original, dentro del "cuerpo", junto con el código de la ventana de transmisión, tengo el código para los elementos de texto y botón que se mostrarán. Pero en el navegador, estas partes desaparecen. Cuando abro el Inspector, estos elementos no existen. He intentado varios enfoques hasta ahora para evitar esta situación aislando / incrustando la ventana de transmisión dentro de la pestaña del navegador. Estos enfoques son: iframe, URI de datos, reemplazo multipart / x-mixed, forma. Desafortunadamente, se produjo el mismo resultado para todos estos enfoques (color de fondo gris, ventana de transmisión en el medio de la pantalla y botones y texto desaparecidos).
Lo único que sé es que, cuando el navegador "ve" la imagen entrante del servidor, produce estos efectos secundarios. Cuando creo un HTML solo con texto y botones, se muestra muy bien. Hago algo mal aquí, pero no puedo encontrar lo que es.
A continuación adjunto 2 imágenes de lo que obtengo en la pestaña del navegador y el código HTML que envío desde el servidor esp-12e para una captura de fotos
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);
}
Finalmente progresé, pero no al 100%. Logré mostrar imágenes jpeg en el iframe incrustando datos en formato jpeg de una imagen con método URI de datos dentro del elemento Iframe.
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
Mi error fue que no utilicé las comillas con el orden correcto y los datos de la imagen se interpretaron como texto en el navegador. Luego intenté hacer lo mismo con la función que uso para enviar la imagen capturada de la cámara al navegador. Desafortunadamente, surgió el mismo problema y no puedo solucionarlo esta vez. Algo que sucede cuando envío una cadena con varias comillas al navegador porque las interpreta como texto y no como un formato de datos jpeg como este: / 9j / 4AAQ ...... Subí una imagen del inspector de mi navegador (mostrando el recibí datos cuando uso la función para los datos de cuadro enviados de la cámara) para entender más fácilmente lo que quiero decir. ¿Alguna idea sobre esto?
Aquí hay una revisión de lo que he completado hasta ahora.Creé un HTML con un Iframe dentro y también algunos botones. Tanto el iframe como los botones se muestran correctamente en la misma pestaña del navegador. Ahora, dentro del iframe puse el atributo srcdoc e inserté los datos jpeg sin procesar directamente allí (de una imagen jpeg de muestra) ya que están codificados (base64) pero el navegador interpretó estos datos jpeg como texto sin formato y los mostró en el iframe como texto. Luego usé la etiqueta de imagen dentro de srcdoc para envolver los datos sin formato JPEG en el iframe. Esto funcionó después de algunos errores que hice con las comillas dentro de la cadena iframe. Luego eliminé los datos jpeg sin procesar de la etiqueta de imagen y los reemplacé con la función que trae datos jpeg de la cámara. Envío la primera parte de la cadena de respuesta (abriendo etiquetas iframe e img), luego envío los datos desde la cámara y finalmente envío la segunda parte de la cadena de respuesta (cierre las etiquetas iframe e img). Normalmente debería funcionar ya que seguí el mismo procedimiento que antes. Pero el navegador no pudo interpretar la imagen ... otra vez.
A continuación, he agregado las partes del código para la imagen de muestra codificada (que el navegador interpretó como imagen) y luego la función de cámara (que las interpretó como caracteres impares y no como imagen), para comparar. Ambos deberían funcionar de la misma manera, pero solo los primeros funcionan.
Imagen de muestra codificada:
answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" > <p> Error </p> </iframe>\r\n ";
Función de cámara sendFrame ():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
Entonces, creo que he encontrado lo que falla con los datos jpeg entrantes de la cámara. La función de la cámara trae los datos jpeg (al servidor y luego al cliente) en un formato que el navegador lo interpreta como texto o algo así porque contiene personajes extraños (verifique la última imagen que publiqué).
También para escribir el código html utilizo comillas "y '(o" y \') para crear el código del iframe y todo lo demás dentro del iframe.
Y aquí está la cosa: dado que algunos de los datos jpeg de la cámara son interpretados como citas por el navegador, interactúan con las citas que puse dentro del iframe para envolver la etiqueta img y los datos que provienen de la cámara y es por eso que arruina todo en iframe (creo)
¿Hay alguna forma de convertir los datos de imagen que provienen de la función de la cámara en base64, para que no interactúen con las comillas del iframe y las etiquetas de imagen?
fuente
Content-Type
, ya que claramente está siendo interpretado como una imagen (todos los estilos insertados son estilos internos para Firefox )Respuestas:
Está escribiendo directamente desde su cámara web los datos en la transmisión y luego viene la plantilla de respuesta vacía que está construyendo.
Puede ver, no escribe la primera parte de la respuesta a wifi y escribe datos de la cámara directamente en el wifi.
Debido a que sus datos de la cámara ya tienen un formato, sugeriría agregar datos al iframe en lugar de la etiqueta img, donde está ahora y no pertenece.
y donde verifica a qué uri respondió con serveWebpage () que hace similar para que coincida con serveImage () y / yourURIforImage.
fuente
Lo que destaca es su declaración:
Recordé que hay una forma específica de incrustar citas es html: se necesitan algún tipo de caracteres de escape. Busqué en google
Esta pregunta fue respondida en StackOverflow aquí:
¿Cómo escapar correctamente de las comillas dentro de los atributos html?
Parece que tienes comillas entre comillas. Por lo tanto, no estoy seguro de si ya está utilizando los caracteres de escape o no, pero sugeriría usar la opción explícita
para sus citas incrustadas.
fuente