0

シンプルな JPEG ファイルを中継するビデオストリームのようなものを実装しようとしています。私のサーバーでは、JPEG が外部カメラによって周期的に作成されています。そして、この画像を GWT アプリケーションに含めたいだけです。

タイマーで画像をリロードする最初のアイデアは非常に単純でしたが、あまり良くありませんでした。クライアントはリロード サイクルごとに接続を開き、画像がちらつきます (少なくとも Firefox では)。

これらの問題をどのように解決できますか? 「Web-Sockets」のようなものを考えていましたが、どうすればいいのかよくわかりません。リロードごとに単一の接続を避けたい。私のアイデアは、クライアントが要求するたびに新しい画像を提供するオープン接続のようなものを持つことでした.

また、画像を交換するときのちらつきを回避するにはどうすればよいですか?

どんなアイデアでも大歓迎です!

よろしく、ヴァンダーレン

4

1 に答える 1

0

ちらつきを避けるための解決策は、2 つの画像を絶対に同じ場所に配置することです。タイマーは、各フレームでどちらか一方を交互にロードします。各画像にハンドラーを設定してload、画像が読み込まれたときに z-index を変更し、タイマーを再起動するようにします。

画像の URL に追加のパラメータを追加すると、ブラウザは毎回サーバーにキャッシュをバイパスするように要求します。

フレーム間の時間が短い場合、通常、サーバーでキープアライブが正しく構成されていれば、ブラウザは同じ接続を再利用し ます。通常は 5 ~ 15 秒の一般的な値で有効になっていますが、これを増やすこともできます。.jpg 画像がこの周期で更新される場合は、心配する必要はなく、より良い解決策を探す必要はありません。

これらの考えに基づいたUIソリューションを提案します。ただし、websocket/comet メカニズムを使用して、base64 形式の最後の .jpg ファイルを提供する場合も同様に機能します (返された値で URL を変更するだけです)。

GWT コード:

public void onModuleLoad() {

  final Image i1 = new Image();
  i1.setWidth("400px");

  final Image i2 = new Image();
  i2.setWidth("400px");

  AbsolutePanel panel = new AbsolutePanel();
  panel.add(i1, 0, 0);
  panel.add(i2, 0, 0);
  panel.setSize("600px", "400px");

  RootPanel.get().add(panel);

  // You could change this by base64 data if you use comet/websockets
  String url = "my_image_url.jpg?";

  final Timer loadNext = new Timer() {
    boolean b;
    int c;
    public void run() {
      // the counter parameter forces to load the next frame instead of using cache
      if (b  = !b) {
        i1.setUrl(url + c++);
      } else {
        i2.setUrl(url + c++);
      }
    }
  };

  i1.addLoadHandler(new LoadHandler() {
    public void onLoad(LoadEvent event) {
      i1.getElement().getStyle().setZIndex(1);
      i2.getElement().getStyle().setZIndex(0);
      loadNext.schedule(1000);
    }
  });

  i2.addLoadHandler(new LoadHandler() {
    public void onLoad(LoadEvent event) {
      i1.getElement().getStyle().setZIndex(0);
      i2.getElement().getStyle().setZIndex(1);
      loadNext.schedule(1000);
    }
  });

  loadNext.schedule(1000);
 }

gwtqueryを使用する場合、コードは明らかに小さくなります。

  // You could change this by base64 data if you use comet/websockets
  final String url = "my_image_url.jpg?";

  final GQuery images = $("<img/><img/>").appendTo(document);
  images.css($$("position: fixed, top: 10px, left: 600px, width: 400px"));

  final Timer timer = new Timer() {
    int c;
    public void run() {
      images.eq(c%2).attr("src", url + c++);
    }
  };

  images.bind("load", new Function(){
    public void f() {
      $(this).css($$("z-index: 1")).siblings("img").css($$("z-index: 0"));
      timer.schedule(1000);
    }
  });

  timer.schedule(1000);
于 2013-04-18T14:36:30.973 に答える