Stack Overflow Asked by kemicofa ghost on November 12, 2021
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>
Answered by Prakhar on November 12, 2021
If you are loading an html page - use preload="auto" in the video tag. This tells the browser to download the entire video on page load (the default is preload = "metadata" which downloads 3-5% of the video).
You can then look at the mediaEvent canPlayThrough
to fire to know when the video is ready to play(MDN reference).
Have you thought about streaming the video? A properly configured stream should begin playback immediately, and have little to no buffering as the adaptive bitrate algorithm can change the video delivered based on the device screen AND network throughput. api.video has a great service (with SDKs for iOS, Android and several web backends)
Answered by Doug Sillars on November 12, 2021
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!
});
});
Answered by Menas on November 12, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP