June 17th, 2024 × #podcasting#offline#caching
How We Built a Netflix Style “Save for Offline” Feature Into Syntax
Scott and Wes discuss how they built an offline playback feature for Syntax podcast episodes using the Cache API to save files locally in the browser.
- Excited about using Cache API to store stuff locally in browser
- Sentry tracks errors when working with Cache API
- Cache API allows caching resources without using browser cache headers
- Chrome Cache API storage limit is 6-10% of device free space
- Browser storage options: Local Storage, Cache API, IndexedDB, Service Workers, File System
- Cache API is like browser cache but allows manually storing specific resources
- Saving podcast episodes locally using Cache API
- Summary of saving and loading files from Cache API
- Can list cached files with cache.keys()
- Browser determines cache eviction based on storage usage across origins
- navigator.storage API shows browser storage quota and persistence
Transcript
Scott Tolinski
Welcome to Syntax on this Monday Sanity treat. We're gonna be once again talking about the thing that we all hold so dearly. In fact, we hold it for a long time. Sometimes we hold it for days days. I'm talking about caching. We're gonna be talking about caching, but not necessarily in the ways that we've talked about it before. We're gonna be talking about the cache API, which many people think of as being part of service workers. But we're gonna be talking about how we used it to build a Netflix style save for offline for the application for podcast episodes on our Syntax site. My name is Scott Tolinski. I'm a developer from Denver. And with me JS always is Wes Bos.
Wes Bos
Hey. I am really excited about this because I did not realize that this was the EPA that you needed to to store stuff locally, in the browser.
Excited about using Cache API to store stuff locally in browser
Wes Bos
I always thought it was, like, file system APIs or IndexedDB, and turns out that there JS a really nice cache API that's not just service worker. I've used it plenty of times as service workers, but not for storing data in the browser. And I've always wondered myself, like, I would love to be able to, for my courses, like, save them in the browser,
Scott Tolinski
so people can watch them, but still get the whole streaming experience. You know? Yeah. I know. The the solutions I thought of for that at some point because I thought about the same thing when I was doing Vercel up tutorials Wes, I guess, I'm gonna have to make an electron app. Right? Making a desktop app. And then, therefore, they could download the course and then have it be easily work with the file system that way. Because the browser file system, if if we haven't, taken a look at that yet in fact, maybe I should even pull that up here. Before we even get too deep into this, if you are listening on audio, we'll be showing some stuff on video here. I know I know I've said that a couple of times here, but I'll be pulling up API docs. I'll be showing some code. We're gonna make the experience of the episode work just fine with audio as Wes. But I will be showing some things like this, like the file system API. And you can see with the file system API, browser support is not yet here. Works with Safari, works with Chrome, works with Edge, does not work with Firefox fully.
Scott Tolinski
Now this is gonna be the type of thing that's potentially gonna throw an error in your system if you're, what, if you're trying to load up the file system API and it doesn't exist and you don't have permissions for it. And for something like that, you might want a tool like Sentry at Sentry dot ioforward/ syntax. Sign up and get 2 months for free, and it'll track and log all of the errors in your application. And that's gonna be really handy if you're working with things like a cache. Right? You don't know what you don't know if you're trying to save things. So why not use the file system API for storing this kind of thing? One, it doesn't work on every browser. 2, you do have to get permissions and how like, you click a a thing to access the file system API. In fact, I I did a whole course using the file system API, and it pops up saying like, hey. The browser wants to access your local files. I think that could freak some people out. It's kinda spooky when it happens. Freaked me out. Yeah.
Sentry tracks errors when working with Cache API
Scott Tolinski
So, you know, I I think there is some reason there. I wanted this to just work transparently. Like, you you hit a button. It saves to your system. That's it. Right? So that's why I reached for the cache API, which is, like you mentioned, you mentioned it being related to service workers. It's a part of the service worker API.
Cache API allows caching resources without using browser cache headers
Scott Tolinski
And I think because of that, people don't realize you don't have to use it within service workers. And in fact, somewhere in this mess on the MDN docs of paragraphs, it says, hey. Just because this is a part of the, service worker API does not mean you need to use it in service workers itself. It does need to be in a secure context, HTTPS, all that stuff.
Scott Tolinski
Not really super surprising there. But, hey, man. What is the cache API? It's basically a way for you to access and cache things in a request response way without having to do it via the browser cache or caching headers. You're essentially creating your own, cache response directly in the browser.
Scott Tolinski
And it's it's really pretty simple.
Scott Tolinski
So we're gonna be diving into 1, how we pulled off what we pulled off on the syntax site, maybe some gotchas, and then we're gonna be talking even further about persistent storage and, sizes of storage and those types of things. So first and foremost, like I said, cache API.
Chrome Cache API storage limit is 6-10% of device free space
Scott Tolinski
You could do a lot with this stuff. You can put anything in here. There is some caveats there in terms of size. So Chrome. Chrome is probably the best for this because Chrome lets you store a percentage.
Scott Tolinski
Typically, six to 10% of the device's free space, meaning that if your device has a 100 gigabytes free, you could store anywhere from 6 to 10 gigabytes, which is kind of wild compared to when you see some of the limits of some of these other ones, where Firefox has a a global limit of 2 gigabytes for all storage API APIs combined. This is cache storage.
Wes Bos
It's any any of the storage APIs on your browser. Yeah. Because there's there's lots of ways there's lots of ways to store data in the browser. Right? You have local storage. You have IndexedDB.
Wes Bos
You have what are the other ones? Cookie. I just sent you a whole list. Is cookies coming from that? I guess that's not right. Probably not. Local storage, cache API, IndexedDB, service worker, and file system. So you talked about the file system API.
Browser storage options: Local Storage, Cache API, IndexedDB, Service Workers, File System
Wes Bos
We're talking about the cache API here. IndexedDB is kind of like local storage, but it's a bit more flexible for doing, like, full blown database stuff, and then local storage is just a nice key value store. What I'm what I am curious about this cached API is that it's you said it's based on request and response, meaning that those are web requests and web response. And and that's generally, the way that works with with a service worker is that when the browser requests like a a CSS file, you can write a service worker to jump in the middle there, and then you can say, oh, I've I've I've already stored this and and send it on back because it's in the cache API. But when you're not in a service worker, that's primarily a fetch request. Right? Mhmm. The thing you need to think about this is that it it is essentially
Scott Tolinski
the same API that you use with caching headers. Right? You're caching things like normal. It goes into the the browser cache, and that is a request response as well. Right? You cache a font or you you cache an image.
Scott Tolinski
When you pop open your network tab, you see that being loaded directly from the cache. But it's not like it's not like a key value store. It's the request and response. It just happens transparently behind the scenes. What this API allows you to do is just step in and store anything that you want in that same caching mechanism, which which is comes in handy for all kinds of things. You might be wondering why we don't just cache it via HTTP caching. I'll talk talk a little bit about that. But before we get off that, Safari only has a limit of 500 megabits, megabytes. Did I say bits? 500 megabytes per domain.
Cache API is like browser cache but allows manually storing specific resources
Scott Tolinski
And if it exceeds that limit, Safari will start removing items from the cache to make space for new data, which is one of the reasons why tools like what Riverside that we used for recording, you can only use it in Chrome because simply recording that much video, is not gonna work in Firefox or Safari because you're gonna hit those limits probably while you're recording, which that's no good. Right? Yeah. I was just just looking at,
Wes Bos
I'm in the dev tools right now for Riverside as we're recording this, and they are sticking it in, IndexedDB.
Wes Bos
Yep. And you can see the little chunks. Like so there's a there's a API in the browser called media recorder. Node sure if they're using media recorder or not, but the get user media will give you chunks of the user's video, and you can put those into the browser storage so that you can upload them as you have as you have space to do so. And I was always curious what that looks like. And I guess the reason why they're using IndexedDB here instead of the cache API is because, like you said, cache API is only for Wes ESLint response. Right? It's not for, oh, I have a I made an image in the browser, or I have this canvas element that I wanna be able to persist, offline in in when I refresh. If it's not actually a a request to a server, those the cache API is not for that. Right?
Scott Tolinski
Yes. Yeah. And it's I think I I I wonder if I I could have just done this in Index TB as well. Honestly, I don't know. But there I think this was the best approach for me, and I'll I'll talk a little bit about why. I think so because Yeah. Because it's the end of the day, the MP 3 for the show is
Wes Bos
a request. Right? Yes. So it it makes sense that you would request you would save it.
Scott Tolinski
Yeah. Although the way I am accessing it, I kind of am accessing it like a key value store. Let's talk real quick about eviction.
Wes Bos
That is when the data is gone because you cannot promise that the data will be there forever.
Wes Bos
We'll talk about persistence in in just a second, but, eviction is when, at some point, your hard drive is going to get full. Between all of the origins, which is like a domain name on a browser, you're going to be using too much of the space, and there's only so much that Chrome can be allowed to use on your user's computer.
Wes Bos
And when you get close to that limit, the browser will just purge it for you. So I always like to think of these caches JS, unfortunately, you can you can keep them there for fairly long, and it it works fairly well. Like, we use Riverside, and I don't think ever we've lost a recording. Maybe maybe once.
Wes Bos
But at a certain point, the browser will purge it, and you cannot guarantee that it will be there forever.
Scott Tolinski
Yeah. I like to think of these things as, like, questionable storage. Not that it's questionable if it will work, but questionable if it will be there. Right? You you can put things in here, but you can't always assume that it's going to be there because, again, because of storage limits, how the different browsers work or time or any of that different menu, open it up on 1 browser profile and another. So you can't always rely. You kinda have to take it JS, like, hey. I'm checking to make sure that the the cache exists first before, doing anything. So how exactly are we using it, and what are we using it for? I mentioned a little bit about this. I'm gonna show a quick demo here. I have the the code open. I have a website open if you're watching on YouTube, if you're watching on your podcast player. If not, I'll describe it, basically.
Saving podcast episodes locally using Cache API
Scott Tolinski
And and I'm gonna preface this. This is still in dev. This is a, the interface is not complete for this yet. So the way this works is that I have a little pin here in the player. And if I click the pin, it's downloading the MP 3 right now, and it's downloading it and storing it as a blob. When it's completed, the pin kinda goes straight up and down. Again, UI is still being worked on here. But one thing that you'll notice happen is in my dev tools over here, which is in dev tools application cache storage.
Scott Tolinski
You'll see I have an MP 3 cache here. And now right over here, since that is completed, I have an MP 3 cache where the essentially, the name of it is the request URL. So just syntax forward slash and then an m p three. I chose this URL ESLint a a URL that's not going to be hit in the site necessarily.
Scott Tolinski
That's not too important. Either way, you can see that you can see when it was stored, the size of it, the re response type. And if I click on it, yeah, there's no preview, but you do get the headers and stuff here. So now if I were to go and play this file, if I head to my network and I click play episode, you can see that Wes did that go? Where's the blob? Okay. So I filtered by media, and you can see that instead of trying to load this from Libsyn, which is where we host our m p three files, you can see it's actually loading it directly from local host as a blob here. So you can tell size is 0 0 bytes because it's Scott stayed in storage. You didn't have to download anything from the Internet. So, therefore, this is now officially loading this file from the local storage not local storage, but from my caching API as a blob. So how do we do this in code? Well, it's it's actually pretty simple. Okay? So when we go to save something offline, the first thing we do is we fetch the m p three as we normally would. And when that comes back as a response, we grab the blob from it. So we don't grab JSON or whatever. It's an Npm 3. Right? So we grab the blob.
Scott Tolinski
Then with that blob, what we're able to do is create a new response. Now I created a new response specifically to attach not only, like, content length here, but also metadata here. For some reason, I don't I don't know if this is maybe you can tell me why, Wes. When I was doing this without adding metadata Tolinski creating a new response and just using the response from the initial fetch, the content length was 0 for some reason. I had to do this manually. I don't I'm not exactly sure why.
Wes Bos
Oh, that's it's it's probably because it was pulling it from your browser's cache initially.
Wes Bos
Yeah. It's it's interesting. I'm not quite sure why. The whole response and, like, streaming thing is is really funky. I was doing that with the the Syntax website as well where I had to, like I was trying to modify a response, and Node was not letting me because I was trying to, like, modify a header. So I essentially had to, like, clone the response and then loop over every single header and add it in manually Yep. Because it was it was kinda funky.
Scott Tolinski
Yeah. So I had to create a new response, and I did so using the blob. I made it a content TypeScript it, audio Pnpm. Again, set the content Tolinski myself. And then the metadata header, what I did is I JSON stringified the entire object of the show data.
Scott Tolinski
Because what we do when we have the syntax player and you click click play, it doesn't just load the MP 3 file. It has the title. It has, link to the episode. It has, like, share stuff. It has a lot of information in there. But if you're just doing a request and response to save an MP 3, and if I was going to just cache that MP 3 response without the metadata, it wouldn't have any of that. And then you'd click play, and, yeah, you'd get the audio, but you wouldn't get all the other stuff. So I added the metadata header. I used the JSON stringify through all the show information in there. So that way, when we do load from cache, we can retrieve that information and load it up like normal.
Scott Tolinski
So to actually do the caching bit since I I've just created the response, all we did is we do caches, which is a global, dot open, and then you give it a name. You'll notice Npm 3 cache was the exact same name that we saw in the browser dev tools when I looked at my application cache right here. It's the the name that you're giving to this bucket.
Scott Tolinski
So by giving your information or your cache a name, you're essentially making a bucket.
Scott Tolinski
So once the cache is open, it returns a promise, so I do a then, and then I can do cache Scott put Wes I then give it a URL, which is essentially the key of a key value and the response, which is essentially the value of the key value even though it is a request and respond. It's a URL and a response. Not a request, so to say, but a URL and a response.
Scott Tolinski
That's it. That's really it. I can then, if if if you do cache dot put, there's no async response or anything like that. You can just be assured that it's in there, which is neat. It works really well. One thing that I had a little bit of trouble trying to do that I would like to try to do again, Wes, was Yeah. Streaming this.
Scott Tolinski
So that way I could get, like, a progress of how long like, where I'm at in the downloading into the cache process because you can do that.
Scott Tolinski
And I had it working to a degree, but I was still kind of new to what I was doing. So I would like to to try to get Node that I have, like, a fully working implementation.
Scott Tolinski
I I'd, like, paired it back a bit. You know Wes you, like, work on something really, foreign to you that you haven't done before, you try to do a lot of stuff, and you're like, let me pull this back a little bit to the bare bones so I can get it working. So that's where I'm at right now. Okay. So this is the whole bit for saving it in the cache. Once you do this, whatever you're trying to save into the cache, you open, you put, it's in the cache.
Scott Tolinski
How do you get something from the cache manually instead of, like, having it be the browser's request for that thing? Well, I'll show you that now. It's within the player state here. So we wanted to have this work very transparently where the user JS not going to necessarily know if they're playing from local or not. So I wanted to be a part of the normal play flow. And the normal play flow, again, JS you click play, it loads up the data, it loads up the MP 3, it saves it all to a Svelte writable, and then it opens up the player. We have a big old state object here. This might be the largest state object I've ever written in Svelte. So how do we load it from cache? The first thing we do is we open our cache of the same name. So Npm 3 cache returns a promise. You await that, then you have access to your actual cache. From there, all you have to do is a dot match with the string of the path, and it will give you a response. That's a normal response.
Scott Tolinski
With that normal response, what I did is I first got the metadata headers. I parsed it as JSON, and then I I essentially returned it as part of the data.
Scott Tolinski
And then I replaced the URL of the data that the player JS typically looking for with a URL created from the blob. You can do that with URL, create object URL, pass in the blob. That gives you a blob URL.
Scott Tolinski
Guess what? An audio player, you you might not know this. You might. An audio player does not care if it's a dotmp 3 URL or a blob URL. It will play the audio as long as it's valid.
Scott Tolinski
So that's pretty much it. That's the whole process. So when you click play, it really quickly checks to make sure that something is in cache. If it's not in cache, gets out and plays the normal one. If it's in cache, loads it up, makes it into a blob URL, plays it in the audio player.
Summary of saving and loading files from Cache API
Wes Bos
That's awesome. I was just looking up your streaming thing that you're asking about, and I remembered that we did a show on on streaming. And when you want to both use a stream for something, like save it to the cache and view the progress, you can't do 2 of those things at once. Right? You're either you're either saving it or you're viewing the the actual progress. If you do want to see both of them, you have to use the dot t method, and that will basically t split it split the stream. In in one of them, you can create a reader that will see watch the progress, and then the other one, you can throw you could probably just pass directly into the cache API.
Wes Bos
Although adding that metadata, it might get a little bit angry that you're trying to modify the headers Yeah. Before you put it in. That's probably the issue you had.
Scott Tolinski
The metadata piece was interesting because I did think, like, alright. Here's another way I could do the metadata. I could toss it all in local storage and just with, like, a key of the same key as the cache. And then when I'm loading up the URL, I just let that that's very valid.
Scott Tolinski
I think I could have done that as well. I think this for me was just like, alright. I'll I'll put it all in Node spot, and it'll be easy. So maybe alternate methods that you could do. But as you can see, I can store a couple of these. Boom. It loads pretty quick. I got fast Internet. And every time you you save 1, here, another one pops in.
Wes Bos
Oh, that one. What what's that issue you just got? I think it's related. Failed to fetch MP 3.
Scott Tolinski
Okay. Headers. Something might be wrong with that MP 3 itself.
Scott Tolinski
Oh. I'm a I'm on a local build of the site here, so and and it's not guaranteed.
Scott Tolinski
Oh, wow. Another one failed to construct a response.
Wes Bos
Contains an ISO. Non ISO code point.
Scott Tolinski
Woah.
Scott Tolinski
Alright. I got some googling to do. Like I said, this is still a a, it's still in my development branch. But for generally, it's working. At least the first 2, it works. So I got I got some googling to do about whatever this, ISO code point is. I'm wondering if it has something to do with the file name. I don't know idea. Let's try this one. This is a pretty generic file.
Wes Bos
Yeah. This one's working. There Wes go. It's probably there's probably something in the show notes that is not a string of fine. Like that. Okay. Yeah. You're doing JSON Node string of of the show and there's probably something in there. And if you're trying to set that to a header, you're trying to stick the entire show into a header as storage. Mhmm. It's probably
Scott Tolinski
there's probably a weird character in there that it's not okay with. Well, here's what I should do then, Wes. I should remove the show notes because we don't need the show notes for the player.
Scott Tolinski
Yeah. We just we really just need things like the show title and some metadata there. We don't need we don't need the we don't need the show notes saved in there. So I I got some work to do, so to say.
Wes Bos
Yeah. But But even even then, if if somebody's name has, like, a an accented character in it Yeah. Yarn you gonna hit that? So I'm trying to think just trying to look at the the show notes if they're what it could possibly be.
Scott Tolinski
Well, these 2 let's see. This one has a colon, and this one has an ampersand or a, let's see if this one has I think a lot of them have colons, and I don't think the colon's the problem. So you're right. I bet it's something in the show notes itself.
Scott Tolinski
Mhmm. You can also
Wes Bos
Node it, but then you got all those problems as well.
Scott Tolinski
Yep. So bugs to work out, bugs to work out. But for the most part, I got 4 here saving, and it's it's working. You'll be able to very soon. And and I'm gonna say by the time you're listening to this episode, this interface will be tweaked, and this will be available for you. But you'll be able to store these files locally on your computer to play offline or your phone or whatever. What about if, like, we had something where you went to the shows and there was a filter for offline saved, is are you able to pull out and, like, loop over and show them, or or how does that work? Let's check the, the cache API. I would imagine you do keys here. I I'm not positive. I have not thought about that. But keys, yeah, you open, you get the keys. Hey. Bingo bango, Wes. That's it.
Wes Bos
Yeah. Nice.
Can list cached files with cache.keys()
Scott Tolinski
Yeah. So we'll be able to do that for sure. Another thing I'm gonna be working on in the same regard is, like, queuing. So if you add thing add an episode to the queue, I'm gonna have it automatically saved to your cache.
Scott Tolinski
So that way, you know, it's like preloading,
Wes Bos
essentially for MP 3 files. Pretty neat. Awesome. One last thing we wanna talk about is just persistent storage.
Wes Bos
I was always curious about this as to when does it get sort of pushed out. And we talked about the browser.
Wes Bos
Once it gets full, it starts to sort of purge.
Wes Bos
And I found some interesting stuff on online about this. I'm just going to read through it. This is as each origin gets a higher storage limit by default, the browser will evict data by origin, which is a domain name.
Browser determines cache eviction based on storage usage across origins
Wes Bos
When the total usage of all origins is bigger than a certain value, the all the overall quota is calculated based on disk space.
Wes Bos
So, again, it's it says, alright. Well, now Chrome is taking too much of of disk space. What do I do about that? However, at at that point, the browser says, alright.
Wes Bos
What do I delete? You know? Do I just start deleting random stuff? Because some of it will be, yeah, you you cached a CSS file.
Wes Bos
It's fine. We'll just go download that again. And some of it will be more important stuff like, oh, yeah. I I saved a recording that hasn't uploaded to the cloud yet, and the only place that exists is in the browser cache right now. So that's that's pretty important. Right? So there JS an API called navigator.storage JS the API that will allow you to see how much space is available for you to store stuff, and navigator dot storage dot persist is the API that will it used to, like, pop up a thing and says, hey. Can we store stuff in Chrome? And now it's just based on flags, like how often you visited the website, if you've bookmarked it. There's all these things. Kind of the same idea of when you wanna autoplay video. That sounds good to me. Scott allowed to autoplay video unless the user has interacted with the website a whole bunch. There's just, like, a a whole there's a whole bunch of stuff that goes into calculating the score of a website. So I had, now you can Scott just say navigator.storage.persist, and it's it's kind of like a pretty please, can we have elevated, storage? Like Yeah. Like, don't delete us first, please. It doesn't pop anything open, and it simply was returned true or false. So I ran it on Chrome on Riverside, and it it returned true. Why? Because I'm here often. I spend a lot of time on this website. I interact with the website. I've bookmarked it, And then I tried it on a website I've never been to, and it obviously says no, automatic. So I don't know what those flags are by browser. I think it's it's up to the browser to decide what is important and what is not.
navigator.storage API shows browser storage quota and persistence
Wes Bos
But I thought that was kinda interesting.
Scott Tolinski
If that feels mysterious, let me tell you. As somebody who's had to maintain an autoplay feature on a website, man, that is one annoying system to work into because you'll think that you have it working. It works for you. It works for most people, and then, again, GitHub Air. Autoplay does not do anything. I'm like, okay. Great. How am I supposed to debug this when it's not like it's throwing an error or anything? It could just be that they have not interacted with the site enough. And, like, the one thing is that the user has to interact with the site before autoplay works.
Scott Tolinski
I wonder I wonder how much, like, Google I don't I'm not, like, trying to do any conspiracy thinking here, but, like, YouTube has no problems with autoplay.
Scott Tolinski
Is that because is that because YouTube and Chrome are owned by the the same company? I have no idea. You can look it up. It's called Media Score. Let me let me just find it. Chrome look it up?
Wes Bos
Alright. So I'm in Chrome forward slash or colon slash slash media dash engagement.
Wes Bos
And this will actually give you the information about how much a user has interacted with it, and it will give you whether it is a high media engagement score or not.
Wes Bos
And if you have a high media engagement score, that that is one of the ways that you're allowed to autoplay videos. So look at this. YouTube, 16 sessions.
Wes Bos
6 of them, I actually played something.
Wes Bos
Last time I played something was January first just because I I don't use Chrome for anything other than recording this podcast. And then it but it is a high media engagement score. Right? And then all of these other websites here are just, like, domains or origins that I have interacted with, and it has a low media engagement score. I'm kinda curious if I look it up. I I switched to Microsoft Edge.
Scott Tolinski
I this this still this still kinda makes me annoyed that this exists. Like, how am I gonna debug somebody else's? Right? Like, somebody a user user says, I have
Wes Bos
the play method has switched to a promise.
Wes Bos
So what you can do is you say await video Scott play or audio dot play.
Wes Bos
And if you're not allowed to play, you catch it. So just put a dot catch on the end, and and then you can you can say, oh, it's not done. And, yeah, the the real trick, though, is just just listen for any any click at all on the website and play something at that point, and then you're you're in.
Scott Tolinski
I hate that. I hate all of this because, like, some somebody comes to me and they say, hey. I I clicked the toggle that says autoplay. Your videos don't autoplay. The site's broken.
Scott Tolinski
Like, I gotta send an email or I gotta send a response or, you know, catch that or whatever at the moment and say, oh, you haven't engaged enough with the site for autoplay to work even though you clicked the toggle that said, please let me autoplay.
Scott Tolinski
Like, there has to be a better permissions model than, this. You know? But Give me give me just a straight up permissions
Wes Bos
flag. But once you click the button that turns on autoplay, there's your click. Yeah. But what if they refresh
Scott Tolinski
refresh the page? What if they refresh? The toggle still
Wes Bos
doesn't work.
Wes Bos
Then they have well, no. It it that's a good a good point.
Wes Bos
I tested it when I was doing my autoplay, and it was very easy to get a high enough media engagement score.
Wes Bos
I think I think the user had to to watch, a couple minutes.
Scott Tolinski
But even with, like, a high enough engagement store Scott, upon loading a page, the browser still doesn't like it to immediately start playing media when a page has been opened without some sort of click or some sort of anything.
Wes Bos
No. You can do it if your media engagement Scott is not I Node, but it doesn't like it.
Scott Tolinski
I'm telling you. Doesn't like it? The browser? The browser gets angry. It says, no. Thank you. Yeah.
Wes Bos
No. You're no. You're wrong about that. As long as your media engagement score is higher, and I'm reading it right Node, consumption of media must be greater than 7 seconds.
Wes Bos
So as long as you can play something for 7 seconds that is in unmuted state, you can you could do that. And I bet you could get around that by playing a permission flag. Just give me a yes. Give me a yes or no. Come on. Yeah. It's true. Are you are you going to allow this? Because, honestly, there's most websites I don't want autoplay on unless it is actually a video website like, like YouTube or a core my course platform.
Scott Tolinski
And guess what? I'm a big boy. If that pops up and says, would you like the site to autoplay video? I click no and feel good about that. I want I want the browser making choices for me about which which sites I I can autoplay video on this. I think, also, people hate that, though, because
Wes Bos
Another problem. Permissions like, you see this on Ios all the time. They pop a permission up, and they try to do, like, a fake permission. Because if you're gonna click no, they don't wanna show you the real one because then you gotta tell the user how to go into your settings and and turn it off. Like, once they hit no, you're it's over. There's no normal people are not turning that setting back on.
Scott Tolinski
Yep. Man,
Wes Bos
no fun stuff. Permissions is a hard thing. Yeah. Alright. I think that's good enough for today. Hopefully, you enjoyed that. We'll catch you later.
Wes Bos
Peace. Peace.