iOS における HTML5 の audio 要素に関する制約を克服する

モバイル版 Safari でのソリューションと次善策

HTML5 の audio 要素は素晴らしい仕様になる可能性がありますが、まだ完成途上にあることから、さまざまな制約があります。それに輪をかけて、モバイル版 Safari がさらに制約をもたらします。この記事を読んで、モバイル版 Safari での HTML5 に関する制約を学んでください。記事では実際に動作する例によって、ソリューションと包括的な次善策を紹介します。また、モバイル版 Safari でオーディオ・スプライトを使用するメリットを理解するとともに、iOS でのあらゆる HTML5 の制約を乗り越える、優れたソリューションを試してみてください。

Aaron Gloege, Software Engineer, The Nerdery

Photo of Aaron GloegeAaron Gloege がプログラミングへの情熱を自覚したのは 2006年のことです。ブラウン大学で受けた Web 開発の課程をきっかけに、独学で JavaScript、iOS、PHP の第一人者になるために余暇をささげるようになりました。2007年に、ビジュアル・コミュニケーションの応用科学で準学士号を取得してブラウン大学を卒業した後、Greatapes/MediaXpress に Web およびインタラクティブ主任開発者として入社しました。2011年の初め、The Nerdery でソフトウェア・エンジニアとして働くようになってからは、瞬く間に才能ある開発者として、そして信頼できる献身的なチーム・メンバーおよびプロジェクト・リーダーとしての評判を得ました。



2012年 11月 08日

はじめに

開発者たちは数年ぐらい前から、程度の差はあれブラウザー内で直接実行される本格的なインタラクティブ・エクスペリエンスを提供するサイトを作成するようになりました。通常、このようなサイトには、ブラウザー・プラグイン (Flash) が必要になります。スマートフォンとタブレットが登場すると、新しいガジェットとインタラクティブ・エクスペリエンスの相性はぴったりであるかのように思えましたが、モバイル機器の処理能力は限られているため、ブラウザー・プラグインは開発に有効なプラットフォームではなくなりました。

頻繁に使用される略語

  • AAC: Advanced Audio Coding
  • CSS: Cascading Style Sheet
  • HTML: HyperText Markup Language
  • MP3: MPEG-1 Audio Layer 3
  • OGG: オープン・コンテナー・フォーマット
  • WAV: Waveform Audio Format

HTML5 で追加された多彩なブラウザー内ツールは、追加のプラグインを必要としません。W3C による HTML5 仕様の策定は今でも引き続き行われていますが、仕様が進化するにつれ、ブラウザーがサポートを提供しつつあります。

HTML5 の audio 要素の登場は、ブラウザー (特にモバイル機器上のブラウザー (iOS 上で動作するモバイル版 Safari ブラウザーなど)) におけるサウンドの埋め込みを強力に推し進めています。HTML5 の audio 要素は新しく追加された機能とは言え、iOS でサポートされています。人気の高いモバイル・アプリケーションである Instapaper の開発者たちによると、2011年 11月の時点で、このアプリケーションの iOS ユーザーの 98.8% は iOS 4 以上を使用しています (「参考文献」を参照)。HTML5 の audio 要素がモバイル向けの Safari に導入されたのは iOS 3 なので、iOS プラットフォームのほぼすべてで HTML5 の audio 要素がサポートされていることになります。

この記事では、デスクトップ版 Safari とモバイル版 Safari での HTML5 の制約について説明し、インタラクティブなサウンド・エフェクトを作成するためのソリューションをいくつか試してみます。さらに、サポートされていないイベント、オーディオ・スプライト、そして directCanvas と multiSound を使って HTML5 ゲームのパフォーマンスを高める仕組みについても取り上げます。

注意すべき重要な点として、Apple は iOS 6 で、Web Audio API (この後のセクションで説明) のサポートを追加しています。これにより iOS 6 では、この記事で説明する次善策の多くが不要になりますが、この記事を執筆した時点では iOS 6 が登場してからわずか数週間しか経っていないので、iOS 5 が市場ではまだ主流となっています。したがって、記事で説明する問題と、それに対して提案する次善策は今でもなお有効であるため、モバイル版 Safari を対象にしたオーディオ・ファイルを開発する際には、これらの問題と次善策を考慮する必要があります。

記事で使用するサンプルのソース・コードは、「ダウンロード」セクションからダウンロードすることができます。


