解決html5 audio iphone,ipd,safari不能自動播放問題

html audio 在iPhone,ipd,safari瀏覽器不能播放是有緣由滴
(在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
    });
}); //綁定事件

 

方式二:html

版權歸做者全部,任何形式轉載請聯繫做者。
做者: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 一下ios

<!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 way</title>
</head>
<body>
    <h1>在 iOS Safari 中僞裝自動播放 HTML5 audio(音樂) 的正確方式</h1>
    <p>核心原理: 經過一個用戶交互事件來主動 play 一下 audio</p>
    <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>
相關文章
相關標籤/搜索