Можно ли кэшировать все видео HTML5 с помощью API Service Worker для автономного использования?
У меня есть автономное приложение, которое кэширует все статические ресурсы. В настоящее время кэшируются только первые 15 секунд видеоактивов.
Ниже показаны основные реализации прослушивателей событий
install и fetch.Работник Службы:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/',
'/videos/one.mp4',
'/videos/two.mp4'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
if (response) return response;
return fetch(event.request);
});
);
});
И в index.html
<video controls preload>
<source src="/videos/one.mp4" type="video/mp4">
</video>
1 ответ:
Я использовал следующие шаги для выполнения автономного видео При загрузке первой страницы без предварительного просмотра всего видео (ов).
- зарегистрируйте работника службы и кэшируйте все запросы. Статические активы-это просто
'/'для этого случая. Если вы проверите событиеfetchработника службы, вы увидите, что последующие запросы также кэшируются.- используйте API
fetchдля запроса видео в качествеblob.Пример использования fetch для запроса видео в качестве blob
const videoRequest = fetch('/path/to/video.mp4').then(response => response.blob()); videoRequest.then(blob => { ... });
- используйте API
IndexedDBдля храненияblob. (ИспользуйтеIndexedDBвместоLocalStorage, чтобы избежать блокировки основного потока во время хранения.)Вот оно! Теперь, находясь в автономном режиме, работник службы будет перехватывать запросы и обслуживать как
html, так иblobиз кэша.Индекс.html
<!DOCTYPE html> <html> <head> <title>Test</title> </head> <body> <h1>Service Worker Test</h1> <p>Try reloading the page without an Internet connection.</p> <video controls></video> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js').then(registration => { console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(error => { console.log('ServiceWorker registration failed: ', error); }); }); } else { alert('serviceWorker is not in navigator'); } </script> <script> const videos = { one: document.querySelector('video') }; const videoRequest = fetch('/path/to/video.mp4').then(response => response.blob()); videoRequest.then(blob => { const request = indexedDB.open('databaseNameHere', 1); request.onsuccess = event => { const db = event.target.result; const transaction = db.transaction(['videos']); const objectStore = transaction.objectStore('videos'); const test = objectStore.get('test'); test.onerror = event => { console.log('error'); }; test.onsuccess = event => { videos.one.src = window.URL.createObjectURL(test.result.blob); }; } request.onupgradeneeded = event => { const db = event.target.result; const objectStore = db.createObjectStore('videos', { keyPath: 'name' }); objectStore.transaction.oncomplete = event => { const videoObjectStore = db.transaction('videos', 'readwrite').objectStore('videos'); videoObjectStore.add({name: 'test', blob: blob}); }; } }); </script> </body> </html>Работник Службы
const latest = { cache: 'some-cache-name/v1' }; self.addEventListener('install', event => { event.waitUntil( caches.open(latest.cache).then(cache => { return cache.addAll([ '/' ]); }) ); }); self.addEventListener('fetch', event => { // exclude requests that start with chrome-extension:// if (event.request.url.startsWith('chrome-extension://')) return; event.respondWith( caches.open(latest.cache).then(cache => { return cache.match(event.request).then(response => { var fetchPromise = fetch(event.request).then(networkResponse => { cache.put(event.request, networkResponse.clone()); return networkResponse; }) return response || fetchPromise; }) }) ); }); self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.filter(cacheName => { if (cacheName === latest.cache) { return false; } return true; }).map(cacheName => { return caches.delete(cacheName) }) ); }) ); });Ресурсы:
Comments