BeginnerEngineerBlog
中の人
中の人

【javascript audio ios】iphoneとかipadで音鳴らしたい

公開: 2023-07-05 19:16
更新: 2023-08-26 23:17
770
javascript audio ios
iosで音鳴らしたい時のメモ

こんにちは!

中の人です

最近web上で何かしたら音鳴らすという仕様を実装したとき、androidは鳴るけど、iosでは鳴らないということがありました。

ネットサーフィンしてなんとか実装できたのでメモとして紹介します

20230826追記
githubに公開しました。READMEからデモを試すことができます。
パターン2をデプロイしています。

前提


あくまで私が調べた限りですが、pcもandroidもiosもユーザーからのアクションが一回はないと、音は出せません。(多分)

例えば

<!DOCTYPE html>
<html lang="ja">
    <meta charset="utf-8" />
    <body>
        <script>
            let sound = new Audio("./jump01.mp3");
            sound.load();
            sound.play();
        </script>
    </body>
</html>

このようにwebサイトに訪れたら、問答無用で音を鳴らすというのは、そもそもブラウザで制限がかかっていて音を出すことはできません。


つまり


以下のようにユーザーが意図してボタンを押した際などは、android,ios関係なく音を出すことができます

<!DOCTYPE html>
<html lang="ja">
    <meta charset="utf-8">
    <body>
        <button id="button">音出る</button>
        <script>
            (document.getElementById('button')).addEventListener('click', function(e) {
                e.preventDefault();
                let sound = new Audio("./jump01.mp3");
                sound.load();
                sound.play();
            });
        </script>
    </body>
</html>


そんで?


で、あくまで例ですが、以下のように、ボタン押すけど、音を出す目的でない場合で、別のアクションで音を出すような実装をすると、pc、androidは音出るんですが、iosだと出なくなってしまいます。

<!DOCTYPE html>
<html lang="ja">
    <meta charset="utf-8" />
    <body>
        <button id="button">ある要素を見つけたら音出る</button>
        <script>
            // 👇 ボタン押したら
            (document.getElementById('button')).addEventListener('click', function(e) {
                e.preventDefault();
                // 👇 適当な要素をbody内に埋め込む処理のみ実行
                const body = document.querySelector('body');
                const div = document.createElement('div');
                div.innerText = 'hello';
                div.id = 'hello';
                body.appendChild(div);
            });
            let is_played = false;
            // 👇 htmlを監視して、ボタンで追加された要素があったら音を鳴らす処理
            let interval_id = setInterval(() => {
                if (!is_played) {
                    let hello = document.getElementById('hello');
                    if (hello) {
                        let sound = new Audio("./jump01.mp3");
                        sound.load();
                        sound.play();
                        is_played = true;
                    }
                } else {
                    clearInterval(interval_id);
                }
            }, 1000);
        </script>
    </body>
</html>

音が出ん(´・ω・`)


こうすると鳴る


パターン1


ボタンが押された時にロードしておく

<!DOCTYPE html>
<html lang="ja">
    <meta charset="utf-8" />
    <body>
        <button id="button">ある要素を見つけたら音出る</button>
        <script>
            // 👇 soundを定義
            let sound = null;
            (document.getElementById('button')).addEventListener('click', function(e) {
                e.preventDefault();
                // 👇 ボタンを押した時にloadしちゃう
                sound = new Audio("./jump01.mp3");
                sound.load();

                const body = document.querySelector('body');
                const div = document.createElement('div');
                div.innerText = 'hello';
                div.id = 'hello';
                body.appendChild(div);
            });
            let is_played = false;
            let interval_id = setInterval(() => {
                if (!is_played) {
                    let hello = document.getElementById('hello');
                    if (hello && sound !== null) {
                        // 👇 音出す
                        sound.play();
                        is_played = true;
                    }
                } else {
                    clearInterval(interval_id);
                }
            }, 1000);
        </script>
    </body>
</html>

パターン2


ボタンが押された際に、ミュート(無音)で再生しちゃう

<!DOCTYPE html>
<html lang="ja">
    <meta charset="utf-8" />
    <body>
        <button id="button">ある要素を見つけたら音出る</button>
        <script>
            // 👇 soundを定義
            let sound = null;
            (document.getElementById('button')).addEventListener('click', function(e) {
                e.preventDefault();
                // 👇 ファイルを読み込んでミュートで再生しちゃう
                sound = new Audio("./jump01.mp3");
                sound.load();
                sound.muted = true;
                sound.play();

                const body = document.querySelector('body');
                const div = document.createElement('div');
                div.innerText = 'hello';
                div.id = 'hello';
                body.appendChild(div);
            });
            let is_played = false;
            let interval_id = setInterval(() => {
                if (!is_played) {
                    let hello = document.getElementById('hello');
                    if (hello && sound !== null) {
                        // 👇 再生時間を最初に戻す
                        sound.currentTime = 0;
                        // 👇 ミュートを解除して再生
                        sound.muted = false;
                        sound.play();

                        is_played = true;
                    }
                } else {
                    clearInterval(interval_id);
                }
            }, 1000);
        </script>
    </body>
</html>

iosでも音出たヽ(゚∀゚ )ノ

参考


パターン1は少し不安


私がこの実装をしたときはパターン2でやりました。

パターン1はこの記事書いているとき、色々試してたら、あれ?鳴った。って感じでできたので紹介しましたが、少し不安です。

試してみてうまくいかなかったらパターン2で試してみてください。


終わりに


iosこの野郎嘘ですiphone使ってます最高ですこれいつもありがとうございます全然怒ってないです。
0
0
0
0
通信エラーが発生しました。
【広告】
似たような記事