ESP8266(12-E)モジュールに接続されたarducam mini 2MPカメラを使用していて、テキストとコントロールボタンが周囲にあるウィンドウ内に、すべて同じブラウザータブ/ページにビデオストリーミングを実装しようとしています。サーバーで使用する2つのHTMLページを作成しました。1つ目は、画像ストリーミングのないホームWebページで、テキストボタンといくつかのCSSを備えた単純なページです。2番目のHTMLページは、連続するフレーム(ストリーミングビデオ)といくつかのテキストおよびボタンをブラウザーに提供します。ホームページがブラウザに送信されると、すべてが期待どおりに表示されます。しかし、2番目のHTML Webページが提供されているが、ブラウザー(FirefoxまたはChrome)がサーバー(esp12-e)からの応答を受信すると、奇妙なことが発生します。
通常、私は小さなウィンドウにカメラから取得した連続フレームを表示し、そのウィンドウ上にテキストとその下にいくつかのコントロールボタンを表示することを期待します。しかし、その代わりに2つのことが起こります。
- ブラウザのタブにはビデオストリーミングウィンドウのみが表示されますが、このウィンドウの周りには灰色の背景色しかありません。ボタンなし、テキストなし。「インスペクタ」の「ヘッド」の内側を開くと、背景の灰色を作成する数行のHTMLコードと、サーバーで記述していないCSS要素がいくつかあります。どういうわけか、ブラウザはこのコード行を自動的に作成し、私のオリジナルのHTMLコードに追加します。
- 私の元のHTMLコードでは、「body」内に、ストリーミングウィンドウのコードとともに、表示されるテキスト要素とボタン要素のコードがあります。しかし、ブラウザでは、これらの部分は消えます。インスペクターを開くと、これらの要素は存在しません!これまでに、ブラウザのタブ内にストリーミングウィンドウを分離/埋め込むことで、この状況を回避するためにさまざまなアプローチを試みてきました。これらのアプローチは、iframe、データURI、multipart / x-mixed replace、formです。残念ながら、これらすべてのアプローチで同じ結果が発生しました(灰色の背景色、画面中央のストリーミングウィンドウ、表示されていないボタンとテキスト)。
私が知っている唯一のことは、ブラウザがサーバーからの着信画像を「見る」と、これらの副作用が生じることです。テキストとボタンのみのHTMLを作成すると、うまく表示されます。私はここで何か悪いことをしていますが、それが何であるかを見つけることができません。
以下に、ブラウザーのタブで取得したものの2つの写真と、esp-12eサーバーから送信した写真キャプチャ用のHTMLコードを添付します。
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);
}
ようやく少し進歩しましたが、100%ではありません。iframe要素内にデータURIメソッドを含む画像からjpeg形式のデータを埋め込むことにより、iframeにjpeg画像を表示することができました。
string = "<iframe srcdoc='<img src=\"data:html/text;base64,/9j/4AAQ..... \" > ' > ";
私の間違いは、正しい順序で引用符を使用せず、画像データがブラウザーでテキストとして解釈されることでした。次に、キャプチャした画像をカメラからブラウザーに送信するために使用する関数を使用して、同じことを試みました。残念ながら、同じ問題が発生し、今回は修正できません。次のように、jpegデータ形式ではなくテキストとして解釈されるため、複数の引用符を含む文字列をブラウザに送信すると、何かが起こります。/ 9j / 4AAQ ......ブラウザのインスペクタから画像をアップロードしました(ブラウザのカメラの送信フレームデータの関数を使用したときに受信したデータ)が意味を理解しやすくします。これに関するアイデアはありますか?
ここに私がこれまでに完了したことのレビューがあります。内部にiframeといくつかのボタンを含むHTMLを作成しました。iframeとボタンの両方が同じブラウザーのタブに正しく表示されます。ここで、iframe内にsrcdoc属性を置き、そこに生のjpegデータを直接(サンプルjpeg画像の)挿入しました(base64)が、ブラウザーはこれらのjpegデータをプレーンテキストとして解釈し、iframeにテキストとして表示しました。次に、srcdoc内のイメージタグを使用して、未加工のjpegデータをiframeにラップしました。これは、iframe文字列内の引用符で行ったいくつかのミスの後に機能しました。次に、画像タグから未加工のjpegデータを削除し、カメラからjpegデータを取り込む機能に置き換えました。応答文字列の最初の部分(iframeとimgタグを開く)を送信します。次に、カメラからデータを送信し、最後に応答文字列の2番目の部分(iframeタグとimgタグを閉じる)を送信します。以前と同じ手順を実行したので、通常は機能するはずです。しかし、ブラウザは画像を解釈できませんでした...もう一度。
以下に、比較のために、エンコードされたサンプル画像(ブラウザーが画像として解釈したもの)のコード部分と、カメラ機能(それらを画像ではなく奇数文字として解釈したもの)のコード部分を追加しました。どちらも同じように機能するはずですが、最初の機能のみが機能します。
エンコードされたサンプル画像:
answer = "<iframe srcdoc='<img src=\"data:image/jpeg;base64,/9j/4AAQS...0KDQo=\"> ' scrolling=\"no\" width=\"340\" height=\"340\" > <p> Error </p> </iframe>\r\n ";
カメラ関数sendFrame():
answer = "<iframe srcdoc=\"<img src='data:image/jpeg;base64,";
client.print(answer);
sendFrame();
answer ="' > \" > <p> Error </p> </iframe>\r\n ";
client.print(answer);
だから、私はカメラの受信jpegデータに問題があることを見つけたと思います奇妙な文字(私が投稿した最後の画像を確認してください)。
また、htmlコードを記述するために、引用符 "および '(または"および\')を使用して、iframeコードおよびその他すべてをiframe内に作成します。
そして、これが問題です:カメラのjpegデータの一部はブラウザーによって引用として解釈されるため、imgタグとカメラからのデータをラップするためにiframe内に置いた引用と相互作用し、それがすべてを台無しにしてしまう理由ですiframeで(私は思う)
とにかく、カメラ機能からの画像データをbase64に変換して、iframeタグと画像タグのラッピング引用符と相互作用しないようにしますか?
Content-Type
ことが明確にイメージとして解釈されていて(すべての挿入のスタイルがあり、内部Firefoxのスタイル)