Android 除非手动触发一次,否则 HTML5 音频无法通过 Javascript 播放

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12206631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:00:56  来源:igfitidea点击:

HTML5 Audio can't play through Javascript unless triggered manually once

javascriptandroidhtmlhtml5-audio

提问by Jonah H.

I'm trying to get a small sound file to play automatically using an tag and javascript to initiate it.

我正在尝试使用标签和 javascript 来启动一个小声音文件来自动播放。

<audio id="denied" preload="auto" controls="false">
    <source src="sound/denied.wav" />
 </audio>

And then through javascript, at the appropriate time:

然后在适当的时候通过 javascript:

$('#denied')[0].play()

Works fine on Chrome on my desktop. In Android 4.1.1, the sound will not play, unless I hit "play" on the HTML5 audio controls before javascript attempts to play it.

在我桌面上的 Chrome 上运行良好。在 Android 4.1.1 中,声音不会播放,除非我在 javascript 尝试播放之前在 HTML5 音频控件上点击“播放”。

So basically the Android browser (stock or Dolphin) will not play the audio unless the user initiates it at some point before the javascript. Is this intended? Is there any way around this?

所以基本上Android浏览器(股票或海豚)不会播放音频,除非用户在javascript之前的某个时间启动它。这是故意的吗?有没有办法解决?

采纳答案by Jonah H.

Well, for my purposes, here's what I did:

好吧,就我的目的而言,这就是我所做的:

Luckily, before the user can trigger the behavior to start audio, they have to click a button. I set the volume of the element to 0.0, and have it "play" when they click this button.

幸运的是,在用户触发行为以开始音频之前,他们必须点击一个按钮。我将元素的音量设置为 0.0,并在他们单击此按钮时让它“播放”。

After the sound is played silently, I simply set the volume property back to 1.0, and it plays without user intervention just fine.

静音播放后,我只需将音量属性设置回 1.0,它就可以在没有用户干预的情况下正常播放。

回答by FRa

In my case this was an easy solution:
https://stackoverflow.com/a/28011906/4622767
Copy & paste this in your chrome:

就我而言,这是一个简单的解决方案:
https: //stackoverflow.com/a/28011906/4622767
将其复制并粘贴到您的 chrome 中:

chrome://flags/#autoplay-policy

My web app has many page reload so I can't force the user to press a button every time; but it is for internal usage, so I can force the users to use chrome and configure that option.

我的网络应用程序有很多页面重新加载,所以我不能强迫用户每次都按下按钮;但它是供内部使用的,因此我可以强制用户使用 chrome 并配置该选项。

回答by Rob Lynch

I know that in mobile safari any javascript call to play() must be in the same call stack as a userinitialted click event. Spoofing the the click with a javascript trigger won't work either.

我知道在移动 safari 中,任何对 play() 的 javascript 调用都必须与用户初始化的点击事件在同一个调用堆栈中 。使用 javascript 触发器欺骗点击也不起作用。

On my nexus 7 I can confirm that unless the javascript was triggered by a user click, it does not play.

在我的 nexus 7 上,我可以确认除非 javascript 是由用户点击触发的,否则它不会播放。

回答by Eli Mashiah

The main issue is that sound (on iOS and Android) must be triggered by a user click. My workaround was very simple. Tie the audio.play()to a click event listener and then immediately pause it. From that point and on the sound works perfect.

主要问题是声音(在 iOS 和 Android 上)必须由用户点击触发。我的解决方法非常简单。将 绑定audio.play()到单击事件侦听器,然后立即暂停它。从那时起,声音就完美无缺了。

var myAudio = new Audio('assets/myAudio.mp3');
...
button.addEventListener("click", function() {
    myAudio.play();
    myAudio.pause();
    ...
});

回答by makechaos

Here is a blog-post on the reason and how to overcome it by loading all the audio files on first user interaction and play them later in programmed manner: https://blog.foolip.org/2014/02/10/media-playback-restrictions-in-blink/Adopting this approach a small javascript module is available on GitHub https://github.com/MauriceButler/simple-audio

这是一篇关于原因以及如何通过在第一次用户交互时加载所有音频文件并稍后以编程方式播放它们来克服它的博客文章:https: //blog.foolip.org/2014/02/10/media- play-restrictions-in-blink/采用这种方法,GitHub 上提供了一个小的 javascript 模块https://github.com/MauriceButler/simple-audio

I tried this simple approach on my own - worked seamlessly & great!

我自己尝试了这种简单的方法 - 无缝工作且很棒!

回答by MaKR

Luckily for me the html5 app I'm working on only needs to work in Android 4.1, but if you're trying to make something cross-platform you'll need to adapt this slightly. Neither setting volume to 0.0 then back or autoplay on the control worked for me. I also tried muted and that didn't work either. Then I thought, what if I set the duration and only play a miniscule amount of the file? Here's yet another hacked-together script that actually did work:

对我来说幸运的是,我正在开发的 html5 应用程序只需要在 Android 4.1 中运行,但是如果您正在尝试制作跨平台的东西,则需要稍微调整一下。将音量设置为 0.0 然后返回或在控件上自动播放都不适合我。我也试过静音,但也没有用。然后我想,如果我设置持续时间并且只播放极少量的文件怎么办?这是另一个实际工作的黑客脚本:

function myAjaxFunction() {
  clearTimeout(rstTimer); //timer that resets the page to defaults
  var snd=document.getElementById('snd');
  snd.currentTime=snd.duration-.01; //set seek position of audio near end
  snd.play(); //play the last bit of the audio file
  snd.load(); //reload file
  document.getElementById('myDisplay').innerHTML=defaultDisplay;
  var AJAX=new XMLHttpRequest(); //won't work in old versions of IE
  sendValue=document.getElementById('myInput').value;
  AJAX.open('GET', encodeURI('action.php?val='+sendValue+'&fn=find'), true);
  AJAX.send();
  AJAX.onreadystatechange=function() {
    if (AJAX.readyState==4 && AJAX.status==200) {
      document.getElementById('myDisplay').innerHTML=AJAX.responseText;
      if (document.getElementById('err')) { //php returns <div id="err"> if fail
        rstTimer = setTimeout('reset()', 5000); //due to error reset page in 5 seconds
        snd.play(); //play error sound
        document.getElementById('myInput').value=''; //clear the input
      }
    }
  }
}

回答by aesede

You don't need JavaScript for autoplay, and I see several issues in your code:

自动播放不需要 JavaScript,我在您的代码中看到了几个问题:

<audio id="denied" preload="auto" controls="false">
    <source src="sound/denied.wav" />
</audio>

I'd change it to (in HTML5 you don't need attribute="value" syntax in some cases, that's for XHTML):

我将其更改为(在 HTML5 中,在某些情况下您不需要 attribute="value" 语法,这是针对 XHTML 的):

<audio id="denied" autobuffer controls autoplay>
    <source src="sound/denied.wav" />
</audio>
<a href="#" id="play-button">play!</a>

In iOS autoplay is disabled, you need to click play button or put a userclick event on custom controls like this with JavaScript:

在禁用 iOS 自动播放时,您需要单击播放按钮或使用 JavaScript 在自定义控件上放置用户单击事件:

var audio = document.getElementById('denied');
var button = document.getElementById('play-button');
button.addEventListener('click',function(){
    audio.play();
});

or with jQuery:

或使用 jQuery:

$('#play-button').click(function(){ audio.play(); });}

Edit

编辑

Keep in mind that HTML5 is pretty recent technology (at least some functionalities), so browser compatibility and functionality changes every once in a while.

请记住,HTML5 是相当新的技术(至少是某些功能),因此浏览器兼容性和功能每隔一段时间就会发生变化。

I encourage everybody to keep informed about the current status, as sometimes things start to be less hack-dependant, or the other way around.

我鼓励每个人都了解当前状态,因为有时事情开始不那么依赖黑客,或者相反。

A good starting point: http://caniuse.com/#feat=audio(check the tabs at the bottom).

一个好的起点:http: //caniuse.com/#feat=audio(检查底部的选项卡)。

Also for a global audio solution I recommend using SoundManager2JS library

同样对于全局音频解决方案,我建议使用SoundManager2JS 库

回答by Marks

It happened to me too. Here's how I hacked this:

它也发生在我身上。这是我如何破解这个:

I set the audio to autoplayand set the vol to 0. When I need it to play, I use the load()method and it will autoplay. It's a light mp3 file and it plays every one hour/two hour, so this works fine for me.

我将音频设置为 并将音量autoplay设置为0。当我需要它播放时,我使用该load()方法,它会自动播放。这是一个轻量级的 mp3 文件,每隔一小时/两小时播放一次,所以这对我来说很好用。

回答by Lubo? Mi?atsky

I met the same problem in my app. My application usage scenario was like this:

我在我的应用程序中遇到了同样的问题。我的应用使用场景是这样的:

  1. click the button to show a table with information (user action)
  2. show the table and refresh data in it by AJAX
  3. play sound when data has been changed
  1. 单击按钮以显示包含信息的表格(用户操作)
  2. 通过 AJAX 显示表格并刷新其中的数据
  3. 数据更改时播放声音

Fortunately I had the user action (step 1) so I was able to "initiate" the sound by it and then play it by javascript without the user action needed. See the code.

幸运的是,我有用户操作(第 1 步),因此我能够通过它“启动”声音,然后通过 javascript 播放它,而无需用户操作。查看代码。

HTML

HTML

<audio id="kohoutAudio">
    <source src="views/images/kohout.mp3">
</audio>

<button id="btnShow">Show table</button>

Javascript

Javascript

$("#btnShow").click(function () {
    //some code to show the table
    //initialize the sound
    document.getElementById('kohoutAudio').play();
    document.getElementById('kohoutAudio').pause();
});

function announceChange(){
    document.getElementById('kohoutAudio').play();
};