HTML5 の audio 要素に伴う制約

モバイル版 Safari での制約について検討する前に、デスクトップ・ブラウザー上での HTML5 の audio 要素の制約を理解しておくことが重要です。HTML5 の audio 要素が確実な動作をするか、制約があるかは、その実装に大きく依存します。音楽プレイヤー (ジュークボックス・プレイヤーなど) や単純なサウンド・エフェクトには十分有効に機能しますが、ゲームなどのサウンドを多用するアプリケーションには、まだまだ物足りません。

フォーマットのサポート

残念ながら、すべてのブラウザーが同じオーディオ・ファイル・フォーマットをサポートしているわけではありません。表 1 に記載されているように、現在使用されている主要なフォーマットには、MP3、OGG、WAV、AAC の 4 つがあります。

表 1. HTML5 の audio 要素の主要フォーマットのサポート状況
Ogg VorbisWAVPCMAAC
Internet Explorer 9××
Firefox××
Chrome/Safari/モバイル版 Safari×××

すべてのブラウザーに対応するには、すべてのオーディオ・ストリームを Ogg Vorbis と AAC の両方で用意することが最善策です。

MP3 が上記の表に含まれていない理由は、MP3 を営利目的で配布する場合には、高額のロイヤリティーを支払わなければならないためです。MP3 のライセンス要件により、10 万ドルを超える全収益の 2% が配布料として請求されます (「参考文献」を参照)。このことから、私が MP3 よりも優先しているのは AAC です。AAC はロイヤリティー・フリーではありませんが、そのライセンスは遥かに緩いものとなっており、無料で配布することができるほどです。さらに、AAC のほうが圧縮能力に優れているため、ファイル・サイズをさらに小さくすることができます。これは、Web の世界では喜ぶべきことです (「参考文献」を参照)。

私が圧倒的に支持しているのは、特許使用料もロイヤリティーもかからないオープンソースの Ogg Vorbis です。ただし、Ogg Vorbis がサポートされるのは Firefox に限られます。

リスト 1 に、クロスブラウザー対応の HTML マークアップの例を記載します。

リスト 1. HTML5 の audio 要素のマークアップ
<audio>
    // AAC file (Chrome/Safari/IE9)
    <source src="sound.m4a" type="audio/mpeg" />
    // Ogg Vorbis (Firefox)
    <source src="sound.ogg" type="audio/ogg" />
</audio>

操作とエフェクト

オーディオ・ファイル (オーディオ・ストリーム) を扱う際に強力な機能となるのは、サウンドを操作する機能です。サウンドをオンザフライで合成する場合やサウンド・エフェクトの処理をする場合、あるいは環境エフェクトを適用する場合や基本的なステレオ・パンニングを行う場合など、いずれの場合でも HTML5 の audio 要素で操作をすることはできません。ロードされるオーディオ・ファイル (オーディオ・ストリーム) が、そのまま再生されます。

Web Audio API (Chrome) および Audio Data API (Firefox) のそれぞれは、ブラウザー・プラグインを使わずにオーディオ・ファイル (オーディオ・ストリーム) をオンザフライで合成して処理する機能を提供することで、この欠けている機能に有効に対処します。この 2 つの API はいずれも開発中であり、サポートされているのは Chrome 14 またはそれ以降のバージョン、そして Firefox 4 またはそれ以降のバージョンのみです。残念ながら、この 2 つは実装の点でもかなりの違いがあります。そのため、audiolibjs をはじめ、サポートを標準化するのに役立つ優れたライブラリーがいくつか登場しています (「参考文献」を参照)。Chrome の Web Audio API は W3C によって標準としての策定が推し進められています。

単一サウンドの多層化 (ポリフォニック)

同じサウンドを重ねて再生するには、同じサウンドのオーディオ・オブジェクトをもう 1 つ別のオブジェクトとしてインスタンス化する必要があります。マークアップと再生可能なオーディオ・オブジェクトの間には、1 対 1 の対応関係があるためです。現状のHTML5 の audio 要素では、サウンドを多層化することはできません。他のプラットフォーム (Flash など) では、新しいオーディオ・オブジェクトを作成せずに、単一のオーディオ・オブジェクトを多層化することができます。


iOS、モバイル版 Safari、そして HTML5 の audio 要素の制約

