Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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" />

Ответ 2

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

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

Шаг 1: создайте звуковой шрифт базы 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 destination (the speakers)
    source.noteOn(0); 
}, function(err) { console.log("err(decodeAudioData): "+err); });

И это! У меня это работает через мою настольную версию Chrome, а также работает на мобильном Safari (iOS 6, конечно, поскольку Web Audio не поддерживается в более старых версиях). Загрузка на мобильный Safari (не менее 1 секунды на настольном Chrome) занимает пару секунд, но это может быть связано с тем, что он тратит время на загрузку звуковых шрифтов. Также может случиться так, что iOS не позволяет воспроизводить звук до тех пор, пока не произойдет событие взаимодействия с пользователем. Мне нужно сделать больше работы, глядя на то, как она работает.

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

Ответ 3

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

Это относится к ios6, поскольку предыдущие версии ios не поддерживали веб-аудио api

Ответ 4

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

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

header('Access-Control-Allow-Origin: *');