html audio 在iPhone,ipd,safari浏览器不能播放是有原因滴
(在safri on ios里面明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的action就播放的话就会被safri拦截)
(在safri on ios里面明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的action就播放的话就会被safri拦截)
找了很多资料都没有解决,不过最终在国外网站通过翻译解决问题,希望能帮到没有解决此问题的童鞋
附带源码如下:黑色部分表示重点突出
var g_audio = window.g_audio = new Audio(); //创建一个audio播放器 var g_event = window.g_event = new function() { var events = ['load', 'abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting', 'mediachange']; g_audio.loop = false; g_audio.autoplay = true; g_audio.isLoadedmetadata = false; g_audio.touchstart = true; g_audio.audio = true; g_audio.elems = {}; g_audio.isSupportAudio = function(type) { type = type || "audio/mpeg"; try { var r = g_audio.canPlayType(type); return g_audio.canPlayType && (r == "maybe" || r == "probably") } catch(e) { return false; } }; g_audio.push = function(meta) { g_audio.previousId = g_audio.id; g_audio.id = meta.song_id; g_audio.previousSrc = g_audio.src; g_audio.previousTime = 0.00; g_audio.src = g_audio.currentSrc = meta.song_fileUrl; g_audio.isLoadedmetadata = false; g_audio.autobuffer = true; g_audio.load(); g_audio.play(); if (g_audio.previousSrc !== g_audio.src) { g_audio.play(); } }; for (var i = 0, l = events.length; i < l; i++) { (function(e) { var fs = []; this[e] = function(fn) { if (typeof fn !== 'function') { for (var k = 0; k < fs.length; k++) { fs[k].apply(g_audio); } return; } fs.push(fn); g_audio.addEventListener(e, function() { fn.apply(this); }); }; }).apply(this, [events[i]]); } this.ended(function() { //播放结束 }); this.load(function() { //加载 this.pause(); this.play(); }); this.loadeddata(function() { this.pause(); this.play(); }); this.loadedmetadata(function() { this.isLoadedmetadata = true; }); this.error(function() { //请求资源时遇到错误 }); this.pause(function() { //歌曲暂停播放 }); this.play(function() { //歌曲播放 }); }; $$$$(document).ready(function() { if (/i(Phone|P(o|a)d)/.test(navigator.userAgent)) { $$$$(document).one('touchstart', function(e) { g_audio.touchstart = true; g_audio.play(); g_audio.pause(); return false; }); } }); audio使用: $$$$("#main").unbind("click").bind("click", function() { //gid 表示歌曲id,只是一个表示,没有值不影响播放 //song_fileUrl :播放歌曲地址,不能为空,有效地址 g_audio.elems["id"] = gid; g_audio.push({ song_id: gid, song_fileUrl: json.URL }); }); //绑定事件
方式二:
版权归作者所有,任何形式转载请联系作者。
作者:U_U(来自豆瓣)
来源:https://www.douban.com/note/527250492/
ake auto play html audio in iOS Safari the right way
由于 iOS Safari 限制不允许 audio autoplay, 必须用户主动交互(例如 click)后才能播放 audio, 因此我们通过一个用户交互事件来主动 play 一下 audio.
这个坑相信大家都已经踩过了, 在 iOS 9 没出现以前, 这样的 hack 方案还是妥妥的.
但 iOS 9 出现后, 发现这个方案"失效"了.
没有办法, 看来是时候升级一下 hack 方案了, 于是仔细看了下 audio 的事件.
对于能够自动播放时事件的顺序如下
loadstart -> loadedmetadata -> loadeddata -> canplay -> play -> playing
对于不能自动播放时触发的事件因系统版本不同而不同
* iPhone5 iOS 7.0.6 loadstart
* iPhone6s iOS 9.1 loadstart -> loadedmetadata -> loadeddata -> canplay
最终发现相比原来的 hack 方案, 对于 iOS 9 还需要额外的 load 一下, 否则直接 play 不能让 audio 开始播放.
audioEl.load(); // iOS 9
audioEl.play(); // iOS 7/8 仅需要 play 一下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Fake auto play html audio in iOS Safari the right waytitle>
head>
<body>
<h1>在 iOS Safari 中假装自动播放 HTML5 audio(音乐) 的正确方式h1>
<p>核心原理: 通过一个用户交互事件来主动 play 一下 audiop>
<br>
<br>
<br>
<audio id="bgmusic" autoplay preload loop controls>audio>
<script>
(function() {
function log(info) {
console.log(info);
// alert(info);
}
function forceSafariPlayAudio() {
audioEl.load(); // iOS 9 还需要额外的 load 一下, 否则直接 play 无效
audioEl.play(); // iOS 7/8 仅需要 play 一下
}
var audioEl = document.getElementById('bgmusic');
// 可以自动播放时正确的事件顺序是
// loadstart
// loadedmetadata
// loadeddata
// canplay
// play
// playing
//
// 不能自动播放时触发的事件是
// iPhone5 iOS 7.0.6 loadstart
// iPhone6s iOS 9.1 loadstart -> loadedmetadata -> loadeddata -> canplay
audioEl.addEventListener('loadstart', function() {
log('loadstart');
}, false);
audioEl.addEventListener('loadeddata', function() {
log('loadeddata');
}, false);
audioEl.addEventListener('loadedmetadata', function() {
log('loadedmetadata');
}, false);
audioEl.addEventListener('canplay', function() {
log('canplay');
}, false);
audioEl.addEventListener('play', function() {
log('play');
// 当 audio 能够播放后, 移除这个事件
window.removeEventListener('touchstart', forceSafariPlayAudio, false);
}, false);
audioEl.addEventListener('playing', function() {
log('playing');
}, false);
audioEl.addEventListener('pause', function() {
log('pause');
}, false);
// 由于 iOS Safari 限制不允许 audio autoplay, 必须用户主动交互(例如 click)后才能播放 audio,
// 因此我们通过一个用户交互事件来主动 play 一下 audio.
window.addEventListener('touchstart', forceSafariPlayAudio, false);
audioEl.src = 'http://www.w3school.com.cn/i/song.mp3';
})();
script>
body>
html>