2016-12-22 17 views
0

Firefox 49以降では、IPカメラからのMJPEGストリームが社内サービスを使用して最初のフレームでフリーズします。これはChromeでは発生しません。このエラーが発生する可能性のあるFF 49の変更ログに変更が見つかりませんでした。このコードは私のものではなく、古いものですが、まだChromeでうまく動作します。私が考えたコードの 小品は、エラーが発生することがあります:MJPEGストリームがFirefox 49以降の最初のフレームでフリーズ

CameraplayerUI.js 
self.drawStream = function (image) { 
      //#region Argument validation and sanitization 

      if (typeof image === "undefined" || image === null) { return false; } 
      if (typeof image.src === "undefined" || image.src === null) { return false; } 
      if (!image.complete) { return false; } 

      if (_stream.width !== image.width) { _stream.width = image.width; } 

      if (_stream.height !== image.height) { _stream.height = image.height; } 

      //#region Argument validation and sanitization 

      if(_isLive !== true){ 
       _isLive = true; 
       $(_image).hide(); 
       $(_stream).show(); 
      } 

      _ctx.drawImage(image, 0, 0, _stream.width, _stream.height); 
      self.source = image.src; 
      return true; 

/** Mjpegstream.js 
     * Updates the current stream based on the elapsed time since last update. 
     * Warning: Numeric representations for all parameters are used without validation for 
     *   performance considerations. 
     * 
     * @param {Integer} time  - Current time} 
     * @param {Integer} elapsedTime - Elapsed time since last update cycle. 
     */ 
     this.update = function (time, elapsedTime) { 
      if (!self.isOpen) { return false; } 

      //#region Argument validation and sanitization 

      time = +time; // Unary plus operation. Numeric representation. 
      elapsedTime = +elapsedTime; // Unary plus operation. Numeric representation. 

      //#endregion Argument validation and sanitization 

      _serviceReauthenticationTimer = _serviceReauthenticationTimer - elapsedTime; 
      if (_serviceReauthenticationTimer <= 0) { 
       downloadAsync(_userId, _userKey, this.cameraId, update_callback); 
      } 

      // Firefox MJPEG stream fix. 
      if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { 
       if (this.data !== "undefined" && this.data !== null) { 

        self.data.src = _stream.src; 

       } 
      } 

      return true; 
     }; 

Cameraplayer.js 
if (self.isLive) { 
       _time = now; 
       ui.setTime(_time); 

       if (!_mjpegStream.isAuthenticated) { 
        ui.showAuthenticationNotification(false, _mjpegStream.error); 
        self.hasError = true; 
       } else if (_mjpegStream.error !== null) { 
        ui.showError(true, _mjpegStream.error); 
        self.hasError = true; 
       } else if (_mjpegStream.isOpen) { 
        ui.clearNotifications(); 
        if (_mjpegStream.isPlaying) { 
         if (_mjpegStream.update(_time, elapsedTime)) { 
          ui.drawStream(_mjpegStream.data); 
         } 
        } else { 
         _mjpegStream.play(); 
        } 
       } else if (_mjpegStream.isConnecting) { 
        ui.showLoading(true); 
        return false; 
       } else { 
        ui.showLoading(true); 
        _mjpegStream.open(_request); 
        return false; 
       } 
      } else { 
       _time = time; 

は、このプログラムは巨大であると私はちょうど私がエラーを引き起こす可能性が考えスニペットを取った覚えておいてください。 49より前、現在ChromeのすべてのFirefoxバージョンで動作します。

答えて

0

chrome bugに依存しています。 specsによれば

... when a CanvasImageSource object represents an animated image in an HTMLOrSVGImageElement, the user agent must use the default image of the animation (the one that the format defines is to be used when animation is not supported or is disabled), or, if there is no such image, the first frame of the animation, when rendering the image for CanvasRenderingContext2D APIs.

MJPEGストリームはこれらアニメーション画像の一部であり、したがって、UAは最初のフレームのみを返さなければなりません。最近Chromeがこの仕様に準拠しましたが、GIF画像の場合はのみです。

したがって、それぞれの再描画時にリクエスト内にランダムなパラメータを追加することで、MJPEGストリームの完全なリロードを強制するという回避策がありますが、MJPEG形式のすべての利点を失い、 。

var url = 'http://webcam.st-malo.com/axis-cgi/mjpg/video.cgi?resolution=352x288'; 
 

 
var img = new Image(); 
 
img.onload = drawAndReload; 
 
// check if there are already parameters in the passed url 
 
var paramHead = url.indexOf('?') > 0 ? '&' : '?'; 
 
img.src = url; 
 
var ctx = c.getContext('2d'); 
 

 
function drawAndReload(){ 
 
    if(c.width !== this.naturalWidth){ 
 
    c.width = this.naturalWidth; 
 
    c.height = this.naturalHeight; 
 
    } 
 
    ctx.drawImage(this, 0, 0); 
 
    // reset the image 
 
    this.src = ''; // should not be necessary 
 
    this.src = url + paramHead + Math.random(); // force no-cache 
 
    }
<canvas id="c"></canvas>

真の解決策は、あなた」、あなたのMJPEGストリームはチャンクをフェッチし、HTMLVideoElementに表示しMediaSource APIを使用し、その後、ビデオストリームのサーバ側に変換することです制限なくキャンバス上に描画することができます。

関連する問題