如何在Chrome上实现音频自动播放

141

音频自动播放在Mozilla、Microsoft Edge和旧版Google Chrome中都能正常工作,但由于Google Chrome 67+的自动播放策略更改,它无法工作(请参考链接的博客文章)

他们已经阻止了自动播放(直到符合链接博客文章中指定的特定会话条件)。如何让音频自动播放在Google Chrome 67+中?


28
谷歌这么做太荒谬了。他们简直是在说:“除非用户点击播放音乐,否则你的游戏就没有音乐”,这是不可接受的。我太生气了! - Hobbes
3
@霍布斯 同意。至少应该有例外情况。就像我对另一位发帖者提到的那样,我有一个“音乐”页面,有一个名为“mymusic.html”的站点链接,只能通过明确标记为“我的音乐”的链接/按钮才能进入。某人会去那里听示例音乐并感到惊讶或烦恼是相当荒谬的,特别是还有一个明确的“固定位置”的停止音乐按钮。这个政策是对滥用行为过度反应的例子。 - Randy
6
@Randy,说实话,作为一名音乐人,如果在“音乐”页面上播放采样音乐而没有任何交互,我会感到很烦恼。我期望能看到歌曲列表,选择要听取采样的歌曲,并与之交互以真正听到它。 - Fox
1
@Fox - 我同意你的观点。自从我发表了我的帖子后,我已经删除了所有自动播放代码,即使在支持它或可以欺骗的浏览器上也是如此。最好让访问者掌控。 - Randy
1
这是谷歌的一种反竞争举动。请注意,他们自己的网站免受这些限制,可以自由地自动播放音频,而不需要任何用户交互。 - Enverex
显示剩余2条评论
23个回答

133

解决方案 #1

我在这里的解决方案是创建一个iframe

<iframe src="audio/source.mp3" allow="autoplay" style="display:none" id="iframeAudio">
</iframe> 

同时还需要为非Chrome浏览器添加audio标签

<audio autoplay loop  id="playAudio">
    <source src="audio/source.mp3">
</audio>

并且在我的脚本

  var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
  if (!isChrome){
      $('#iframeAudio').remove()
  }
  else {
      $('#playAudio').remove() // just to make sure that it will not have 2x audio in the background 
  }

解决方案 #2:

还有另一种解决方法,根据@Leonard的建议:

创建一个iframe,不播放任何内容,只是为了在第一次加载时触发自动播放。

<iframe src="silence.mp3" allow="autoplay" id="audio" style="display: none"></iframe>

这是一个好的源头,提供mp3文件silence.mp3

然后轻松播放您的实际音频文件。

<audio id="player" autoplay loop>
    <source src="audio/source.mp3" type="audio/mp3">
</audio>

个人而言,我更喜欢解决方案2,因为它是一种更清洁的方法,不需要过多依赖JavaScript。

更新于2019年8月

解决方案3

作为替代方案,我们可以使用<embed>

对于Firefox 看起来音频自动播放正在工作,所以我们不需要<embed>元素,因为它会创建双倍音频运行。

// index.js
let audioPlaying = true,
    backgroundAudio, browser;
browser = navigator.userAgent.toLowerCase();
$('<audio class="audio1" src="audio.mp3" loop></audio>').prependTo('body');
if (!browser.indexOf('firefox') > -1) {
    $('<embed id="background-audio" src="audio.mp3" autostart="1"></embed>').prependTo('body');
    backgroundAudio = setInterval(function() {
        $("#background-audio").remove();
        $('<embed id="background-audio" src="audio.mp3"></embed>').prependTo('body');
    }, 120000); // 120000 is the duration of your audio which in this case 2 mins.
}

如果您对音频进行了切换,请确保删除创建的<embed>音频元素。

注意:在切换后,由于已删除<embed>元素,<audio>元素将会从头开始播放。