HTML5 の audio 要素には既にある程度の制約がある上に、モバイル版 Safari では HTML5 の audio 要素の最も基本的な使用方法にさらに制約が加わります。

単一のオーディオ・ストリーム

モバイル版 Safari が課す最大の制約の 1 つは、一度に 1 つのオーディオ・ストリームしか再生できないことです。モバイル版 Safari での HTML5 のメディア要素はシングルトンであるため、一度に1 つの HTML5 の audio 要素 (および HTML5 の video 要素) のストリームしか再生することができません。Apple はこの制約について何も説明していませんが、これはおそらく (iOS での HTML5 に伴う他のほとんどの制約の根拠と同じく) データへの課金額を抑えるためだと思われます。

iOS は モバイル版 Safari に 1 つの HTML5 メディア (音声および動画) コンテナーしか提供しません。オーディオ・ストリームの再生中に別のオーディオ・ストリームを再生すると、再生中のオーディオ・ストリームがコンテナーから削除されて、代わりに新しいオーディオ・ストリームがインスタンス化されます。

リスト 2 に、ストリームの再生中に play() を呼び出すと、再生中のストリーム (この例では audio1) が停止されるコードを示します。

リスト 2. 単一のオーディオ・ストリーム
var audio1 = document.getElementById('audio1');
var audio2 = document.getElementById('audio2');
audio1.play(); // this stream will immediately stop when the next line is run
audio2.play(); // this will stop audio1

このサンプルを視聴するには、ここをクリックしてください。

念頭に置いておくべき重要な点として、音声と動画は互いに置き換えることができます。動画の再生中に音声ファイルを再生すると、動画が停止します。一度に再生できるのは、1 つのオーディオ・ストリームまたはビデオ・ストリームだけです (リスト 3 を参照)。

リスト 3. 互いに置き換え可能なオーディオ・ストリームとビデオ・ストリーム
var audio = document.getElementById('audio');
var video = document.getElementById('video');
video.play();

// at a later time
audio.play(); // this will stop video

自動再生

モバイル版 Safari では、オーディオ・ファイルをページのロード時に自動再生することはできません。オーディオ・ファイルをロードできるのは、ユーザーによるタッチ (クリック) イベントによってのみです。以下のように HTML マークアップ内で autoplay 属性を指定しても、モバイル版 Safari はこの属性を無視し、ページのロード時にファイルを再生しません。

<audio id="audio" src="audio_file.mp3" autoplay></audio>

この件については、Safari の開発者向けガイドで詳しく説明しています (「参考文献」を参照)。

オーディオ・ストリームのロード

オーディオ・ストリームをロードできるのは、ユーザーによるタッチ・イベント (onmousedownonmouseuponclickontouchstart など) によってロードが開始された場合に限られます。図 1 に一例を示します。

図 1. モバイル版 Safari で音声をロードする場合のワークフロー
モバイル版 Safari で音声をロードする場合のワークフロー

リスト 4 のコードがページのロード時に実行されても、モバイル版 Safari ではオーディオ・ストリームはロードされず、ダウンロードすらされません。

リスト 4. ページ・ロード時のオーディオ・ストリームの再生は暗黙のうちに失敗します
var audio = document.getElementById('audio');
audio.play();

HTML マークアップ内で preload 属性を指定したとしても、モバイル版 Safari はこの属性を無視し、ユーザーによるタッチ・イベントによってロードが開始されるまで、ファイルはロードされません (リスト 5 を参照)。

リスト 5. preload 属性はモバイル版 Safari ではサポートされません
<audio id="audio" src="audio_file.mp3" 
preload="auto"></audio>

このサンプルを視聴するには、ここをクリックしてください。

デスクトップ版 Safari では、リスト 5 のコードによってページのロード時にオーディオ・ファイルがダウンロードされますが、モバイル版 Safari ではこの属性が無視されるため、オーディオ・ファイルはダウンロードされません。

その他の特異な点

モバイル版 Safari で HTML5 の audio 要素を使用するときには、他にも考慮しなければならない特異な制約があります。

新しいオーディオ・ストリームを初期化する際に、数秒の遅延が生じます。これは、iOS が新しいオーディオ・オブジェクトをインスタンス化するためです。リスト 6 に、遅延が発生するコードを示します。

リスト 6. オーディオ・オブジェクトを切り替える際の HTML5 の audio 要素の遅延
var audio1 = document.getElementById('audio1');
var audio2 = document.getElementById('audio2');
audio1.play();

