2016-08-05 8 views
16

JavaScriptを使用したQRコードリーダーで作業しています。 ユーザが私のWensiteにいる場合、カメラの使用を許可するかどうかを尋ねます。ユーザーがそれを受け入れるとすぐに、それは仲間のcamaraをオンにします。私は最新のChromeバージョンでSamsung Galaxy S4を使用していますが、これまでのところうまくいきます。DOMException:play()はユーザージェスチャーによってのみ開始されます

私は、フロントからリアに変更するドロップダウンを追加しました。 すぐに私はカメラを変更するビデオストリームが停止し、私はこのエラーが発生します。

未知(約束)DOMException:play()は、 ユーザジェスチャによってのみ開始できます。

古いバージョンのChromeで試したところ、camareの変更でもうまくいきました。

  var videoElement = document.createElement("video"); 
      var videoSelect = document.querySelector("select#videoSource"); 

      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; 

      function start() { 
       if (window.stream) { 
       videoElement.src = null; 
       window.stream.stop(); 
       } 
       var videoSource = videoSelect.value; 
       var tw = 640 // 320 // 640 // 1280; 
       var th = 480 // 240 // 480 // 720 

       var hdConstraints = { 
       audio: false, 
       video: { 
        mandatory: { 
          maxWidth: tw, 
          maxHeight: th 
         }, 
        optional: [{ 
         sourceId: videoSource 
        }] 
       } 
       }; 
       if (navigator.getUserMedia) { 
       navigator.getUserMedia(hdConstraints, success, errorCallback); 
       } else { 
        errorCallback(""); 
       } 
      } 

      videoSelect.onchange = start; 
      start(); 

      function gotSources(sourceInfos) { 
       for (var i = 0; i !== sourceInfos.length; ++i) { 
       var sourceInfo = sourceInfos[i]; 
       var option = document.createElement("option"); 
       option.value = sourceInfo.id; 

       if (sourceInfo.kind === "video") { 
        option.text = sourceInfo.label || "camera " + (videoSelect.length + 1); 
        videoSelect.appendChild(option); 
       } else { 
        console.log("Some other kind of source: ", sourceInfo); 
       } 

       } 
      } 

      if (typeof MediaStreamTrack === "undefined") { 
       alert("This browser does not support MediaStreamTrack.\n\nTry Chrome."); 
      } else { 
       MediaStreamTrack.getSources(gotSources); 
      } 

      function errorCallback(e) { 
       console.log("Cant access user media", e); 
      } 

      function success(stream) { 

       window.stream = stream; 
       videoElement.src = window.URL.createObjectURL(stream); 
       videoElement.onclick = function() { videoElement.play(); }; 
       videoElement.play(); //Here is the Error 


       function getFrame() { 
        requestAnimationFrame(getFrame); 

        if (!videoElement.videoWidth) return; 

        if (!image) { 
         width = videoElement.videoWidth, height = videoElement.videoHeight; 
         log("videoElement", width, height, videoElement); 

         var canvas = document.createElement("canvas"); 
         canvas.width = width; 
         canvas.height = height; 
         canvas.style.transform = "scale(1, 1)"; 

         ctx = canvas.getContext("2d"); 
         document.body.appendChild(canvas); 

         log("start"); 
         image = Module._xsetup(width, height); 
         log("_xsetup", image, "pointer"); 
         return; 
        } 

        ctx.drawImage(videoElement, 0, 0, width, height); 
        var imageData = ctx.getImageData(0,0, width, height); 
        data = imageData.data; 
        gofill(); 
       } 

       getFrame(); 

}

答えて

11

これはおそらく、信頼できるセキュリティモデルに関係しています。特定の操作は、ユーザーによって開始された場合にのみ許可されます。これは、ポップアップブロッカーの多くがどのように機能するかなどです。同様にChromeは、ユーザーをビデオの自動再生から保護したい場合があります。

ジェスチャーに関連付けられているイベントハンドラーでvideoElement.play()に電話してください。あなたの関数がnavigator.getUserMediaで呼び出されているので

// this should be ok 
videoElement.addEventListener("click", function() { 
    videoElement.play(); 
}); 

// this is not ok 
setTimeout(function() { 
    videoElement.play(); 
}); 

再びユーザの入力を求めることを奇妙に思えるでしょう。 video要素でautoplayを使用しようとしましたか?

+0

はまだ動作しません。 Video要素が黒いフィールドに変わります。私が知っているように、ユーザーの帯域幅を節約するために自動再生はGoogleから無効になっています。奇妙なことは古いバージョンにあります。それは私に、変更に関するcamaraの許可も求めました。最新のバージョンではそうではありません。私の場合は – Ovoxo

+0

で、Android用Chromeでは「クリック」は呼び出されません。タッチスクリーンで機能する唯一のイベントタイプは、 "touchstart"または "touchend"です。残念ながら、これらのイベントでは同じDOMExceptionが返されます。 Androidはtouchstart/touchendをユーザージェスチャーとして扱わないようです。 – mchiasson

2

この自動再生の問題を解決しようとしているすべての人。おそらく多少遅れているかもしれませんが、私はいくつかの実験をした後、この問題を解決する方法を考え出しました。私は再生ボタンの後に始まるサウンドの無限ループを作成しようとしていましたが、繰り返されている間にギャップを作り出していたHTML autoplay属性でそれを望みませんでした。それで、もし私が同じ音でを2度入れて<audio>タグを作ったら、setTimeout(function);は最初の終わりの直後に2番目のものを開始することができ、これはループになります。これは私がこのplay() DOMExceptionに直面したところです。デスクトップでは完璧でしたが、モバイルではジェスチャーが必要だったので停止していました。その後、あなたがplay()のジェスチャーを1回鳴らすと、pause()currentTime = 0;に設定し、次にplay()をユーザジェスチャーなしで再設定できることがわかりました。以下のコードは、モバイルとデスクトップのための無限ループを作成します。ここで

DEMO

HTML

<audio id="rain" src="https://www.soundjay.com/nature/sounds/water-dripping-1.mp3" preload="auto"> 
</audio> 
<audio id="rainloop" src="https://www.soundjay.com/nature/sounds/water-dripping-1.mp3" preload="auto"> 
</audio> 
<button> 
    Rain 
</button> 
<div id="slider"></div> 

あるJS

$(document).ready(function(){ 
    var interloop; 
    var aud = document.getElementById("rain"); 
    var audloop = document.getElementById('rainloop'); 
    var wplay = aud; 
    $('button').click(function(){ 
    if(aud.paused && audloop.paused){ 
     audloop.play(); 
     audloop.pause() 
     audloop.currentTime = 0; 
     looper(); 
    } else { 
     aud.pause(); 
     aud.currentTime = 0; 
     audloop.pause(); 
     audloop.currentTime = 0; 
     clearInterval(interloop); 
    } 
    }); 

    function looper(){ 
     wplay.play(); 
     if(wplay == aud){ 
     wplay = audloop; 
     } else { 
     wplay = aud; 
     } 
    interloop = setTimeout(looper, 4600); 
     } 

    $('#slider').slider({ 
    value: 100, 
    slide:changevolume, 
    stop:changevolume 
    }); 

    function changevolume(){ 
    var val = $('#slider').slider('value'); 
    aud.volume = (val/100); 
    audloop.volume = (val/100); 
    } 
}); 
関連する問題