Использование локального файла для Web Audio API в Javascript

Я пытаюсь заставить звук работать в моей игре для iPhone с помощью API Web Audio. Проблема в том, что это приложение полностью на стороне клиента. Я хочу хранить свои 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 не может загрузить файл:///sounds/beep-1.mp3. Запросы перекрестного происхождения поддерживаются только для HTTP. Uncaught Ошибка: NETWORK_ERR: исключение XMLHttpRequest 101

Я понимаю риски безопасности при чтении локальных файлов, но в вашем собственном домене все должно быть в порядке?

4 ответа

У меня была такая же проблема, и я нашел это очень простое решение.

audio_file.onchange = function(){
  var files = this.files;
  var file = URL.createObjectURL(files[0]); 
              audio_player.src = file; 
  audio_player.play();
};
<input id="audio_file" type="file" accept="audio/*" />
<audio id="audio_player" />

Вы можете проверить здесь: http://jsfiddle.net/Tv8Cm/

Хорошо, у меня ушло два дня на создание прототипа различных решений, и я наконец понял, как я могу это сделать, не сохраняя свои ресурсы на сервере. Есть несколько блогов, которые подробно описывают это, но я не смог найти полное решение в одном месте, поэтому я добавляю его здесь. Опытные программисты могут посчитать это немного хакерским, но это единственный способ увидеть, как это работает, поэтому, если у кого-то есть более изящное решение, я бы хотел услышать его.

Решением было сохранить мои звуковые файлы в виде строки в кодировке Base64. Звуковые файлы относительно небольшие (менее 30 КБ), поэтому я надеюсь, что производительность не будет слишком большой проблемой. Обратите внимание, что я поставил "xxx" перед некоторыми гиперссылками, так как мой статус n00b означает, что я не могу опубликовать более двух ссылок.

Шаг 1: создайте звуковой шрифт Base 64

Сначала мне нужно преобразовать мой mp3 в строку в кодировке Base64 и сохранить ее в формате JSON. Я нашел веб-сайт, который делает это преобразование для меня здесь - 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 (конечно, только для iOS 6, так как Web Audio не поддерживается в более старых версиях). Загрузка в Safari для мобильных устройств занимает пару секунд (против настольного Chrome менее 1 секунды), но это может быть связано с тем, что он тратит время на загрузку звуковых шрифтов. Это также может быть тот факт, что iOS предотвращает воспроизведение звука, пока не произойдет событие взаимодействия с пользователем. Мне нужно больше работать, глядя на то, как это работает.

Надеюсь, это спасет кого-то еще от горя, через которое я прошел.

Поскольку приложения ios находятся в "песочнице", веб-представление (в основном сафари, обернутое в телефонную пробку) позволяет вам хранить ваш mp3-файл локально. То есть, нет проблемы безопасности "междоменного".

Начиная с ios6, так как предыдущие версии ios не поддерживали веб-аудио API

Используйте HTML5 Audio tag для воспроизведения аудио файла в браузере.

Ajax-запрос работает с протоколом http, поэтому, когда вы пытаетесь получить аудиофайл, используя file://, браузер помечает этот запрос как междоменный запрос. Установите следующий код в заголовке запроса -

header('Access-Control-Allow-Origin: *');
Другие вопросы по тегам