// at a later time
audio2.play(); 
// there will be a few-seconds delay as iOS is instantiating a new audio object. 

// at an even later time
audio1.play(); // there will also be a few-seconds delay, as the audio object 
// for audio1 in iOS was destroyed when we played audio2.

このサンプルを視聴するには、ここをクリックしてください。

重要なのは、オーディオ・ストリームがページのロード時にロードされるという思い込みを排除することです。play() の呼び出しは暗黙のうちに失敗しますが、本体のみならずメタデータもロードされていないオーディオ・ストリームに currentTime を設定しようとすると、致命的エラーがスローされてしまいます (リスト 7 を参照)。

リスト 7. メタデータがロードされていないオーディオ・ストリームに currentTime を設定する
// run on page load
var audio = document.getElementById('audio');
audio.play(); // This will silently fail
audio.currentTime = 2; // This will throw a fatal error because the metadata 
// for the audio does not exist

このサンプルを視聴するには、ここをクリックしてください。

iOS のモバイル・マニフェストでは、オーディオ・ファイルをキャッシュすることはできません。これが適用されるのは、オフライン Web アプリケーション用にマニフェストを使用している場合のみです。オーディオ・ファイルがマニフェストに含まれていても、iOS はこれを無視し、ファイルをキャッシュしません。Web アプリケーションがオーディオ・ファイルにアクセスしなければならないときには、そのたびに、ネットワークからオーディオ・ファイルにアクセスすることになります。

モバイル版 Safari は、JavaScript でプログラムによって設定される音量と playbackRate プロパティーを考慮しないため、属性の値を変更しても、その値が実際に調整されることにはなりません。音量は常にユーザーが制御します。playbackRate については、モバイル版 Safari ではサポートされていません。音量は常に 1 に設定されたままになりますが、playbackRate はユーザーが設定する新しい値に設定されます。ただし、オーディオ・ストリームの実際の再生速度は変更されないため、onratechange イベントでは「サポートされていないイベント」で説明する複雑な問題が生じます。

iOS 5 より前のバージョンでは、loop 属性はサポートされていませんでした。このサポートの欠如に対処するには、イベント・リスナーを onended イベントに追加して、その関数の中で play() を呼び出してください。リスト 8 に一例を記載します。

リスト 8. iOS 5 より前のバージョンでのオーディオのループ処理に対する次善策
var audio = document.getElementById('audio');
audio.play();

var onEnded = function() {
    this.play();
};

audio.addEventListener('ended', onEnded, false);

このサンプルを視聴するには、ここをクリックしてください。


ソリューション

モバイル版 Safari の HTML5 の audio 要素に関する欠点に対処するためのソリューションは、完全にその使い方に依存します。1 つのオーディオ・ファイルやオーディオ・ファイルのプレイリストを再生するだけであれば、変更の必要はほとんどありませんが、インタラクティブなサウンド・エフェクトが必要だとすると、事態はかなり厄介になってきます。

単一のオーディオ・ストリーム

一度に 1 つのオーディオ・ストリームしか再生できないという制約に対する単純なソリューションは、オーディオ・ストリームのソースとなるファイルを必要なオーディオ・ストリームが含まれたファイルと交換することです (リスト 9 を参照)。けれども、新しいオーディオ・ストリームを再生するには、そのオーディオ・ストリームがロードされるのを待たなくてはならないため、これは理想的なソリューションではありません。

リスト 9. オーディオ・オブジェクトのソースを交換する
var audio = document.getElementById('audio');
audio.play();

// at some later point in your script (does not need to be from a touch event)
audio.src = 'newfile.m4a';
audio.play(); // there will be a slight delay while the new audio file loads

このサンプルを視聴するには、ここをクリックしてください。

単一のオーディオ・ストリームの制約を解決するための、これよりも優れた方法は、オーディオ・スプライトを使用する方法です。つまり、すべてのオーディオ・ストリームを 1 つのオーディオ・ストリームに結合し、その結合されたストリームの部分を再生するという方法です。その詳細については「オーディオ・スプライト」で説明します。

自動再生

