Eu tenho uma câmera arducam mini 2MP conectada a um módulo ESP8266 (12-E) e estou tentando implementar o streaming de vídeo dentro de uma janela com alguns botões de texto e controle ao redor, tudo na mesma guia / página do navegador. Eu criei duas páginas HTML para o servidor usar. A primeira é a página inicial sem transmissão de imagens, apenas uma página simples com botões de texto e algum CSS. A segunda página HTML exibe os quadros contínuos (streaming de vídeo), juntamente com alguns textos e botões do navegador. Quando a página inicial é enviada para o navegador, tudo é exibido da maneira que eu espero. Porém, quando a segunda página da Web HTML é exibida, algumas coisas estranhas acontecem quando o navegador (Firefox ou Chrome) recebe a resposta do servidor (esp12-e).
Normalmente, eu esperaria uma pequena janela exibindo quadros contínuos tirados da câmera com algum texto sobre a janela e alguns botões de controle embaixo. Mas, em vez disso, duas coisas acontecem.
- Somente a janela de transmissão de vídeo é exibida na guia do navegador, mas nessa janela há apenas uma cor de fundo cinza. Sem botões, sem texto. Quando abro o HTML Inspector, dentro de "head", existem algumas linhas de código HTML que criam a cor cinza de fundo e algumas coisas CSS que não escrevi no meu servidor. De alguma forma, o navegador cria essas linhas de código automaticamente e as adiciona ao meu código HTML original.
- No meu código HTML original, dentro de "body", junto com o código da janela de streaming, tenho o código para os elementos de texto e botão que serão exibidos. Mas no navegador, essas partes desaparecem. Quando abro o Inspetor, esses elementos não existem! Até agora, tentei várias abordagens para evitar essa situação, isolando / incorporando a janela de streaming na guia do navegador. Essas abordagens são: iframe, URI de dados, substituição multipart / x-mixed, formulário. Infelizmente, o mesmo resultado ocorreu em todas essas abordagens (cor de fundo cinza, janela de transmissão no meio da tela e botões e texto desaparecidos).
A única coisa que sei é que, quando o navegador "vê" a imagem recebida do servidor, produz esses efeitos colaterais. Quando eu crio um HTML apenas com texto e botões, ele é exibido perfeitamente. Faço algo errado aqui, mas não consigo encontrar o que é.
Abaixo, anexo 2 fotos do que recebo na guia do navegador e o código HTML que envio do servidor esp-12e para uma captura de foto
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 fiz alguns progressos, mas não 100%. Consegui exibir imagens JPEG no iframe, incorporando dados no formato JPEG a partir de uma imagem com o método URI de dados dentro do elemento Iframe.
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
Meu erro foi não usar as aspas com a ordem correta e os dados da imagem foram interpretados como texto no navegador. Depois tentei fazer o mesmo com a função usada para enviar a imagem capturada da câmera para o navegador. Infelizmente, o mesmo problema surgiu e não posso corrigi-lo desta vez. Algo acontece quando envio uma sequência com várias aspas para o navegador porque ela as interpreta como texto e não como formato de dados jpeg como este: / 9j / 4AAQ ...... Enviei uma foto do inspetor do navegador (mostrando o navegador) dados recebidos quando uso a função para os dados de quadro enviados da câmera) para entender melhor o que quero dizer. Alguma idéia sobre isso?
Aqui está uma revisão do que concluí até agora.Eu criei um HTML com um Iframe dentro dele e também alguns botões. O iframe e os botões são exibidos corretamente na mesma guia do navegador. Agora, dentro do iframe, coloquei o atributo srcdoc e inseri os dados jpeg brutos diretamente nele (de uma imagem jpeg de amostra), pois eles são codificados (base64), mas o navegador interpretou esses dados jpeg como texto sem formatação e os exibi no iframe como texto. Depois usei a tag image dentro do srcdoc para agrupar os dados jpeg brutos no iframe. Isso funcionou após alguns erros que cometi com as aspas dentro da string iframe. Em seguida, removi os dados jpeg brutos da tag da imagem e os substitui pela função que traz dados jpeg da câmera. Envio a primeira parte da sequência de respostas (abrindo as tags iframe e img), depois envio os dados da câmera e, finalmente, envio a segunda parte da sequência de respostas (fechando as tags iframe e img). Normalmente, ele deve funcionar desde que eu segui o mesmo procedimento de antes. Mas o navegador não conseguiu interpretar a imagem ... novamente.
Abaixo, adicionamos as partes do código da imagem de amostra codificada (que o navegador interpretou como imagem) e, em seguida, a função da câmera (que as interpretou como caracteres estranhos e não como imagem), para comparação. Ambos devem funcionar da mesma maneira, mas apenas os primeiros trabalhos.
Imagem de amostra 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 ";
Função da câmera sendFrame ():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
Então, acho que descobri o que há de errado com os dados jpeg recebidos da câmera. A função camera traz os dados jpeg (para o servidor e depois para o cliente) em um formato que o navegador interpreta como texto ou algo parecido porque contém caracteres estranhos (verifique a última imagem que publiquei).
Também para escrever o código html, uso aspas "e '(ou" e \') para criar o código iframe e tudo o mais dentro do iframe.
E eis a questão: como alguns dos dados jpeg da câmera são interpretados como citações pelo navegador, eles interagem com as citações que coloquei no iframe para envolver a tag img e os dados provenientes da câmera, e é por isso que estraga tudo no iframe (eu acho)
Existe alguma maneira de converter os dados da imagem provenientes da função da câmera em base64, para que eles não interajam com as aspas das tags iframe e image?
Content-Type
, como é claramente sendo interpretado como uma imagem (todos os estilos inseridos são estilos internos Firefox )