Click here to follow along: https://tinyurl.com/3xyj6mf4
This channel is totally free to watch! I sign up for partner links when I can as a way to keep this channel going. If you like watching, please give me a click :)
00:00 Introduction
01:02 How to Optimize your Videos
11:40 What is ABS?
14:37 How to handle ABS
17:47 Build an Optimized Video Streaming App
39:40 Recap
Final code: (COMING SOON!)
⭐ Learn JavaScript with my Course here: https://www.codewithania.com
⭐ Check out my IDE here: https://jb.gg/GetWebStormForFree
⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/aniakubow
Оглавление (6 сегментов)
Introduction
Buffering. The most frustrating thing in video apps. Am I right? Today I'm going to show you how to build your own buffer-free video app using ImageKit. io and adaptive bitrate streaming. This means your videos will automatically adjust to every viewer's network speed, so they play instantly, whether someone's on a slow 3G connection or a 4K monitor. We'll go through everything step-by-step, starting from how to optimize your videos, what is ABS, how to handle ABS, and how to generate multiple quality versions, and finally use everything we've learned to build an app that streams videos smoothly with zero buffering. By the end, you'll have a fully functional smooth streaming app that works across all devices and connections. And you can use it to build whatever you wish. If you've ever wanted to make apps like Netflix, YouTube, or your own private video platform without the headache of buffering, this is the tutorial for you. So, what are we waiting for? Let's get started by clicking on the link in the video description below. Chapter 1: How
How to Optimize your Videos
to optimize your videos. First, let's talk video optimization. When building apps with videos, these video files can be large in size, and slow loading times can degrade the playback. In addition to that, posters and thumbnails for videos are usually a pain. You have to render them, store them, link them. So, in this section, I'm going to show you how to automate many aspects of video optimization for web delivery, as well as get posters and thumbnails from the videos themselves, instead of creating and storing your own. Okay, so I'm going to demo this using Next. js. However, if you don't know how to set up Next. js or a Next. js project, don't worry because I'm going to be showing you how to do this from scratch when we build a project later on in the video. Or if you don't want to use Next. js at all, I will also show you where you can get starter code for JavaScript, React, and so on. Okay, but for now, let's look at how to optimize your videos in a super simple way. So, what I mean by this is that the videos that you store on imagekit. io, so for example, the videos in your media library. So, right now we have a sample video called sample-video. mp4 and a default image called default-image. jpeg. If you sign up to imagekit. io, you should have these two sample files in there, too. And all we're going to do is get this video and optimize it to play on our apps, as well as do a bunch of other cool stuff, which I can't wait to show you. So, in order to do that, we first need to communicate with imagekit. io, and for that you need your URL endpoint. Yours, of course, is unique, so please don't copy mine. I will be deleting this one. Please get your own. So, just copy that because we will need to use it later on. Now, let's get back to our code. So, I'm just going to save this for now in my file, so const URL and simply save it as a string like so. Okay, so all you should have in your Next. js project at the moment is a layout. tsx file, which just has the default code in here. So, we are importing the type metadata from Next and importing our global CSS file. So, in other words, our styling. These two lines bring in things our page needs. So, metadata is a Next. js helper for setting the page's title and description, or in other words, the text you see in the browser tab and in Google, and that is why I define it here. So, here we go. The title of my app is ABS streaming demo, and we also have a description. Great. Next, we also need to export the root layout wrapper around every page on the site. Think it like a picture frame. The frame stays the same, but the picture inside, or in other words, each individual page, can change. Right now, our frame is so super simple, just a basic HTML page that drops the page contents directly into the body element. Okay? Great. So, let's move on. So, first things first, we're going to have to add use client here. Use client is a Next. js label that essentially says, "Run this page in the browser, not on the server. " Why? Because we're going to play a video, and a video playback only happens on the user's device. So, your phone, your laptop, your TV, and so on. Next, we're going to import two things from ImageKit. So, these are two ready-made tools from our video service. They are video, which essentially is a smart video player, like a beefier version of YouTube's embedded player, that we can use to essentially handle all the hard stuff. We will look into that soon. We're also going to use build source, and this is a little helper that builds web addresses, or URLs, for our video files and thumbnails. It's essentially a kind of address generator. So, let's go ahead and import that. So, I'm just going to get up my terminal, and making sure we are in the project. Mine is called video playback. I'm going to do npm i imagekit/next, and that's going to do its thing. And great. So, if we look in here, we see imagekit/next, along with its version. So, if something isn't working for you, perhaps you're watching in this in the future, it could be down to the version you are using. So, I would just go back, change your version to this, and run npm i again. Okay? So, that is just something to keep in mind. Great. So, of course, we have our URL or in other words, the home address of our video library on ImageKit's service. So, again, just imagine this as a giant warehouse on the internet and this URL is where it lives. And we have the key to it thanks to our unique little identifier here. Every video, every picture, or every preview we ask for will come from this address. Now, we need to specify which video we're looking for in our giant warehouse. So, let's do it. I'm going to define this as const video source and we're literally just going to go back here, go to our media library, and whatever this is called, I'm just going to copy the name and paste it in like so. So, we are specifying what video looking for in our media library or our warehouse. Now, what is cool is that we only really ever need to upload one high-quality copy of the video and ImageKit will handle making these smaller, internet-friendlier versions of it for us automatically. So, this is what we're talking about video optimization. That is something that we're going to explore. So, let's have a look at getting this video showing. So, I'm just going to export the page. So, export default function page and then let's return the video that we essentially imported from ImageKit. So, this component has been imported from ImageKit and we're going to have to pass through a few things. So, the first thing we're going to pass through is the URL end point. So, that is literally our URL. Okay, so this literally tells the video player, get the video from this warehouse. Okay, this warehouse that lives on the internet. And of course, we need to tell it which video. So, I'm just going to pass through the video source. Easy. I mean, it really couldn't get any easier than this. Okay, there are a few things we can pass through, but I'm simply just going to pass through controls for now for this demo. We'll look at passing through more things when we build out our project towards the end. For now, controls is what I'm going to use in order to show the play button and the pause button on the video itself. So, that is an option that I have chosen to display. Okay? So, let's save this and spin it up. I'm simply going to get my terminal and do npm run dev in order to run the project. And there we go. So, let's open it up on localhost 3000. And there is our video. So, as you can see, the video is here and we have the controls to play it as well. This is looking good. So, now if I simply hit play, the video, the 6-second long video, will play. Amazing. But, we are not yet done. I want to show you a few more cool things. So, let's go back in here and I'm just going to minimize our terminal. Now, one super cool thing that we can do is create a poster for the video. So, if we go poster like so, I'm going to use build source to essentially pick out a frame from the video itself. This is great because it means we don't have to upload any images or anything like that. No, we are literally taking it from the video itself. So, what we're going to do is just open this up and pass through an object. And that object is just going to have the URL end point and just assign our own URL to it and then the source. Well, I'm going to use backticks and then pass through the video source and simply append {forward slash} ik thumb nail {dot} jpeg. Okay? Great. And that's it. So now a thumbnail has been applied to the video. And the coolest part, if I want to choose which frame to have, so for example, maybe I want a frame from here or here, so second two, I can do so. So still in the build source function, so in this object, I would pass through transformation and then open up an array and I'm going to pass through start off set two. I'm also going to have to pass through a width and a height as well. So I've gone ahead with width 320 and height 180. And now, tada, you will see that if you refresh the thumbnail has been shrunk. Okay, it's tiny and the thumbnail is different. It's been taken from a different frame in our video. So to be exact, frame from second two. Okay? Great. So here we go. Here is the thumbnail as it is and if you hit play, the video will start from the beginning. You can of course have fun messing around with how big or how small you want the thumbnail simply by changing the width and the height right here. Okay, amazing. So we've looked at a few things for video optimization. One major thing is using a video warehouse, as we called it, to upload just one high-quality copy of a video and use it for multiple things such as creating thumbnails from various points in the video as well as changing the size of the video based on your needs. So in other words, making it smaller and more internet-friendly for us automatically. Let's have a look at that next. Chapter two, what is ABS?
What is ABS?
Okay, so I'm going to show you how to stream videos like Netflix, meaning streaming videos with adaptive quality, instant playback, and no buffering using ImageKit and Next. js. And the whole thing is about 15 lines of code, no joke. So, let's do it. So, in this section we're going to look at ABS or adaptive bitrate streaming. But before explaining it, I think I'm going to show you first for all you visual learners out there. So, for this I'm just going to get rid of the poster for now so we can focus just on the video. Okay? And great. So, at the moment we have our video. It looks great, it plays, it looks fine. However, I'm watching this on a slower internet connection. So, the video doesn't look that great if I'm honest. Ideally, this video needs to shrink. But let's have a look at how that would work. So, let's go back here. So, once again in the video component, we are passing through our URL, so the warehouse where all our videos live, the source which is the video that we are looking for in the warehouse, and the controls. So, in other words, the play button and the pause button that are on the video. Now, I'm going to do one thing to this video source right here and I'm going to change it to ImageKit's HLS or HTTP live streaming manifest endpoint. And this line is essentially the whole point of the tutorial. So, I'm going to use backticks and then I'm going to get the video source and do forward {slash} ik master. m3u8 and then a backtick to close off and great. So, normally a video file is just one big chunk, like a big bottle of water, and if your internet is slow like mine, the bottle takes forever to pour. Now, with adaptive bitrate streaming, or ABR, we instead give the player a menu of different size bottles. So, tiny, small, medium, or large, extra large, and the player tastes your internet speed and picks the biggest bottle you can drink without choking it. The. m3u8 file you were asking for here is that menu. It's a tiny text file that lists all the available video sizes. The video player reads the menu, then keeps switching sizes during playback as your Wi-Fi gets faster or slower. That is what makes the video adaptive. It adapts to you. Okay, so we've looked at adaptive bitrate streaming. It's a technology that dynamically adjusts the video's quality in real time, and pre-encodes content into multiple quality levels. So, essentially it allows you to switch between them seamlessly. We also know how to use ImageKit's HLS manifest endpoint, and we can now focus on setting our streaming resolutions next. Chapter three, how to handle ABS.
How to handle ABS
Okay, now let's get to demoing how to handle adaptive bitrate streaming. Here is the entire app, one page and one video component from ImageKit's Next. js SDK. Okay, and we are not yet done because we still need to pass through the menu with these sizes. So, I'm going to use transformation, and then an object, an array, another object, and this time I'm going to pass through our streaming solutions. So, there we go. Each of these numbers represents a video size. Think of them like t-shirt sizes for a video. You've got 240, this is tiny for someone on slow mobile data. Then you have small for basic mobile, medium, which is okay quality, 720, which is large regular HD, and 1080, which is extra large full HD on fast Wi-Fi. The player will automatically jump between these depending on how fast or slow the viewer's internet is, second by second. The viewer never has to pick anything. So, let's check it out. So now, amazing. Okay? So, that's what it looks like, and let's go back here. Once again, if I just comment this out and use the original source, which was just the video, and let's comment that out. It goes back to being big, but at not great quality. Amazing. So, I hope that makes sense. For now, I'm just going to put back uh adaptive bitrate streaming configuration. Amazing. Now, this might seem a little counterintuitive, but we are going to set the video itself to have a width of 100. Why? Because adaptive stream players don't just look at internet speed. They also look at how many pixels is this video actually being displayed at, which is quite clever. So, even if you're on a fast internet, have a super high-quality video in your ImageKit library, you might still get served a 240 streaming resolution. The player may do so intentionally to save bandwidth and CPU. So, let's change the video to appear larger, and we'll test the streaming rate that we are getting returned back. And great. So, now if we inspect this right here, go to network, let's just refresh, you will see 240 gets served to me fast, and then it changes to 1080. How cool is that? Okay, so that is the basics. I you're now ready to try build a Netflix clone with a bunch more features that I want to show you. This is what it's going to look like. We're going to add text overlays that disappear. We're going to position them. We're going to style them up. We're also going to add on trending now section, which has the same video but thumbnails from different points of the video itself. We're going to add the option to auto play as well as have the video muted to start. And we're going to stop the video from forcefully going full screen on iPhones as well. So, a lot to cover. Let's do it. Okay, so now
Build an Optimized Video Streaming App
we have enough knowledge to build a super simple Netflix clone using Next. js and video optimization thanks to imagekit. io. Our app is going to play a video for us on page load and also have a text overlay for 2 seconds that disappears as the rest of the video plays. I will also demonstrate how we create thumbnails from different sections of our video by passing through the exact second we want to show as our thumbnail. Let's do it. Okay, so let's get started by building a super simple adaptive bitrate streamer that is optimized for our video apps. I'm going to do this with the most minimal amount of code, okay? A fully working app that is done so minimally that you can take this, put in your own video streaming projects, okay? You name it. So, let's get started. I am using WebStorm as my IDE, which makes it super simple to spin up Next. js projects. So, what I'm going to do is click on Next. js. Okay, so this is the command you would use to spin this up in your terminal, but it's already here. All we're going to do is name our project something. So, I'm going to go with ABS streaming demo. And yes, I'm going to select TypeScript to make this a TypeScript project, and then I'm going to run it so it does its thing. So, our Netflix project is being spun up for me. Once again, if you are not using WebStorm, you can do this in your terminal. Just type MBX create-next-app and then whatever you want to call your project and hit enter. Okay. So, when that is done, you will have this. I'm just going to delete what we don't need. Again, this is going to be so super basic and simplified. So, I'm going to delete the agents MD file. cloud eslint. config. mjs file. I'm going to delete the postcss. config. mjs file. And I'm going to delete the whole public directory, so everything in there. Great. So, now if you open up your app directory, there's four things in here. I'm going to get rid of the favicon, like I said, super simple. So, you should just have these three files. And I'm just going to delete everything in them. So, let's get up our globals. css file and delete everything. layout. tsx And let's get up our page. tsx file and delete everything. These are the three files we're going to focus on today. So, before we get started with anything, I'm just going to import the package that we need. That helps us do all of the hard lifting. So, making sure we are in the project ABS streaming demo, I'm just going to do NPM I and then imagekit/next. So, once again, you will remember in the package. json, it will show up along with the version that we are using today. If you are watching this in the future, I would strongly suggest going to this version because you never know, in version three, something might have changed. So, just go back and change this number and run NPM I again. Great. Amazing. So, we are done with the package. json file. I'm just going to also minimize that for now. Let's get started on our layout. tsx page. So, once again, we're going to have to import two things. We're going to import type metadata from next and import globals. css. So, metadata is a Next. js helper, and it essentially helps us set the page's title and description. So, I'm just going to define that now. So, here we are. We are defining our title of our site as ABS Streaming Demo, and we're also passing through the description of adaptive bitrate streaming with Next. js and ImageKit/next. For a real video site, you'd add even more here so that things like Twitter or Facebook can show a nice preview thumbnail when the link is shared. But for now, we're just going with this. And of course, import globals. css will import in our styling. So, everything that makes our site pretty, such as fonts, colors, you name it. Once we have done that, we're going to essentially export the root layout, which is a wrapper around every single page of our site. Okay, the wrapper will stay the same, but the pages will change. Right now, we only have one page file, so that is being passed through into the body element. Great. And that's really it. Our layout. tsx file is completely done. Let's get rid of it. Let's focus on the page. tsx file. So, once again, we're going to put use client at the top because we need to run this page in the browser, and not in the server, because we're going to play videos. And video playback only happens on user devices such as your laptop. Next, we're going to import video and build source from ImageKit. So, video is essentially the smart video player that's going to help us with all the heavy lifting, and build source is our little helper that builds web addresses for our video files and thumbnails. Next, we also need our URL. So, this is our endpoint, essentially the home address of where our video library on ImageKit's servers lives. And for that, we simply go back to our ImageKit dashboard, go to URL and endpoints, and just get yours. So, this is mine. Please don't use mine, okay? I will be disabling it. Please use yours. And just paste it as a string right here. Of course, you do not want to share this with anyone, so I wouldn't really advise uploading this file onto GitHub or anything like that. You should always store your secrets in a. env file. Okay, so I'll put store in. env file. Great. Next, we actually need the video itself. So, const video source equals and then we're just going to literally get the name of the video file. So, we're going to go back here, and in our media library I'm just going to copy the name. That's right. And then we're just going to post it like so. Amazing. So, that's really it for now. Let's get to exporting our page. So, export default fault function page. And we're going to return Well, I'm just going to return an empty element. And in here I'm actually going to use sections. So, our first section is going to essentially store our hero video. So, let's go ahead and put class name hero, so we can pick this out and style as the hero section. And I'm just going to put in the video. So, just like that. I'm going to pass through a few things. So, hopefully you remember this from the earlier parts of the tutorial. If not, I'm going to go through again. So, URL endpoint and we're just going to pass through our URL so we can communicate with our warehouse essentially as we called it. Next, I'm going to put source and I'm just going to pass through the video source for now. So, the video that we want to play that lives in our warehouse. Great. And I'm also just going to add some controls so we can control the video. So, now if we run this, so I'm going to do npm run dev making sure I am in the project and hit enter. And then let's open up localhost 3000 and tada! Here we go. Here's our video. It plays. It's got the controls down here. It looks good-ish. You will notice that the quality is not great. I'm on a slow internet. So, this video should have been served to me smaller if we were using adaptive bitrate streaming. We're not yet, so let's change that. So, let's go back here. I'm just going to minimize this and if you remember, first off we need to use ImageKit's HLS manifest endpoint. And that involves changing this source. So, I'm just going to use backticks. Okay, and let's get the video source like so and I'm going to do /ikmaster. m3u8. So, this line is so important. It's essentially the whole point of this tutorial. So, at the moment we just have one video stored in our warehouse. That one video is called sample-video. mp4. And no matter if your internet is slow or fast, the same video gets served. Instead, we want to give the video player a menu of different size videos to choose from. Okay? So, by adding. m3u8, this is essentially a tiny text file that lists all the available video sizes. So, let's go ahead and add those video sizes. So, if you remember, we used transformation for this. So, I'm going to go ahead and do transformation equals and then I'm going to pass through a array and an object. And I'm just going to pass through these streaming resolutions. Okay, so these are the ones I have. It's going to be 240, which is tiny for someone on slow mobile data, 360, which is still small, more for a basic mobile, medium, then we have large regular HD, and extra large full HD on fast Wi-Fi. And the video player will automatically jump between these depending on how fast or slow the viewer's internet is. Okay, and it will change second by second if it needs to. So, now if we go back here, tada, my video has shrunk. It's smaller because I am on a slow internet. How cool is that? Amazing. So, essentially, these two go hand in hand. Okay? You need to add the transformation and this right here in order to essentially initialize adaptive bit rate streaming or ABS. Great. So, the next thing we learned is how to add a poster. So, I'm going to do that. I'm going to do poster, and then I'm going to use build source. And then I'm going to pass through an object. That object takes a URL end point, and we're going to have to pass through our URL from above as well as a source. And this source is essentially, well, we're going to pass through the video itself and then we're asking ImageKit to grab a frame from the video and use that as a poster so that we don't have to upload our own or anything like that. So, that is pretty neat. So, let's do video source and then forward slash IK thumb nail dot jpeg. Great. So, a thumbnail has been saved. Now, I just want to show you one more cool thing because we can add text overlays. So, this is super easy in transformation. We just add overlay and then we're going to stamp some big text on top of the video but just for the first 2 seconds. So, as it's text, we're going to have to specify the type as text. You got it. And then the text itself, I'm going to go with dream because I think that fits the video. Now, we can also actually position it. So, I'm going to use position. There's a lot of text manipulation that we can do. So, position focus and then the string of center to center it. If I want the text to disappear, I can define when I want it to show. So, start at second zero and then I want it to last for 2 seconds. So, really is that easy. Another cool thing we can do is change the font size, the font color, and the typography. So, I'm just going to add transformation here. Just like that and then this array takes an object and I'm going to pass through the font size. I'm going to make it 180 and then the font color. I'm going to go with white. And then the typography, which I'm going to go with B for bold. Amazing. Some other cool things you can do are add something like autoplay. And this essentially, you guessed it, starts playing the video as soon as the page loads, no clicking needs. I've also going to add muted, so the video starts with the sound off and the viewer can unmute with one click. I'm also going to add plays in line. And this essentially on iPhones, this stops the video from forcefully going full screen. We want it to stay tucked into the page like Netflix does, not take over the whole screen. So we can specify that, too. And great. So here we go. This is looking good. We are done with that, so let's preview it. So this might take a while to update, but when it does, it will look like this. Amazing. So dream shows up and disappears after 2 seconds as an awesome overlay. I love it. So we've just applied everything we've learned so far, plus added a few extra sprinklings. Next, I want to take this project a little bit further with some awesome styling, as well as use these thumbnail builders to add some placeholder images for trending now videos at the bottom as a strip. So let's do it. This part of the video is completely optional and just for fun. So first off, I'm going to start by defining where we want our little six preview pictures for trending now to essentially get a frozen frame grabbed from the video from. So const thumbs equals and then let's say we want six videos. I'm going to use map. And then I'm going to do build source and pass through uh URL end point as our URL and then as the source I'm going to do backticks and pass through the video source {forward slash} IK thumbnail. jpeg. Okay, so as a reminder, this is what allows us to grab a single picture out of the video thanks to ImageKit. And now we're going to use transformation. And this time I want to assign a width and height. So, the width is going to be 320. The height is going to be 180. And the start offset for each video. I'm going to use I and multiply by two. So, that you know, the first thumbnail starts at 0 seconds and 2 seconds and 4 seconds and 6 seconds and so on and so on. Okay, cool. So, that is our thumbs defined. So, now all the way at the bottom, so when our first section ends, I'm going to add another section. Let's give this the class name of row. I'm going to pass through an H2 heading and put trending now. And then just going to grab a div class name cards. And then let's map on the thumbs. So, let's grab the thumbs and use map. And then I'm just going to pass through the URL itself and I. So, what are we going to map this on to? Well, we're going to get a div and we're simply going to do key I as we need a key class name card and style and pass through a background image which So, let's do backticks there and pass through the URL itself. So, the URL we constructed earlier. That includes the offset of where we want to take the thumbnail from. Amazing. We have one tiny styling thing to do and that's up here and just add a header. So, a kind of visual navigation bar that doesn't really do much functionally, but makes it look a little bit more like a Netflix app. So, header class name nav Let's add a span that says Netflix class name logo. Let's have A here. home This won't go anywhere as I said, this is purely visual. Same as the thumbnails. Let's have home. Series, movies, and my list. So, let's change this to say series movies my list and we are done. Great. Great. So, now just the CSS is left. So, this with the whole thing, I'm just going to do box-sizing border-box, margin zero, padding zero. For the body, I'm going to go with a font family of Roboto with two fallbacks. The background is kind of an off-black and the text color is white. This is the shorthand for it and the minimum height of 100 viewport height. Next, for the element with the class name of nav, I've added a position of sticky. I've positioned at the top with a z-index of 10 so it sticks out above everything else. I've used display flex to align items in the center. I've added a gap as well as padding and the background is using a linear gradient. The logo itself, I've just changed the color to be red, added a font weight and a font size of 28 pixels. And for every a element, I've essentially just got rid of the underline, changed the color and the font size. And I also wanted to change the color if we hover over them, so I've done that here, too. Now, the section with a class name of hero, I've also added some margin and border radius to it as well as hidden any overflow and changed the background to be black. For each row, I've added some padding and I also want to change any H2 element that lives inside the rows, so I've done that here by changing the font size to be 20 pixels and the margin bottom I'm giving 12 pixels and also changing the font weight. Now, the cards themselves, which display all the thumbnails, well, I'm going to use display grid for that and format the grid a little bit as well as adding overflow X auto so on the X axis so that it kind of looks like it's scrolling as well as adding a padding of 8 pixels at the bottom. And finally, each card, I have changed the background color and also added a transition. And just rounded off these sides so it's not so boxy. And we also want a hover on the cards and that is for it to just scale a little bit. So that's what I've done there. I've also added the aspect ratio for each card so they all appear uniform and most importantly probably as we mentioned in the explainer even though we are being served a video at a resolution perhaps it's 240 perhaps it's 480 and we're thinking hmm but my internet's really fast. Well, adaptive stream players don't just look at internet speed. They also look at how many pixels is this video actually being displayed at. So let's go ahead and add width 100% to the video that is in the hero section. Okay, we've also set the height to auto and the display to block. Great. And that's it. We have our video playing. We have a trending now section and as you will see the first video that got served of us was 240 and then it switched to 1080 as a streaming resolution based on our variables such as internet speed such as the video player render size and so on. This looks great.
Recap
Okay and that's it. Now you no longer have to worry about the quality of your videos bringing your app down. To recap one video component one HSL manifest URL one streaming resolutions transformation is what we use today for professional grade adaptive streaming. We also added ik-thumbnail. jpeg for on the fly posters and a text overlay transformation for branding. I hope you found this video useful and I hope to see you again for another coding tutorial.