自動音声の制約に対する次善策はありません。前述のとおり、オーディオ・ストリームは、ユーザーによるタッチ・イベントによってのみロードすることができます。したがって、モバイル版 Safari を対象に開発する場合には、この制約を許容するように必要に応じてワークフローを調整することが重要です (経験から言うと、最初からこの制約を考慮に入れておかないと、相当なリファクタリングが発生することは目に見えています)。

iOS 4.2.1 より前のバージョンでは、同期 Ajax 呼び出しのコールバックからオーディオ・ファイルをロードすることができました。リスト 10 に一例を記載します。

リスト 10. iOS 4.2.1 より前のバージョンで、同期 Ajax 呼び出しのコールバックからオーディオ・ファイルをロードする
// run on page load
var audio = document.getElementById('audio');

jQuery.ajax({
    url: 'ajax.js',
    async: false,
    success: function() {
        audio.play(); // audio will play in iOS before 4.2.1
    }
});

このサンプルを視聴するには、ここをクリックしてください。

リスト 10 の方法には 1 つの問題があります。それは、この方法は同期型の Ajax 呼び出しであるため、呼び出しが完了するまでブラウザーがロックされることです。モバイル版 Safari では、ロック状態になるということは、ページがロックされるだけでなく、アプリケーション全体がロックされてしまうことを意味します。エラーが発生してモバイル版 Safari がロック状態のままになった場合 (非常に可能性が大きいわけではありませんが)、ホーム・ボタンをクリックしてアプリケーションを強制終了するしか、終了する方法はありません。

Apple は iOS 4.2.1 でこの問題に対する次善策を適用しました。そのため、上記の次善策は、iOS 4.2.1 およびそれ以降のすべてのバージョンには無効です。

オーディオ・ストリームのロード

オーディオ・ストリームは、ユーザー・イベントによってトリガーされた場合にだけロードされます。リスト 11 に示すように、onmousedownonmouseuponclickontouchstart は有効なイベントとして、コールバック内で呼び出されたオーディオ・ストリームを正常にロードします。ただし、イベントはオーディオ・ファイルをロードするためだけのものであることに注意してください。つまり、ロードしたファイルで play() を呼び出すことで期待通りの動作をするようになります。

リスト 11. ユーザーがトリガーしたイベントを使用してオーディオ・ストリームをロードする
// run on page load
var button = document.getElementById('button');
var audio = document.getElementById('audio');

var onClick = function() {
    audio.play(); // audio will load and then play
};

button.addEventListener('click', onClick, false);

このサンプルを視聴するには、ここをクリックしてください。

一見したところ、リスト 11 は煩わしい次善策のように思えるかもしれません。けれども、ゲームやインタラクティブ・エクスペリエンスに図 2 のようなスプラッシュ・スクリーンを用意して、スタートするにはユーザーがボタンをクリックしなければならないようにすることが、ベスト・プラクティスです。こうすれば、ユーザーがスタート・ボタンをクリックしたときのイベントを、プロジェクトにオーディオ・ストリームをロードするために使用することができます。

図 2. 「Cut the Rope」の HTML5 スプラッシュ・スクリーン
「Cut the Rope」の HTML5 スプラッシュ・スクリーン

サポートされていないイベント

モバイル版 Safari での HTML5 の audio 要素は、デスクトップ版 Safari でのメディア・イベントのすべてをサポートしています。けれども、前述のようにサポートされてないプロパティーがいくつかあるために、イベントのなかには決して起動されることのないものがあります。また、認識しておかなければならない特異な問題もいくつかあります。

表 2 に、HTML5 の audio 要素のすべてのイベント・コールバックと、デスクトップ版 Safari とモバイル版 Safari での各イベントの互換性を記載します。記載する結果は、著者がセットアップした HTML5 の audio 要素のイベント・デバッガーに基づくものです。お望みであれば、遠慮なくこのデバッガーを試してみてください。

