audioタグのcontrolsの使えなさっぷりを体感してみた

# audioタグのcontrolsの使えなさっぷりを体感してみた

# 結果

> 使えなかった。という話

## はじめに

[Web Music ハッカソン #3](http://googledevjp.blogspot.jp/2014/08/web-music-3.html)が近づいてきましたが、未だにWeb Audio APIが使えません。

「そうだ。Audioタグを使ってお茶を濁そうw」

というわけで、Audioタグを調べてみることに。

簡単な使い方として

```html
<audio src="test.mp3" controls>
```

上記のように書けば、音の再生・停止等を行うコントローラーを表示することができるはず。

しかし。

- 対応するオーディオフォーマットやコーデックに機種差分がある
- controls属性で表示されるコントロールUI表示にもブラウザ毎に大きな差分がある

と言われており、HTMLだけで書く上記の方法は、あまり使われていない模様。うーむ。

納得いかないので、**どのくらい使えないのか？**、自分の目で確かめてみることに。

いや、もしかしたら使えるかもしれないでしょ？！

## やってみたこと

[ヘッポコなコンテンツ](http://img.dfm.lrv.jp/audio/sample/index.html)を使って、いろんな機種（スマホ）で動作確認してみることに。
aac(.m4a)、mp3(.mp3)、ogg-vorbis(.ogg)を選択して再生できるように。

> ここはCSSのことをとやかく言う場ではありません。スルーする場ですw

確認してみた機種は下記の通り。

- iPhone 5C (iOS7.1.1) Mobile Safari
- iPhone 4S (iOS6.0) Mobile Safari
- iPhone 4S (iOS5.1.1) Mobile Safari
- IS11CA (Android 2.3.3) ブラウザ
- IS11S   (Android 2.3.4) ブラウザ
- IS13SH  (Android 2.3.5) ブラウザ
- ISW13F  (Android 4.0.3) ブラウザ
- ISW13HT (Android 4.0.4) ブラウザ
- Infobar A02 (Android 4.1.1) ブラウザ
- SCL21   (Android 4.1.2) ブラウザ / Chrome v28.0

## controlの表示結果は。

コントロールUIの表示結果は。。。。なかなか酷い状況w

### iPhone。

> iPhone6が発売される直前のこのタイミングですので、iOS7までの確認結果ですw

まず、iPhoneを見てみました。

**左がiOS5、右がiOS7の表示**

![iOSの表示](http://img.dfm.lrv.jp/audio/iOS.png)

iOS5.1.1とiOS6.0では再生時にプログレスや残り秒数表示などが行われます。
プログレスバーにより再生位置を変えることができます。

一方でiOS7.1.1では、コントロールに再生/停止のための三角ボタンしか表示されません。
このため、再生位置を変えたりができません。
しかも、コントロールUIの表示はかなり大きく、前後の要素と重なって表示されてしまいます。

こうして見比べてみても、やはりiOS7はいろいろとおかしいですね。
というか、iOS8どうなっちゃうんですかね。。。。。

### Androidではどうか

最初にAndroidの機種に最初っから入っている「ブラウザ」での表示を見てみました。

**Android2.3.x**

![Android2.3.xの表示](http://img.dfm.lrv.jp/audio/Android2x.png)

機種によって、見た目がかなり違いますが、再生ボタン以外にプログレスバーがあって再生位置を変えることができます。

**Android4.x**

![Android4.xの表示](http://img.dfm.lrv.jp/audio/Android4x.png)

Android4.x系も並べてみました。

デザインがだいぶん統一されましたが、コントロールの右端に停止ボタンがあったり、音量があったり、といった風に少しづつ違います。

**Chrome**

![Chromeの表示](http://img.dfm.lrv.jp/audio/SC21Chrome28.png)

もうひとつ、Android版のChromeブラウザでの表示も見てみました。

iOS版Chromeは、内部でWebViewを使っているためインストールしたiOSバージョンのMobile Safariと同じになりますが、Android版では機種に最初から入っているブラウザとは別の表示になります。
これは、Version 28のキャプチャです。（あれ？なんで会社にある端末のChromeこんなに古いんだ？w）

## 再生はどうだったか。

### ファイル形式は思ったより問題なさそう

ざっくりと試してみました。
とりあえず、今回の確認したAndroid機では下記いずれの形式でも再生可能でした。

今回利用した設定は下記の通り。

- aac(.m4a) ※stereo 最適化レベル500
- mp3(.mp3) ※stereo 320kbps
- ogg-vorbis(.ogg) ※stereo 最適化レベル10

今回のテストでは1つのデータしか試してないので、ファイルサイズやエンコードの際の設定、audio要素に指定するパラメータなどが変われば、結果が変わるかもしれませんが。

iOSでは、ogg-vorbisのみ再生できませんでした。
ということなので、iOSとAndroidのみをターゲットにする場合、mp3とaacを用意しておけば大丈夫そう。

### 複数同時再生には注意。できない機種がある

今回のテストでは1つのaudio要素の音再生がうまくいっても、複数同時操作での再生については、うまくいかない機種がありました。
（同時に短い音データを鳴らして音楽っぽく使おうという野望が。。w）

**複数同時再生がうまくいかない機種**

- iOS 5のiPhone。
- Android 4.x の Android端末

iOS5は複数のaudio要素の再生に対応しておらず、iOS6以降でサポートされている模様。（我が家のiPadはまだiOS5なんですが。。。）

一方、Androidで今回確認した2.3.x系の機種では同時再生が可能だったのですが、Android4.xでは基本的に同時再生できない。なぜだ！

iOS5のように排他制御になるのではなく、Android4.x系での同時再生時はコントロール表示と再生状態が一致しない（再生されないにも関わらず再生中と同じアイコンに変わったまま戻らない）不具合も発生するため、非常に厄介。うーん。

## まとめ

今回は、スマホで良く言われる、「audioタグの`controls`は使えない」という噂が本当なのか試してみました。

結果、「本当でした！」このやろう。

事前情報の通り、audio要素の`controlで表示されるコントローラーUIはブラウザによってバラバラです。
「見た目どうでもいいから、とりあえず再生したい」といったユースケース以外、使えない。。。
社内サイトや、テストくらい？しか使えない印象です。

サイトに音楽再生機能を付けるサンプルとして、audio要素や`controls`属性を使わずに、audioオブジェクトをJavaScriptから生成して音を再生するサンプルが多い理由がわかりました。

↓こんな感じですね。

```html
<!DOCTYPE html>
<html>
<body>
<input type="button" id="audiobutton" value="">
<script src='jquery-2.0.3.min.js'></script>
<script>
$(function() {
	var audio = new Audio("");
	var src = "";
	var name = "再生できません";
	var state = 0;	// 0:pause, 1:playing
	if(audio.canPlayType){
		if(audio.canPlayType("audio/mp4") != ""){
			src = "audio/waterdrop_windnoize_L500_stereo.m4a";
			name = "aac";
		}else if(audio.canPlayType("audio/mpeg") != ""){
			src = "audio/waterdrop_windnoize_256k_stereo.mp3";
			name = "mp3";
		}else if(audio.canPlayType("audio/ogg") != ""){
			src = "audio/waterdrop_windnoize_L10_stereo.ogg";
			name = "ogg";
		}
	}
	$("#audiobutton").val(name);
	if(src != ""){
		audio.src = src;
		$("#audiobutton").click(function(ev){
			if(state == 0){
				audio.load();
				audio.play();
				state = 1;
			}else{
				audio.pause();
				state = 0;
			}
		});
	}
});
</script>
</body>
</html>
```

しかし。。。面倒だ。。。せっかくの **Audioタグ** が使えないとは残念。。

こんな風にJavaScriptで書くなら、さっさとWeb Audio APIでも覚えろ！という声が聞こえてきそうだ。

が、３日後のハッカソンには間に合いそうにないので、私は[この作戦(Web MIDI API)](http://qiita.com/tadfmac/items/e26fdf1034ad6dad4504)で行きます。こっちはえらい簡単なので。

## しかし。

そろそろ、Web Audio API使えない劣等感激しすぎるので、こっそり勉強開始する。

- [『Web Audio API の基礎』by Boris Smusさん](http://www.html5rocks.com/ja/tutorials/webaudio/intro/)
- [『Web Audio API 解説』by g200kgさん](http://www.g200kg.com/jp/docs/webaudio/)

このあたりか。