783

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.

or
Topic 0 00:00

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.

Topic 1 00:40

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.

Topic 2 02:07

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.

Topic 3 03:00

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.

Topic 4 04:21

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.

Topic 5 05:21

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.

Topic 6 06:23

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.

Topic 7 10:30

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.

Topic 8 18:16

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.

Topic 9 22:21

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.

Topic 10 23:07

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.

Share