表 2. デスクトップ版 Safari と モバイル版 Safari がサポートするメディア・イベントの比較
イベント内容デスクトップ版 Safariモバイル版 Safari
abortメディアのダウンロードが完了する前に、ブラウザーがメディアのダウンロードを停止した時に発生するイベント。××
canplayメディア・データの再生を開始できるが、再生が開始された場合、途中でコンテンツのさらなるバッファリングのために再生を停止しなければ、現行の再生速度で最後までメディア・リソースを再生することができないと、ブラウザーが判断した時に発生するイベント。××
canplaythrough現時点で再生が開始された場合、途中でコンテンツのさらなるバッファリングのために再生を停止しなくても、現行の再生速度で最後までメディア・リソースを再生できると、ブラウザーが判断した時に発生するイベント。××
durationchangeduration プロパティーの値が変更された時に発生するイベント。××
emptiedmedia 要素のネットワーク・ステートが NETWORK_EMPTY に変更された時に発生するイベント。××
endedメディア・リソースの末尾に達して再生が停止し、ended プロパティーが true に設定された時に発生するイベント。××
errorメディア・データのダウンロード中にエラーが生じた時に発生するイベント (error プロパティーを使用すると、現在発生しているエラーを取得することができます)。××
loadeddataブラウザーが現在の再生位置 (現行フレーム) のメディア・データを初めて再生できる状態になった時に発生するイベント。××
loadedmetadataブラウザーがメディア・リソースの (メタデータをロードして) 合計再生時間やサイズを認識した時に発生するイベント。××
loadstartブラウザーがメディア・データのロードを開始した時に発生するイベント。××
pausepause メソッドから制御が戻り、再生が一時中断された時に発生するイベント。××
playplay メソッドから制御が戻り、再生が開始された時に発生するイベント。××
playing再生が開始できる状態になった時に発生するイベント。××
progressブラウザーがメディア・データをダウンロードしている時に発生するイベント。××
ratechangedefaultPlaybackRate または playbackRate プロパティーのいずれかの値が変更されることで、再生速度が変更された時に発生するイベント。×× (非推奨)
seekingストリーミングの新しい位置までムーブ/スキップするために seeking プロパティーが true に設定され、このイベントを送信する時間がある時に発生するイベント。×*
seekedストリーミングの新しい位置までムーブ/スキップされて seeking プロパティーが false に設定された時に発生するイベント。×*×*
stalledブラウザーはメディア・データをダウンロード中であるが、メディア・データが到着しなくなった時に発生するイベント。××
suspendブラウザーがメディア・リソース全体のダウンロードが完了していない状態で、メディア・データのダウンロードを中断した時に発生するイベント。××
timeupdate通常の再生動作の一環として、またはその他の条件によって、currentTime プロパティーが変更され、現在の再生位置が変更された時に発生するイベント。××
volumechangevolume プロパティーまたは muted プロパティーのいずれかが変更されて、ボリュームが変更された時に発生するイベント。×
waitingブラウザーが次のフレームを待機中であることから、再生を停止した時に発生するイベント。××

以下に、イベント・コールバックに関する注意事項をいくつか記載します。

ratechange
playbackRate が変更されると必ず ratechange イベントが発生します。前述のとおり、オーディオ・ストリーム (およびビデオ・ストリーム) の再生速度の変更は モバイル版 Safari ではサポートされていないため、playbackRate が発生することはありません。ただし、iOS 5.1.1 では、実際の再生速度が変更されていないとしても、HTML5 の audio 要素によって ratechange イベントが発生します。
volumechange
JavaScript を使用してボリュームを設定することはできないため、volumechange イベントが発生することはありません。モバイル版 Safari を開いている状態で、ユーザーが機器の音量を変更したとしても、このイベントは発生しません。
seeking/seeked
モバイル版 Safari が seeking イベントと seeked イベントをサポートするのは、JavaScript によって再生位置の変更が行われた場合のみです (リスト 12 を参照)。組み込みコントロールが表示されて、ユーザーがプログレス・バーを使用して再生位置を変更した場合には、seeking および seeked イベントは発生しません。
リスト 12. currentTime を設定すると発生する、seeking イベントと seeked イベント
var audio = document.getElementById('audio');
audio.currentTime = 60; // seeking and seeked will be fired

オーディオ・スプライト

オーディオ・スプライトの使用は、モバイル版 Safari で複数のサウンドに対する要求に対処するには最善のソリューションの 1 つです。画像に対する CSS スプライトと同じように、オーディオ・スプライトはすべてのオーディオ・ストリームを 1 つのストリームに結合します (図 3 を参照)。

図 3. オーディオ・スプライト
複数のオーディオ・ストリームが 1 つのオーディオ・ストリームに結合された音声スプライト

原理は極めて単純で、スプライトごとのデータ (開始位置、終了位置または長さ、ID) を保管しておいて、特定のスプライトを再生するときに、オーディオ・ストリームの currentTime を開始位置に設定し、play() を呼び出すというものです。リスト 13 に一例を記載します。

