简体   繁体   中英

Which events are acceptable for starting HTML5 audio play in mobile Chrome

Mobile browsers require user action to start play on Audio elements. The click event satisfies the requirement, but it appears that touchstart is not an acceptable initiating event in Chrome on Android or iOS. (See below)

Does anyone know where to find a precise definition of the event context required to start play.

(I was attempting to solve a UX problem using the ideas in How to prevent doubletap zoom in iOS and Android . Since posting my original question, I've found a solution that solves the UX problem without using touchstart , but I think the essential question about which events are considered to be user action is still valid.)

Addendum:

It has been suggested that I am mistaken about touchstart events, so for the record, I am providing a trivial test program. Since it requires a real music file and a mobile device, JSFiddle isn't a suitable platform (unless somebody knows how to simulate a touchstart event in a fiddle). To reproduce my observations, edit the javascript to load your own audio file.

<!DOCTYPE html>
<html>
<body>

<br>
<button type="button" id="but1">click</button>
<button type="button" id="but2">touch</button>
<br>
<br>
<span id="message"></span>

<script>

var e;

e = document.getElementById('but1');
e.onclick = click;
e = document.getElementById('but2');
e.ontouchstart = touchstart;

function click() {
  alert('caught click');
  play();
  event.preventDefault();
}

function touchstart() {
  alert('caught touchstart');
  play();
  event.preventDefault();
}

var p;
var t;

function play() {

  p = new Audio();
  p.src = '/k487.mp3';      //  CHANGE THIS
  p.preload = 'auto';
  p.play();

  t = setInterval(report,1000);
}

function report() {

  var s = 'Player readyState='+p.readyState+', currentTime='+p.currentTime;
  var e = document.getElementById('message');

  e.innerHTML = s;
}

</script>
</body>
</html>

When I load this page in Chrome 58 on Android 6.0.1 the Click button works as expected, producing a popup, playing some music and updating the play time.

If I reload the page and touch the Touch button instead, I get the popup, but no music plays. The status display shows a readyState of 4 and a currentTime of 0. In other words, the touchstart event is permitted to load the audio but not to initiate play.

Since I can find no documentation on what events are meant to work, I don't know whether to consider this a Chrome bug, or intended behaviour.

In this page you will found answer on this question .

Use some popup or any animation nice for eye to attract user for tap .

in my memory ... android and iOS have no same behavior it is about max number of audios that we can start buffer with this trick .

    var EXE_JUST_ONE_TIME = false;

    document.addEventListener("touchstart" , function(e) {

    if (EXE_JUST_ONE_TIME == false){
    EXE_JUST_ONE_TIME = true;

    document.getElementById("LaserShot").play(); // need for play pause just for buffering start
    document.getElementById("LaserShot").pause();
    // now you can play programmability from js 
    document.getElementById("LaserShot_CLONE").play();
    document.getElementById("LaserShot_CLONE").pause();

    }
  else if(EXE_JUST_ONE_TIME = true){

    document.getElementById("MakeReadyotherAudio1").play();
    document.getElementById("MakeReadyotherAudio1").pause();

     EXE_JUST_ONE_TIME = 'NOMORE'

  } 


    }

If you have problems i can make you code snippet with working example !

I put in 90% in mobile web dev in event function on begin :

   document.getElementById("myAnchor").addEventListener("click", function(event){
    event.preventDefault()
});

//Sometimes even if you dont use some event its good to override :

  window.addEventListener('touchstart', function(e){
      e.preventDefault()

    }, false)

    window.addEventListener('touchmove', function(e){
        e.preventDefault()

    }, false)

    window.addEventListener('touchend', function(e){    
        e.preventDefault()


    }, false)

    window.addEventListener('touchleave', function(e){    
        e.preventDefault()


    }, false)
    window.addEventListener('touchcancel', function(e){    
        e.preventDefault()


    }, false)
    window.addEventListener('touchenter', function(e){    
        e.preventDefault()


    }, false)

If you wanna you can use this library : desktop/mobile event optimise for canvas

When the play() method on a media element is invoked, the user agent must run the following steps https://html.spec.whatwg.org/multipage/media.html#dom-media-play

step1: if the media element is not allowed to play...

then I wonder the condition that allowed to play, it jump to here https://html.spec.whatwg.org/multipage/media.html#allowed-to-play

it says:

For example, a user agent could require that playback is triggered by user activation, but an exception could be made to allow playback while mute

then came to 'triggered-by-user-activation' here I think that's the reason:

An algorithm is triggered by user activation if any of the following conditions is true:

The task in which the algorithm is running is currently processing an activation behavior whose click event's isTrusted attribute is true.

  • change
  • click
  • contextmenu
  • dblclick
  • mouseup
  • pointerup
  • reset
  • submit
  • touchend

'touchstart' is not mentioned there.

hope that helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM