Tôi có một máy ảnh mini 2MP arducam được kết nối với mô-đun ESP8266 (12-E) và tôi đang cố gắng thực hiện truyền phát video bên trong một cửa sổ với một số nút điều khiển và văn bản xung quanh nó, tất cả trong cùng một tab / trang trình duyệt. Tôi đã tạo hai trang HTML để máy chủ sử dụng. Đầu tiên là trang web gia đình không có hình ảnh trực tuyến, chỉ là một trang đơn giản với các nút văn bản và một số CSS. Trang HTML thứ hai phục vụ các khung liên tục (truyền phát video) cùng với một số văn bản và nút cho trình duyệt. Khi trang chủ được gửi tới trình duyệt, mọi thứ sẽ được hiển thị theo cách tôi mong đợi. Nhưng, khi trang web HTML thứ hai được phục vụ nhưng một số điều kỳ lạ xảy ra khi trình duyệt (Firefox hoặc Chrome) nhận được phản hồi từ máy chủ (đặc biệt là12).
Thông thường tôi sẽ mong đợi một cửa sổ nhỏ hiển thị các khung hình liên tục được lấy từ máy ảnh với một số văn bản trên cửa sổ đó một số nút điều khiển bên dưới nó. Nhưng, thay vì hai điều đó xảy ra.
- Chỉ cửa sổ phát video được hiển thị trong tab của trình duyệt nhưng xung quanh cửa sổ này chỉ có màu nền xám. Không có nút không có văn bản. Khi tôi mở Trình kiểm tra HTML, bên trong "phần đầu", có một vài dòng mã HTML tạo màu xám nền và một số nội dung CSS mà tôi chưa viết trong máy chủ của mình. Bằng cách nào đó trình duyệt tự động tạo dòng mã này và thêm chúng vào mã HTML gốc của tôi.
- Trong mã HTML gốc của tôi, bên trong "phần thân", cùng với mã cho cửa sổ phát trực tuyến, tôi có mã cho các thành phần văn bản và nút sẽ được hiển thị. Nhưng trong trình duyệt, những phần này biến mất. Khi tôi mở Thanh tra, những yếu tố này không tồn tại! Tôi đã thử nhiều cách tiếp cận khác nhau để tránh tình trạng này bằng cách cách ly / nhúng cửa sổ phát trực tuyến bên trong tab của trình duyệt. Các cách tiếp cận này là: iframe, URI dữ liệu, thay thế hỗn hợp / x-hỗn hợp, biểu mẫu. Thật không may, kết quả tương tự xảy ra cho tất cả các phương pháp tiếp cận này (màu nền xám, cửa sổ phát trực tuyến ở giữa màn hình và các nút và văn bản biến mất).
Điều duy nhất tôi biết là, khi trình duyệt "nhìn thấy" hình ảnh đến từ máy chủ, nó sẽ tạo ra các hiệu ứng phụ này. Khi tôi tạo HTML chỉ bằng văn bản và các nút, nó sẽ hiển thị tốt. Tôi làm điều gì đó sai ở đây nhưng tôi không thể tìm thấy nó là gì.
Dưới đây tôi đính kèm 2 hình ảnh về những gì tôi nhận được trong tab của trình duyệt và mã HTML tôi gửi từ máy chủ đặc biệt để chụp ảnh
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);
}
Tôi đã thực hiện một số tiến bộ cuối cùng nhưng không phải 100%. Tôi đã quản lý để hiển thị hình ảnh jpeg trong iframe bằng cách nhúng dữ liệu ở định dạng jpeg từ một hình ảnh với phương thức URI dữ liệu bên trong phần tử Iframe.
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
Sai lầm của tôi là tôi đã không sử dụng dấu ngoặc kép với thứ tự chính xác và dữ liệu hình ảnh được hiểu là văn bản trong trình duyệt. Sau đó, tôi đã cố gắng làm điều tương tự với chức năng tôi sử dụng để gửi hình ảnh được chụp từ máy ảnh đến trình duyệt. Thật không may, vấn đề tương tự đã phát sinh và tôi không thể sửa nó lần này. Một cái gì đó xảy ra khi tôi gửi một chuỗi có nhiều trích dẫn tới trình duyệt vì nó diễn giải chúng dưới dạng văn bản chứ không phải định dạng dữ liệu jpeg như thế này: / 9j / 4AAQ ...... Tôi đã tải lên một hình ảnh từ trình kiểm tra trình duyệt của tôi (hiển thị trình duyệt của trình duyệt nhận dữ liệu khi tôi sử dụng chức năng cho dữ liệu khung đã gửi của máy ảnh) để tìm hiểu ý tôi dễ dàng hơn. Bất cứ ý tưởng về điều này?
Dưới đây là một đánh giá về những gì tôi đã hoàn thành cho đến nay.Tôi đã tạo một HTML với Iframe bên trong nó và một số nút. Cả iframe và nút được hiển thị chính xác trong cùng một tab của trình duyệt. Bây giờ, Inside iframe tôi đặt thuộc tính srcdoc và chèn dữ liệu jpeg thô trực tiếp vào đó (của một hình ảnh jpeg mẫu) vì chúng được mã hóa (base64) nhưng trình duyệt đã hiểu các dữ liệu jpeg này dưới dạng văn bản thuần túy và hiển thị chúng trong iframe dưới dạng văn bản. Sau đó, tôi đã sử dụng thẻ hình ảnh bên trong srcdoc để bọc dữ liệu jpeg thô trong iframe. Điều này hoạt động sau một số sai lầm tôi đã làm với các trích dẫn bên trong chuỗi iframe. Sau đó, tôi xóa dữ liệu jpeg thô khỏi thẻ hình ảnh và thay thế chúng bằng chức năng mang dữ liệu jpeg từ máy ảnh. Tôi gửi phần đầu tiên của chuỗi câu trả lời (mở thẻ iframe và img), sau đó tôi gửi dữ liệu từ máy ảnh và cuối cùng tôi gửi phần thứ hai của chuỗi câu trả lời (đóng thẻ iframe và img). Thông thường nó sẽ hoạt động kể từ khi tôi làm theo quy trình như trước. Nhưng trình duyệt không thể giải thích hình ảnh ... một lần nữa.
Dưới đây, tôi đã thêm các phần mã cho hình ảnh mẫu được mã hóa (trình duyệt hiểu là hình ảnh) và sau đó là chức năng camera (giải thích chúng là ký tự lẻ và không phải hình ảnh), để so sánh. Cả hai nên làm việc theo cùng một cách nhưng chỉ hoạt động đầu tiên.
Hình ảnh mẫu được mã hóa:
answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" > <p> Error </p> </iframe>\r\n ";
Chức năng camera sendFrame ():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
Vì vậy, tôi nghĩ rằng tôi đã tìm thấy sự cố với dữ liệu jpeg đến của máy ảnh Chức năng camera mang dữ liệu jpeg (đến máy chủ và sau đó đến máy khách) theo định dạng mà trình duyệt hiểu nó là văn bản hoặc một cái gì đó tương tự vì nó chứa ký tự lạ (kiểm tra hình ảnh cuối cùng tôi đã đăng).
Ngoài ra, để viết mã html, tôi sử dụng dấu ngoặc kép "và '(hoặc" và \') để tạo mã iframe và mọi thứ khác trong iframe.
Và đây là vấn đề: Bởi vì một số dữ liệu jpeg của máy ảnh được trình duyệt hiểu là trích dẫn, chúng tương tác với các trích dẫn tôi đặt bên trong iframe để bọc thẻ img và dữ liệu đến từ máy ảnh và đó là lý do tại sao nó làm rối tung mọi thứ trong iframe (tôi nghĩ)
Có cách nào để chuyển đổi dữ liệu hình ảnh từ chức năng camera thành base64 không, vì vậy chúng không tương tác với dấu ngoặc kép của iframe và thẻ hình ảnh?
Content-Type
, vì rõ ràng nó được hiểu là một hình ảnh (tất cả các kiểu được chèn đều là kiểu Firefox bên trong )