Источник HTML Audio из кеша
Я создаю веб-приложение для воспроизведения некоторых аудиофайлов в автономном режиме. Я прочитал и протестировал часть Cache API Service Worker и могу легко добавить все свои аудиофайлы в именованный кеш. Тем не менее, браузер, кажется, не использует его, когда я добавляю <audio src='/audio/file.mp3'>
в DOM и play()
это, даже если этот точный URL-адрес добавляется в кэш.
В некотором смысле имеет смысл, что кеш не используется автоматически, так как тогда не было бы никакого смысла в присвоении имени кешу.
Я использую create-реагировать-приложение, и, поскольку я не изгнал, я не контролирую Service Worker. Однако, насколько я понимаю, не рекомендуется кэшировать большие файлы заранее, поэтому я создал функцию в пользовательском интерфейсе, которая позволяет пользователю решать, когда кэшировать все файлы.
Мой вопрос: как я могу поместить кэшированный аудиофайл в аудио элемент?
РЕДАКТИРОВАТЬ: Я думал, что проблема должна быть понятна из моего вопроса, но попросили добавить код, так что вот что я попробовал.
В разметке есть аудио элемент и две кнопки. Первая кнопка загружает URL-адрес mp3 в кэш, а вторая пытается установить два источника для аудиоэлемента:
- Вставить блоб из кэшированного ответа
- Установить URL-адрес кэшированного запроса в качестве аудио-источника
Конечно, ни одна из них не работает, поэтому я и пишу это.:)
<div>
<audio src="/audio/shape_of_you.mp3" controls/>
</div>
<div>
<button onclick="addToCache()">Add to cache</button>
<button onclick="playCachedAudio()">Play cached audio</button>
</div>
<script>
function addToCache() {
caches.open('myCache').then((cache) => {
cache.add('/audio/rise.mp3').then(() => {
console.log('cached');
});
});
}
function playCachedAudio() {
caches.open('myCache').then((cache) => {
cache.match('/audio/rise.mp3').then((cachedAudio) => {
cachedAudio.blob().then(cont => {
let audioEl = $('audio');
audioEl.attr('src', cont);
// ...fails with the following error in console:
// HTTP “Content-Type” of “text/html” is not supported. Load of media resource http://localhost:3000/[object%20Blob] failed.
// Cannot play media. No decoders for requested formats: text/html
audioEl.attr('src', '/audio/rise.mp3');
// Works online, but not offline (resource is not found)
});
});
});
}
</script>
Я ищу либо
способ добавить блоб как аудио контент
или же
еще один способ программно заставить браузер гарантировать кэширование списка аудиофайлов для автономного использования.
1 ответ
Здесь упоминаются две концепции. Cache API и сервисные работники. Они часто используются вместе, но не являются частью одной спецификации. Вы можете использовать Cache API без работников сервиса. Это именно то, что вы делаете в коде, который вы предоставили.
Обратите внимание, что использование Cache API никогда не гарантирует, что файлы останутся навсегда, это все еще кеш. Тем не менее, браузеры стараются сохранить файлы.
Теперь давайте посмотрим на проблему. Вы хотите загрузить контент из кэша, если он там хранится, и я предполагаю, что вы хотите загрузить его из сети, если нет. Одним из решений является использование сервисного работника. Работник сервиса работает в фоновом режиме, перехватывая события извлечения (если вы настроили его). Я создал пример приложения ( Исходный код), который использует этот подход.
Аудио-тег настроен с атрибутом src, как вы обычно делаете. Затем у меня есть сервисный работник, который прослушивает выборки событий, проверяет, есть ли запрос на аудиофайл, а затем возвращает кэшированную версию или сетевую версию. Я добавил кнопки, чтобы добавить / удалить файл из кэша, и поле состояния, чтобы увидеть, добавлен ли он. Кнопка удаления и статус не нужны, но хороши для демонстрации.
Обратите внимание, что работник службы использует caches.match(request)
без указания имени кэша. Имя кэша используется только для группировки кэшированных элементов для упрощения обслуживания разработчиком. Это облегчает удаление / замену многих ресурсов одновременно. Также проще проверять кеш в инструментах разработки или перебирать его элементы.
Я не могу ответить, как добавить работника сервиса к вашему конкретному приложению. Обратитесь к документации для создания-реагировать-приложение.