27

Web Audio API を使用して iPhone ゲームでサウンドを動作させようとしています。問題は、このアプリが完全にクライアント側であることです。MP3 をローカル フォルダーに保存したいので (ユーザー入力を必要とせずに)、XMLHttpRequest を使用してデータを読み取ることはできません。FileSystem の使用を検討していましたが、Safari ではサポートされていません。

代替手段はありますか?

編集:以下の回答に感謝します。残念ながら、Audio API はゲームでは非常に遅いです。私はこれを機能させましたが、レイテンシーによりユーザーエクスペリエンスが受け入れられなくなりました. 明確にするために、私が必要としているのは次のような音です -

var request = new XMLHttpRequest();
request.open('GET', 'file:///./../sounds/beep-1.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
    context.decodeAudioData(request.response, function(buffer) {
    dogBarkingBuffer = buffer;
}, onError);
}
request.send();

しかし、これは私にエラーを与えます -

XMLHttpRequest は file:///sounds/beep-1.mp3 を読み込めません。クロス オリジン リクエストは、HTTP でのみサポートされています。キャッチされないエラー: NETWORK_ERR: XMLHttpRequest 例外 101

ローカル ファイルの読み取りに伴うセキュリティ リスクは理解していますが、自分のドメイン内では問題ないはずですか?

4

4 に答える 4

17

さて、さまざまなソリューションのプロトタイピングに2日かかりました。最終的に、サーバーにリソースを保存せずにこれを行う方法を理解しました。これについて詳しく説明しているブログがいくつかありますが、完全な解決策を1か所で見つけることができなかったため、ここに追加します。これはベテランのプログラマーには少しハッキーだと思われるかもしれませんが、これが機能しているのを見ることができる唯一の方法なので、誰かがもっと精力的な解決策を持っているなら、私はそれを聞いてみたいです。

解決策は、サウンドファイルをBase64でエンコードされた文字列として保存することでした。サウンドファイルは比較的小さい(30kb未満)ので、パフォーマンスがそれほど問題にならないことを願っています。n00bステータスは、3つ以上のリンクを投稿できないことを意味するため、一部のハイパーリンクの前に「xxx」を付けていることに注意してください。

ステップ1:Base64サウンドフォントを作成する

まず、mp3をBase64でエンコードされた文字列に変換し、JSONとして保存する必要があります。この変換を行うWebサイトをここで見つけました-xxxhttp://www.mobilefish.com/services/base64/base64.phpテキストエディターを使用して戻り文字を削除する必要があるかもしれませんが、例が必要な人のためにいくつか見つけましたここのピアノトーン-xxxhttps://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js私の例で作業するには、ヘッダー部分のデータを削除する必要があることに注意してください:audio / mpeg; base64、

ステップ2:サウンドフォントをArrayBufferにデコードする

これを自分で実装することもできますが、これを完全に実行するAPIを見つけました(なぜ車輪を再発明するのですか?)-https://github.com/danguer/blog-examples/blob/master/js/base64-binary。 js リソースは-ここから取得

ステップ3:残りのコードを追加する

かなり簡単

var cNote  = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote); 
var context = new webkitAudioContext();

context.decodeAudioData(byteArray, function(buffer) {
    var source = context.createBufferSource(); // creates a sound source
    source.buffer = buffer;    
    source.connect(context.destination); // connect the source to the context's destination (the speakers)
    source.noteOn(0); 
}, function(err) { console.log("err(decodeAudioData): "+err); });

以上です!私はこれをデスクトップバージョンのChromeで動作させ、モバイルSafariでも実行しています(もちろん、古いバージョンではWebオーディオがサポートされていないためiOS 6のみ)。モバイルSafariでの読み込みには数秒かかります(デスクトップChromeでは1秒未満)が、これはサウンドフォントのダウンロードに時間がかかることが原因である可能性があります。また、iOSは、ユーザーインタラクションイベントが発生するまでサウンドの再生を禁止しているという事実もあります。私はそれがどのように機能するかを見てもっと仕事をする必要があります。

これが私が経験した他の誰かの悲しみを救うことを願っています。

于 2012-12-29T16:05:35.610 に答える
1

iOS アプリはサンドボックス化されているため、Web ビュー (基本的に phonegap でラップされたサファリ) を使用すると、mp3 ファイルをローカルに保存できます。つまり、「クロスドメイン」のセキュリティ問題はありません。

以前のバージョンの iOS は Web オーディオ API をサポートしていなかったため、これは ios6 の時点です。

于 2013-03-03T00:13:37.970 に答える
-2

ブラウザで音声ファイルを再生するには、HTML5 Audio タグを使用します。

Ajax リクエストは http プロトコルで動作するため、file:// を使用してオーディオ ファイルを取得しようとすると、ブラウザはこのリクエストをクロス ドメイン リクエストとしてマークします。リクエストヘッダーに次のコードを設定します-

header('Access-Control-Allow-Origin: *');
于 2012-12-28T19:47:28.040 に答える