With the fast approaching removal of synchronous XMLHttpRequest
(i.e.: Chrome 88 is removing this), I am looking for the next optimal alternative method to precache a video.
"Sychronous XMLHttpRequest is a horrible idea" - said no one ever
Yes, you're right for most scenarios but this is different.
On android and ios, the company I work for has an SDK that opens a webview in the background, injects HTML into it and waits for the onload
event to fire. This notifies the SDK when the webview is ready to be shown to the user.
It is imperative that when a video plays there is NO buffering whatsoever for the best possible experience.
This is why when the webview is loading in the background, we precache the video synchronously with XMLHttpRequest (which by consequence, delays the onload
event from being fired).
We've thought about some different solutions, and they each have their pros and cons; here are a few:
<link rel="preload" ... />
index.html
page in base64 (if the video weights 2-3Mo, it'll weigh 30% more after converting to base64)(1) is the cleanest method, but requires some heavy changes on our backend for various reasons. There is also no guarantee that the video will be fully cached by the time the browser/webview appears. There is no guarantee that the priority of the precaching will be the same across webviews and mobile browsers. Users can deactivate the precaching features, for example, in their Chrome configuration. It also does not work when the connection is 4G or lower (sigh).
(2) is a hacky and unoptimized method but is relatively simple to implement compared to (1)
What is the next best method to precache a video in the background of a webview/mobile browser that:
onload
event from being triggeredNote: not all users may have a 4g or wifi connection. Note2: tag is in autoplay
To guarantee that there is no buffering when the video is played, the video can first be downloaded as a blob
using the native fetch
API and then converted to objectURL using window.URL.createObjectURL
. This URL can then be used as the source for video element
This is a native API built-in the webview/browser and the compatibility report can be found here Can I use fetch
And instead of listening for onload
event, listen for some other custom made event which you can manually control. This will give better flexibility in future also.
<script>
fetch('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4').then(response => {
//Video Download Started
return response.blob();
}).then(data => {
//Video Downloaded"
let objectUrl = window.URL.createObjectURL(data);
document.querySelector("#myvideoPlayer").src = objectUrl;
//Trigger a custom event here
}).catch(error => {
// Log Error
})
</script>
<video controls id="myvideoPlayer"></video>
The new solution is by using the Cache API
caches = window.caches;
caches.open("app-assets").then((cache) => {
cache.add(linkToFileToBeCached).then(() => {
// Now the file is cached. Start rendering the app!
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With