Ho una mini fotocamera Arducam da 2 MP collegata a un modulo ESP8266 (12-E) e sto cercando di implementare lo streaming video all'interno di una finestra con alcuni pulsanti di testo e controllo attorno, tutti nella stessa scheda / pagina del browser. Ho creato due pagine HTML da utilizzare per il server. La prima è la home page senza streaming di immagini, solo una semplice pagina con pulsanti di testo e alcuni CSS. La seconda pagina HTML serve i frame continui (streaming video) insieme a testo e pulsanti al browser. Quando la home page viene inviata al browser, tutto viene visualizzato come mi aspetto. Ma, quando viene pubblicata la seconda pagina HTML ma accadono cose strane quando il browser (Firefox o Chrome) riceve la risposta dal server (esp12-e).
Normalmente mi aspetterei una piccola finestra che mostra i fotogrammi continui presi dalla fotocamera con del testo sopra quella finestra e alcuni pulsanti di controllo sotto di essa. Ma invece succedono due cose.
- Nella finestra del browser viene visualizzata solo la finestra di streaming video, ma attorno a questa finestra è presente solo un colore di sfondo grigio. Nessun pulsante nessun testo. Quando apro Inspector HTML, all'interno di "head", ci sono alcune righe di codice HTML che creano il colore grigio di sfondo e alcune cose CSS che non ho scritto nel mio server. In qualche modo il browser crea automaticamente queste righe di codice e le aggiunge nel mio codice HTML originale.
- Nel mio codice HTML originale, all'interno di "body", insieme al codice per la finestra di streaming, ho il codice per gli elementi di testo e pulsante che verranno visualizzati. Ma nel browser, queste parti scompaiono. Quando apro Inspector questi elementi non esistono! Finora ho provato vari approcci per evitare questa situazione isolando / incorporando la finestra di streaming nella scheda del browser. Questi approcci sono: iframe, URI dei dati, sostituzione multipart / x-mixed, modulo. Sfortunatamente lo stesso risultato si è verificato per tutti questi approcci (colore di sfondo grigio, finestra di streaming al centro dello schermo e pulsanti e testo scomparsi).
L'unica cosa che so è che, quando il browser "vede" l'immagine in arrivo dal server, produce questi effetti collaterali. Quando creo un HTML solo con testo e pulsanti, questo viene visualizzato bene. Faccio qualcosa di sbagliato qui, ma non riesco a trovare quello che è.
Di seguito allego 2 immagini di ciò che ottengo nella scheda del browser e il codice HTML che invio dal server esp-12e per scattare una 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);
}
Alla fine ho fatto qualche progresso ma non al 100%. Sono riuscito a visualizzare immagini jpeg nell'iframe incorporando i dati in formato jpeg da un'immagine con il metodo URI dei dati all'interno dell'elemento Iframe.
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
Il mio errore è stato che non ho usato le virgolette con l'ordine corretto e che i dati dell'immagine sono stati interpretati come testo nel browser. Quindi ho provato a fare la stessa cosa con la funzione che utilizzo per inviare l'immagine catturata dalla fotocamera al browser. Sfortunatamente è sorto lo stesso problema e questa volta non posso risolverlo. Qualcosa accade quando invio una stringa con più virgolette al browser perché le interpreta come testo e non come formato di dati jpeg in questo modo: / 9j / 4AAQ ...... Ho caricato un'immagine dall'ispettore del mio browser (mostrando il browser dati ricevuti quando utilizzo la funzione per i dati di frame inviati dalla fotocamera) per capire più facilmente cosa intendo. Qualche idea su questo?
Ecco una recensione di ciò che ho completato finora.Ho creato un HTML con un Iframe al suo interno e anche alcuni pulsanti. Sia iframe che i pulsanti sono visualizzati correttamente nella stessa scheda del browser. Ora, all'interno di iframe ho inserito l'attributo srcdoc e ho inserito i dati jpeg grezzi direttamente al loro interno (di un'immagine jpeg di esempio) poiché sono codificati (base64) ma il browser ha interpretato questi dati jpeg come testo semplice e li ha visualizzati nell'iframe come testo. Quindi ho usato il tag immagine all'interno di srcdoc per racchiudere i dati jpeg grezzi nell'iframe. Questo ha funzionato dopo alcuni errori che ho fatto con le virgolette all'interno della stringa iframe. Quindi ho rimosso i dati jpeg grezzi dal tag immagine e li ho sostituiti con la funzione che porta i dati jpeg dalla fotocamera. Mando la prima parte della stringa di risposta (aprendo i tag iframe e img), quindi invio i dati dalla telecamera e infine invio la seconda parte della stringa di risposta (chiusura dei tag iframe e img). Normalmente dovrebbe funzionare da quando ho seguito la stessa procedura di prima. Ma il browser non è stato in grado di interpretare l'immagine ... di nuovo.
Di seguito, ho aggiunto le parti di codice per l'immagine di esempio codificata (che il browser ha interpretato come immagine) e quindi la funzione della fotocamera (che le ha interpretate come caratteri dispari e non immagine), per confronto. Entrambi dovrebbero funzionare allo stesso modo, ma solo i primi funzionano.
Immagine di esempio codificata:
answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" > <p> Error </p> </iframe>\r\n ";
Funzione telecamera sendFrame ():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
Quindi, penso di aver trovato ciò che non va nei dati jpeg in entrata della fotocamera La funzione fotocamera porta i dati jpeg (sul server e quindi sul client) in un formato che il browser li interpreta come testo o qualcosa del genere perché contiene personaggi strani (controlla l'ultima immagine che ho pubblicato).
Inoltre per scrivere il codice HTML uso le virgolette "e" (o "e \") per creare il codice iframe e tutto il resto all'interno di iframe.
Ed ecco il punto: poiché alcuni dei dati jpeg della fotocamera sono interpretati come citazioni dal browser, interagiscono con le virgolette che ho inserito in iframe per avvolgere il tag img e i dati provenienti dalla fotocamera ed è per questo che rovina tutto in iframe (penso)
Esiste un modo per convertire i dati delle immagini provenienti dalla funzione della fotocamera in base64, in modo che non interagiscano con le virgolette dei tag iframe e delle immagini?
Content-Type
, poiché è chiaramente interpretata come un'immagine (tutti gli stili inseriti sono stili interni di Firefox )