DOMException: play() can only be initiated by a user gesture

后端 未结 4 1490
Happy的楠姐
Happy的楠姐 2020-12-10 00:54

I\'m working on a QRCode Reader with JavaScript. If a user is on my website, it asks for permission to use the device camera. As soon the user acce

相关标签:
4条回答
  • 2020-12-10 01:23

    This might help.

    webViewSettings.setMediaPlaybackRequiresUserGesture(false);
    
    0 讨论(0)
  • 2020-12-10 01:23

    To whom all that having and trying to solve this autoplay problem; it's a bit late maybe but I figured out how to solve this issue, after making few experiments. I was trying to create an endless loop for a sound which starts after play button and I wasn't wanting it with HTML autoplay attribute which was creating gap while it was repeating. Then I figured out that if i create an <audio> tag twice with same sound src and then i could setTimeout(function); to start the second one just after the end of the first and this would be a loop. This is where i faced with this play() DOMException. In desktop it was flawless but on mobile it was stopping because it was needing a gesture. Then I found out that if you play() the audio with gesture for 1 time then you would be able to pause() set currentTime = 0; and then play() again without user gesture. The code below creates an endless loop for mobile and desktop without any problem.

    Here is the 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);
      }
    });
    
    0 讨论(0)
  • 2020-12-10 01:36

    I found a simpler solution.

    <button #notificationSound (click)=" _notifService.initAudio()" hidden></button>
    
    initAudio() {
        const audio = new Audio('./../assets/audio/notification.mp3');
        audio.muted = true
        audio.play();
    }
    

    And you should be good after this initialization. You can attach this to a body mouseover too and that will count as a gesture.

    0 讨论(0)
  • 2020-12-10 01:40

    This probably has to do with the trusted security model. Certain operations are only allowed if they're initiated by the user. This is for instance how a lot of popup blockers work. Likewise Chrome may want to protect users against auto-playing videos.

    Make sure you call videoElement.play() in an event handler that is associated to a gesture.

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

    Since your function is called in navigator.getUserMedia it would seem strange to ask for user input again. Have you tried using autoplay on the video element?

    0 讨论(0)
提交回复
热议问题