$(".toggle-audio").on('click', function(event) {
    audioPlaying = !audioPlaying;
    $("#background-audio").remove();

    clearInterval(backgroundAudio);
    if (audioPlaying){
        $(".audio1").play();
        // play audio 
    }
    else {
        $(".audio1").pause();
    }

现在请确保隐藏这些<audio><embed>元素。

audio, embed {
    position: absolute;
    z-index: -9999;
}
注意:diplay: nonevisibility: hidden 会使得 <embed> 元素无法工作。

2
静音文件的链接已经失效,所以我在GitHub上找到了其他一些静音文件:https://github.com/anars/blank-audio。我正在使用`1-second-of-silence.mp3`来完成我的项目,但是这个集合中的任何文件都可以使用,我想。 - Travis
34
在Chrome 76版本中似乎出现了故障。 - Shahar 'Dawn' Or
9
是的,这不再起作用了(如果它曾经有效)。 - Yulian
2
听起来这个答案可能会“现在存在安全风险或提供不再有效的代码”。 - showdev
3
过时的解决方案现在已经不再适用。 - xgqfrms
显示剩余4条评论

32

在Chrome浏览器中,有一个非常巧妙的技巧可以使用音频标签的自动播放功能。

添加

<iframe src="silence.mp3" allow="autoplay" id="audio"></iframe>

然而,silence.mp3 只包含了0.5秒的静音。

这个

<audio id="player" autoplay controls><source src="0.mp3" type="audio/mp3"></audio>

Chrome 注意到音频已经播放,并允许在音频标签中自动播放。


15
好的,这个方法虽然可行,但感觉像是利用了一个漏洞,或者至少是意外的行为。我想有人会向谷歌报告这个问题,所以不能指望它能长久有效。不过还是很棒的发现! - Neil Bryson
8
话题有点偏,但你的 silence.mp3 文件相当大,达到了 36.7k。可以试试这个(216 字节)- https://s3-eu-west-1.amazonaws.com/neilbryson.net.random/silence.mp3。 - Neil Bryson
3
silence.mp3的链接失效了。你可以按照这个链接(https://dev59.com/SG435IYBdhLWcg3wrSLN#16714541)自己创建一个。 - idbrii
1
@Toniq 当然,大家不好意思 - https://s3-eu-west-1.amazonaws.com/omegasquadron.neilbryson.net/silence.mp3 - Neil Bryson
11
他们已经注意到了这个问题......在Firefox和Chrome中都不再起作用了。 - Stefan Reich
显示剩余6条评论

25
自 2018 年 4 月起,Chrome 的自动播放策略已更改:
"Chrome 的自动播放策略很简单:
  • 静音自动播放始终被允许。

如果满足以下条件,则允许带声音的自动播放:

  • 用户与该域交互(点击、敲击等)。
  • 在桌面上,用户的媒体参与指数阈值已被触发,即用户之前曾以有声音的方式播放视频。
  • 在移动设备上,用户已将该网站添加到主屏幕。

另外,

  • 顶层框架可以委派自动播放权限给它们的 iframe 以允许带声音的自动播放。
  • "
Chrome 的开发者网站提供更多信息,包括一些编程示例,请访问此处:https://developers.google.com/web/updates/2017/09/autoplay-policy-changes

9
你的意思是说在Chrome浏览器中没有自动播放音频的方式? - Akshay Rathod
1
此外,现在在 Android 的 Chrome 浏览器中有一个权限选项,用户可以选择允许自动播放声音。 - zeta

12

你可以给我发一个 jsfiddle 来说明这个实现吗?这会非常有帮助。 - Vikash
7
不起作用了吗?收到了这个信息:“无法启动AudioContext。必须在页面上的用户手势之后恢复(或创建)。https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio” - thdoan
2
在Mac上使用Chrome 81.0.4044.138进行开发。 - Mosh Feu

11
至少你可以使用这个:
document.addEventListener('click', musicPlay);
function musicPlay() {
    document.getElementById('ID').play();
    document.removeEventListener('click', musicPlay);
}

当用户在页面上任意点击时,音乐开始播放。

同时,它也立即移除了事件监听器,因此如果您使用音频控件,用户可以将其静音或暂停,当他再次点击其他地方时,音乐不会重新开始播放。


我相信这是正确的方向,遵守新政策要求一些用户交互才能播放音乐。我已经将此添加到移动浏览器已经添加的触摸事件中,并添加了一个“有时工作”的onscroll事件。不幸的是,“无play()”策略似乎不允许鼠标滚轮滚动计为用户交互,但我也在努力解决这个问题。问题是,我的页面是一个音乐页面,字面上称为“mymusic.html”,您可以通过一个明确标记为“MUSIC”的按钮进入该页面。因此,如果有一个页面来证明“加载时播放”的合理性,那么这个页面真的应该这样做! - Randy
@Randy 我的情况和你非常相似,我正在开发一个音乐页面并想要实现自动播放。添加自动播放属性的效果非常不稳定 - 相同的代码有时可以工作,但有时又不能。我没有控制台或网络错误。你解决了你的问题吗? - Lazarus Rising
@LazarusRising - 尽管这一切似乎始于手机浏览器,但我注意到新版本的桌面浏览器也开始拒绝自动播放。不过,我必须说,我对需要通过用户交互触发事件来启动音乐感到满意。事实上,即使是我作为页面作者,当我触摸屏幕时,页面上的音乐开始播放,我也开始感到烦恼。我开始看到自动播放被逐渐淘汰的逻辑。而且由于它正在普遍发生,我不觉得我的网站是唯一一个无法做到这一点的网站。 - Randy
2
Chrome 抛出违规错误,强制播放。 - Gabriel Petersson
1
这可以简化为:document.addEventListener('click', function() { document.getElementById('ID').play() }, { once: true }); - Henrik N

5
浏览器由于广告而改变了隐私政策,自动播放视频或音频非常令人讨厌。因此,您可以使用以下代码来欺骗浏览器。
您可以在 iframe 中放置任何静音音频。
<iframe src="youraudiofile.mp3" type="audio/mp3" allow="autoplay" id="audio" style="display:none"></iframe>
<audio autoplay>
    <source src="youraudiofile.mp3" type="audio/mp3">
</audio>

只需添加一个源为.mp3的不可见iframe,并在音频元素之前加入allow="autoplay"。这样,浏览器就会被欺骗以启动任何后续音频文件。或者自动播放未静音的视频。


这似乎不起作用了(再也?) - Alec Jacobson
@AlecJacobson 你测试过了吗?它不再起作用了吗? - Murtaza Hussain

5

点击地址栏上的网站设置,或者复制该地址(localhost),在Chrome设置页面中选择允许声音。


4
您可以按如下方式使用(.autoplay = true;)(在Chrome桌面版上测试通过):
<audio id="audioID" loop> <source src="path/audio.mp3"  type="audio/mp3"></audio>

<script>
var myaudio = document.getElementById("audioID").autoplay = true;
</script>

如果你需要添加停止/播放按钮:

<button onclick="play()" type="button">playbutton</button>
<button onclick="stop()" type="button">stopbutton</button>

<audio id="audioID" autoplay loop> <source src="path/audio.mp3"  type="audio/mp3"> 
</audio>

<script>
var myaudio = document.getElementById("audioID");

function play() { 
return myaudio.play(); 
};

function stop() {
return myaudio.pause(); 
};
</script>

如果您想让停止/播放成为一个单一的按钮:

<button onclick="PlayStop()" type="button">button</button>


<audio id="audioID" autoplay loop> <source src="path/audio.mp3"  type="audio/mp3"> 
</audio>

<script>
var myaudio = document.getElementById("audioID");

function PlayStop() { 
return myaudio.paused ? myaudio.play() : myaudio.pause();
};
</script>

如果你想在同一个按钮上显示停止/播放:
<button onclick="PlayStop()" type="button">Play</button>


<audio id="audioID" autoplay loop> <source src="path/audio.mp3"  type="audio/mp3"> 
</audio>

<script>
var myaudio = document.getElementById("audioID");

function PlayStop() { 
if (elem.innerText=="Play") {
    elem.innerText = "Stop";
}
else {
    elem.innerText = "Play";
}
return myaudio.paused ? myaudio.play() : myaudio.pause();
};`
</script>

在某些浏览器中,音频可能无法正常工作,因此可以尝试在代码之前添加iframe进行解决。
<iframe src="dummy.mp3" allow="autoplay" id="audio" style="display:none"></iframe>

<button onclick="PlayStop()" type="button">Play</button>


<audio id="audioID" autoplay loop> <source src="path/audio.mp3"  type="audio/mp3"> 
</audio>

<script>
var myaudio = document.getElementById("audioID");

function button() { 
if (elem.innerText=="Play") {
    elem.innerText = "Stop";
}
else {
    elem.innerText = "Play";
}
return myaudio.paused ? myaudio.play() : myaudio.pause();
};
</script>

3
似乎在Chrome版本85.0.4183.83(官方版本)(64位)中无法运行。 - MC9000
2
同意之前的评论。在Chrome 90.0.4430.93上无法工作,无法在用户交互之前自动播放DOM加载完成后。 - Jeremie

3

[编辑@2021年9月7日]
最近几天我收到了一些踩的反馈,我想我需要澄清一下:这个解决方案要求用户把鼠标悬停在网页上才能使用。没有办法在Chrome浏览器中自动播放声音,因为这是有意被阻止的。现在互联网上充斥着令人生畏的广告,没有人希望在访问网站时听到来自广告的噪音。

[编辑@2021年12月22日] 我曾经误传了一些不正确的信息
事实证明,一些人没有掌握这种方法的一个重要点。您必须将<body>部分中的所有内容都包含在一个<div>中,如下面的原始描述所述。这在jsfiddle上是行不通的,因为它使用了嵌入的<iframe>文档,这正是Chrome浏览器所要阻止的。

[编辑@2021年12月24日]
事实证明我是个小丑。Chrome浏览器会阻止在用户首次访问不同域名下的页面时自动播放。以下是我制作的一些演示:

  • 如果您通过此链接访问自动播放演示,则会正常工作。
  • 但是,此直接链接不起作用,因为目标域与此页面不同。

[原始]
如果您愿意将整个HTML <body> 都包含在一个 <div> 标签中,这是我的解决方案,适用于Chrome 88.0.4324.104(截至2021年1月23日最新版本)。

首先,在<body>部分的开头添加音频部分以及下面显示的脚本片段:

<audio id="divAudio">
   <source src="music.mp3" type="audio/mp3">
</audio>

<script>
   var vAudio = document.getElementById("divAudio");
   var hasInit = false;
   function playMusic()
   {
      if(!hasInit)
      {
          hasInit = true;
          vAudio.play();
      }
   }
</script>

第二步,将你的整个HTML <body>内容(不包括上面显示的插入代码)用一个虚拟部分<div onmouseover="playMusic()"> 包围起来。如果你的HTML <body>内容已经被全局<div>部分包裹,那么只需要在那个<div>中添加onmouseover="playMusic()"标签即可。
这个解决方案是通过在网页上悬停并触发playMusic()函数,欺骗Chrome“认为”用户已经做了一些事情来播放音频。这个解决方案的好处是,只有当用户浏览该页面时才会播放该音频片段。

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接