リスト 13. 単純なオーディオ・ストリームの実装
// audioSprite has already been loaded using a user touch event
var audioSprite = document.getElementById('audio');
var spriteData = {
    meow1: {
        start: 0,
        length: 1.1
    },
    meow2: {
        start: 1.3,
        length: 1.1
    },
    whine: {
        start: 2.7,
        length: 0.8
    },
    purr: {
        start: 5,
        length: 5
    }
};

// play meow2 sprite
audioSprite.currentTime = spriteData.meow2.start;
audioSprite.play();

リスト 13 は meow2 スプライトを再生すると同時に、スプライトが完了したときにオーディオ・ストリームを停止するためのロジックが実装されていないことから、whine スプライトと purr スプライトも再生します。イベント・リスナーを ontimeupdate イベントに追加することで (リスト 14 を参照)、currentTime を監視して、スプライトが終わりに達した時点でオーディオ・ストリームを停止することができます。

リスト 14. スプライトが終わりに達した時点でオーディオ・ストリームを停止するロジックを追加する
var handler = function() {
    if (this.currentTime >= spriteData.meow2.start + spriteData.meow2.length) {
        this.pause();
    }
};
audioSprite.addEventListener('timeupdate', handler, false);

このサンプルを視聴するには、ここをクリックしてください。

オーディオ・スプライトを使用することによる大きな利点は、スプライトの間で切り替えを行う時 (オーディオ・スプライト全体がロードされている前提で、オーディオ・ストリーム間での切り替えを行う時など) に遅延がまったく発生しないことです。すべてのストリームを 1 つのファイルにすることで、HTTP リクエストの数が削減されるという利点もあります。

currentTime の変更は 100% 正確であるわけではありません。currentTime を 6.5 に設定しても、実際には 6.7 や 6.2 の再生位置に移動する可能性があります。別のスプライトの終わりに移動しないようにするためには、各スプライトの間に多少のスペースが必要です。このスペースを追加することで、スプライトが 6.8 秒で開始される場合にストリームが 6.4 の再生位置に移動したとすると、わずかな遅延が発生します。

スプライトにアクセスする前に、確実にオーディオ・ストリーム全体がロードされるようにしてください。これは重要な点です。というのも、オーディオ・ストリームが完全にロードされる前にストリームのロード済み部分にアクセスしようとすると、ストリームのバッファリングが必要になり、ストリームのロード中に遅延が発生することになるからです。

すべての機能を使用したサンプル

オーディオ・スプライト・フレームワークのサンプルを視聴してください。このサンプルは、この記事で取り上げたトピックを考慮して作成されています。


directCanvas と multiSound で HTML5 ゲームのパフォーマンスを改善する方法

AppMobi は、モバイル機器でのさまざまな HTML5 の制約を directCanvas および multiSound という手段で克服する興味深いソリューションを開発しました (「参考文献」を参照)。directCanvas と multiSound は、標準的な HTML5 ブラウザー・アプリケーション内で、機器のネイティブ機能を利用します。したがって、速度の遅いグラフィカル・パフォーマンスも、この記事で説明した制約事項も、もはや問題にはなりません。ネイティブ・アプリケーションならではのパフォーマンス上のメリットを完全に享受することができます。

directCanvas を利用するサイトにユーザーがナビゲートすると、表示されるページで、App Store から MobiUs アプリケーションをダウンロードするように促されます。ユーザーの機器にこのアプリケーションがすでにインストールされている場合には、ページは MobiUs アプリケーションで開くはずです。

AppMobi のサイトに、MobiUs アプリケーションで実行するゲームを、モバイル版 Safari で実行するゲームと比較対照している動画が用意されています。この比較の結果はかなり驚異的なもので、パフォーマンスの改善は10 倍にものぼります (図 4 を参照)。

図 4. モバイル版 Safari と比較した、directCanvas を使用する MobiUs アプリケーションの平均的な HTML5 パフォーマンスの改善
パーセンテージを示す 4 本の棒グラフ

このソリューションをすぐに導入できるように、AppMobi の API サイトには優れたドキュメントが用意されています。SDK は無料でダウンロードすることができます。また、デスクトップ・ブラウザーでの開発を可能にする便利な Google Chrome 拡張機能もあります。

