iPhone/iPad 等行動裝置上的 audio 標籤無法自動播放 (autoplay) 與預載 (preload) 的問題

Standard

即將上線的 Case 花了不少時間在調校手機網頁與電腦網頁互動的工作,是使用 Nodejs 來達成,但這篇講的主題跟 Nodejs 無關,而是在製作手機版網頁時用到 audio 標籤用以播放音效所遇到的問題。

 

情況描述:Case 中有個互動效果是當使用者開啟手機版網頁後,會進行互動並播放 GIF 動畫(噢,許多舊版本的 Android 裝置是無法播放 GIF 動畫的,這點也要提一下),動畫播放過程中會播放音效。

在 Android 的內建瀏覽器中可自動播放音效,但在 Android 的 Chrome Beta 與 iPhone/iPad 上的 Safari 卻無法正常播放,一點聲音也沒有。而且在桌上型電腦上都可正常地播放。

 

為什麼呢?

後來查到 Safari 官方的規範文件 Safari HTML5 Audio and Video Guide 中提到:

User Control of Downloads Over Cellular Networks

In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad=”play()” event does not.

This plays the movie: <input type=”button” value=”Play” onClick=”document.myMovie.play()”>

This does nothing on iOS: <body onLoad=”document.myMovie.play()”>

這是為了防止使用者使用以量計費的行動網路時,自動播放或預載就會不知不覺地花去網路費用。

除非這個播放是使用者「主動」點擊觸發的,不然設什麼屬性都不會自動播放/預載。

能了解它們的立場,是立意良好啦,但在製作一些需要互動體驗的效果上就會受此限制了。跟此篇作者最後的看法一樣,為何不跳出選項(像要求存取 GPS 一樣)讓使用者自由選擇是否要預載/播放聲音呢?

在我的 Case 中,確實是在使用者「主動觸發」,不過是在觸發播放 GIF 動畫後「一段時間」( 我是用 setTimeout 或是 Nodejs 的偵聽來等待 ) 才會播放聲音,那一樣會被判定為「非使用者主動點擊」。

解法有點取巧,就是「先 play 再 pause,接著再 play 」。

Code 如下:

<!DOCTYPE html>

<html>
<head runat="server">
    <meta charset="UTF-8" />
    <title>測試 audio 標籤於行動裝置瀏覽器能否播放</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="author" content="patw, Patrick Wang" />
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                $("#sound_laugh")[0].play();
            });

            function playsound()
            {
                $("#sound_laugh")[0].play();
                $("#sound_laugh")[0].pause();

                setTimeout(function(){
                    $("#sound_laugh")[0].currentTime = 0;
                    $("#sound_laugh")[0].play();
                }, 2000);
            }
        </script>
</head>

<body>

    <audio id="sound_laugh" preload="auto" controls="controls">
      <source src="sound/laugh.mp3">
    </audio>

    <p><input type="button" value="播放吧~" style="width:200px;height:100px;font-size:16pt;" onclick="javascript:playsound();" /></p>

</body>
</html>

主要是 playsound() 這個 function 裡面的 code 啦。
測試過其實用 load() 方法來代替 play() & pause() 也可以,只是在按第二次 playsound 按鈕時會無法再播放一次。
這段 code 在 Android & iPhone (iOS 5.1) & iPad (iOS 4.3.3) 上測試過都可正常播放。

順帶一提,$(document).ready() 中的這段播放音樂 code,在桌上型電腦、Android 內建瀏覽器上都可以在網頁載入後自動播放的,也許是設計規範上的不同吧。

OK,這篇就這樣囉。
行動版網頁的製作上許多眉眉角角,除了聲音外還有很多需要注意的細節哩。

2 thoughts on “iPhone/iPad 等行動裝置上的 audio 標籤無法自動播放 (autoplay) 與預載 (preload) 的問題

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *