iOS howler.js is not working 音量が変わらない 復帰時に音が鳴らない


## 環境

| 名称 | バージョン |
|:-:|:-:|
|howler.js|2.2.4|
|iOS|18.1.1|
|Google Chrome|133.0.6943.120|

issueを見た感じ、Safariでも同じバグがありそうだが、面倒くさいので確認しない。

## 例で使うコード

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>実験</title>
  <script src="https://cdn.jsdelivr.net/npm/howler@2.2.4/dist/howler.min.js"></script>
</head>
<body>
  <button id="sound">再生</button>
  <script src="main.js"></script>
</body>
</html>
```

```js
let sound = null;
const $sound = document.querySelector("#sound");

// 再生ボタンがクリックされたときはBGMを再生する
$sound.addEventListener("click", async () => {
    sound?.stop();
    if (sound === null) {
        sound = await createSound({
            src: "bgm.mp3",
            volume: 1,
            html5: true,
        });
    }
    sound.play();
});

// ページが非表示になったときはBGMを停止する
document.addEventListener("visibilitychange", () => {
    if (document.hidden) {
        sound?.stop();
    }
});

// Howlオブジェクトの生成
function createSound(option) {
    const sound = new Howl(option);
    return new Promise((resolve, reject) => {
        sound.once("load", () => {
            resolve(sound);
        });
        sound.once("loaderror", () => {
            reject();
        });
    })
}
```

## バグ1. 音量が変わらない

```js
sound = await createSound({
    src: "bgm.mp3",
    volume: 0.1,
    html5: true,
});
```

と、`volume`の値を変えても音量が変わらない。

### 解決方法

`html5`を`false`に変える。

```js
sound = await createSound({
    src: "bgm.mp3",
    volume: 0.1,
    html5: false,
});
```

`html5`が`true`のまま音量を変える方法は分からない。
というか、[無理っぽい。](https://github.com/goldfire/howler.js/issues/1237#issuecomment-997471838)

### 参考元

https://github.com/goldfire/howler.js/issues/1691

https://github.com/goldfire/howler.js/issues/1237#issuecomment-997471838

## バグ2. 音が鳴らない

`html5`が`false`のとき
画面を非表示してから（タブを変える、スマホをスリープさせるなど）再表示して、再生ボタンを押しても音が鳴らない。

:::note warn
`html5`が`true`のときは、問題なく音が鳴る。
:::

```js
sound = await createSound({
    src: "bgm.mp3",
    volume: 1,
    html5: false,
});
```

### 解決方法

分からない（絶望）

`unload()`すればいいみたいな情報があったので試したところ、

スリープさせて再度再生 → 音が鳴る
更にスリープさせて再度再生 → 音が鳴らない（絶望）

となったため、完璧な解決方法ではない模様。

<details><summary>unload()</summary>

```js
let sound = null;
const $sound = document.querySelector("#sound");

// 再生ボタンがクリックされたときはBGMを再生する
$sound.addEventListener("click", async () => {
    sound?.stop();
    if (sound === null) {
        sound = await createSound({
            src: "bgm.mp3",
            volume: 1,
            html5: false,
        });
    }
    sound.play();
});

// ページが非表示になったときはBGMを停止する
document.addEventListener("visibilitychange", () => {
    if (document.hidden) {
        sound?.stop();
        sound?.unload();
    }
    else {
        sound = null;
        Howler.unload();
    }
});

// Howlオブジェクトの生成
function createSound(option) {
    const sound = new Howl(option);
    return new Promise((resolve, reject) => {
        sound.once("load", () => {
            resolve(sound);
        });
        sound.once("loaderror", () => {
            reject();
        });
    })
}
```

</details>

### 追記

これで直せる？？？？？？？？

https://github.com/goldfire/howler.js/issues/1753

### 参考元

https://github.com/goldfire/howler.js/issues/1526#issuecomment-1025686332

### 関連してそう

https://qiita.com/okaxaki/items/c807bdfe3e96d6ef7960#ios%E3%81%A7safari%E3%82%92%E3%83%90%E3%83%83%E3%82%AF%E3%82%B0%E3%83%A9%E3%82%A6%E3%83%B3%E3%83%89%E3%81%AB%E5%9B%9E%E3%81%99%E3%81%A8%E3%83%95%E3%82%A9%E3%82%A2%E3%82%B0%E3%83%A9%E3%82%A6%E3%83%B3%E3%83%89%E3%81%AB%E6%88%BB%E3%81%97%E3%81%A6%E3%82%82%E6%BC%94%E5%A5%8F%E3%81%8C%E5%86%8D%E9%96%8B%E3%81%97%E3%81%AA%E3%81%84

https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/state#resuming_interrupted_play_states_in_ios_safari

## まとめると

こうなる。

|  | html5:false | html5:true |
|:-:|:-:|:-:|
| **音量が** | 変えられる | 変えられない（絶望） |
| **復帰時、音が** | 鳴らない？ | 鳴る |


## おまけ

[howler.js](https://github.com/goldfire/howler.js)は素晴らしいライブラリだが、現時点でissueが352個、PRが50個あり、結構放置されている印象。
（ちなみに現バージョン2.2.4は2年前にリリースされている。）

これだけissueがあれば、投げ出したくもなる。

ちなみに`html5:false`だとメモリリークが発生するっぽい。

https://github.com/goldfire/howler.js/issues/1365