Воспроизведение кешированного аудио в оффлайн режиме в Safari под iOS долгое время было настоящим испытанием, которое было признано недостижимой целью. Но с приходом веб аудио API (только в движках WebKit), это наконец-то стало возможным, несмотря на то, что вам все-равно придется сделать несколько шагов.
Плохая новость в том, что вы все равно не сможете кешировать mp3 файлы, используя кеш приложения и просто загружать их используя XmlHttpRequest
. Safari под iOS 6 будет кешировать mp3 файлы, но потом молча откажется воспроизводить их (очень полезно!)
Base64 идет на помощь
Благодаря тому, что веб аудио API предоставляет разработчикам прямой доступ к аудио буферу, вы можете изменять формат данных на лету и передавать их напрямую веб аудио API для воспроизведения. Например, если вы закодируете mp3 файл в base64 строку, то потом сможете его раскодировать в ArrayBuffer и конвертировать сырые аудио данные.
Кодирование аудио файла
Вы можете легко конвертировать mp3 файл в base64 строку использую OpenSSL. Если вы работаете под Mac OS X, где он предустановлен, просто откройте Terminal.app и введите следующую комманду:
openssl base64 -in [infile] -out [outfile]
Замените [infile] на путь к вашему mp3 файлу, а [outfile] на путь для сохранения закодированных данных.
Комманда сохранит, закодированное в base64 строке, представление аудио файла. Затем вы можете закешировать эту строку, используя любое веб хранилище на ваш выбор (например, кеш приложения, локальное хранилище или webSQL)
Base64 в ArrayBuffer
Чтобы преобразовать base64 в ArrayBuffer, вам нужно использовать свое решение. Посмотрите решение base64-binary.js Даниэля Гуерро(Daniele Guerrero). Это хороший скрипт, который создан специально для этой цели. Он преобразует base64 строку в Uint8Array и сохраняет его в ArrayBuffer.
После этого вы можете просто декодировать аудио данные используя медо decodeAudioData()
из веб аудио API.
var buff = Base64Binary.decodeArrayBuffer(sound);
myAudioContext.decodeAudioData(buff, function(audioData) {
myBuffer = audioData;
});
После перекодировки аудио данных, передайте их на аудио буфер и воспроизведите звук:
mySource = myAudioContext.createBufferSource();
mySource.buffer = myBuffer;
mySource.connect(myAudioContext.destination);
mySource.noteOn(0);
Демо и исходный код
Посмотрите онлайн демонстрацию и исходный код с дополнительными примерами использования техники из данной статьи.
Поддержка браузеров
Представленные демо работают под Safari 6, Chrome Desktop и Safari под iOS6. Техника, потенциально, может работать в любом браузере, который поддерживает веб аудио API, поэтому, надеемся, Chrome Mobile скоро добавить ее поддержку.
На данный момент, W3C продвигает веб аудио API как стандарт.
Автор: druf