ユーザーが自分の機器にアプリケーションをインストールしなければならない点は理想的とは言えないものの、AppMobi では、検討するに値する興味深いソリューションを用意しています。現在、MobiUs アプリケーションは App Store では提供されていませんが、またすぐに App Store で提供されるようになるはずです。


まとめ

この記事で説明した制約に関わらず、HTML5 の audio 要素は モバイル版 Safari にとって歓迎すべき追加要素であり、そのメリットは利用するべきです。この記事では、デスクトップ版 Safari と モバイル版 Safari のそれぞれにおける制約について説明し、これらの制約に対するソリューションを紹介するとともに、モバイル版 Safari でオーディオ・スプライトを使用することによるメリットを詳しく探りました。モバイル版 Safari の制約を認識することは、そのユーザビリティーを高めることになるはずです。

HTML5 の audio 要素は策定中の仕様であり、確実に進化しています。けれども、この仕様が (予定では) 2014年に完成するまで待つ理由はありません。すべての iOS ユーザーにとって HTML5 の audio 要素はほぼ普遍的に互換性を持つため、この要素を使用しない手はありません。


ダウンロード

内容ファイル名サイズ
Article source codehtml5audio.article.source.zip4073KB

参考文献

学ぶために

  • More iOS device and OS version stats from Instapaper」: Instapaper アプリケーションのユーザーから集めた最新のデータと傾向を参照してください。
  • MP3 のライセンス要件: mp3、mp3HD、および mp3surround の特許とライセンス供与に関する情報を入手してください。
  • AAC ライセンス要件: ライセンス製品 (PC ソフトウェアを除く) の標準料金を調べてください。
  • HTML5 Audio: ウィキペディアで HTML5 Audio の詳細を読んでください。
  • HTML5 の audio 要素では、サウンドを操作することができません。Web Audio API (Chrome) および Audio Data API (Firefox) がこの欠けている能力を補うために提供している、ブブラウザー・プラグインを使わずにオーディオ・ファイル (オーディオ・ストリーム) をオンザフライで合成して処理する機能について調べてください。
  • How can I autoplay media in iOS >= 4.2.1 Mobile Safari?: iOS 4.2.1 以降の モバイル版 Safari でメディアを自動再生する方法を調べてください。
  • appMobi: appMobi が directCanvas と multiSound によって、どのように HTML5 の欠点を解決しているかを学んでください。
  • iOS Specific Considerations: HTML5 を使用してサウンドやビデオを埋め込む際の考慮事項について学んでください。
  • HTMLMediaElement Class Reference: Safari Extensions Development Guide から詳しい情報を入手してください。
  • Getting Started with Web Audio API」: HTML5 Rocks Web サイトに関する記事を読んでください。
  • Audio Data API: MozillaWiki で Audio Data API の詳細を学んでください。
  • Web Audio API: W3C による公式仕様に目を通してください。
  • WHATWG: W3C と協力して HTML5 の微調整に取り組んでいるこの開発者コミュニティーについて調べてください。
  • developerWorks Web architecture ゾーン: さまざまな Web ベースのソリューションを話題にした記事を調べてください。広範な技術に関する記事とヒント、チュートリアル、標準、そして IBM Redbooks については、Web 開発の技術文書一覧を参照してください。
  • developerWorks コミュニティー: developerWorks のエクスペリエンスを自分流にカスタマイズしてください。
  • developerWorks の Technical events and webcasts: これらのセッションで最新情報を入手してください。
  • Twitter での developerWorks: 今すぐ登録して developerWorks のツイートをフォローしてください。
  • developerWorks オンデマンド・デモ: 初心者向けの製品のインストールおよびセットアップから熟練開発者向けの高度な機能に至るまで、さまざまに揃ったデモを見てください。

製品や技術を入手するために

  • audiolib.js: JS で作成された音声関連の強力なツールキットをインストールしてください。
  • directCanvas: directCanvas SDK をダウンロードしてください。これは、いくつかの HTML5 の欠点を解決する、HTML5 ゲーム・アクセラレーション技術のコレクションです。
  • IBM 製品の評価版: DB2、Lotus、Rational、Tivoli、および WebSphere のアプリケーション開発ツールとミドルウェア製品を体験するには、評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版を試してみてください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=844162
ArticleTitle=iOS における HTML5 の audio 要素に関する制約を克服する
publish-date=11082012