Thus far, we’ve taken a closer look at how node JS handles asynchronous processes with callbacks, promises, and streams. Now it’s time to put our knowledge to work by implementing a web server that handles upload and download streams. And node JS streams are everywhere. And the idea is that you want to stream everything. So let’s go ahead and get started building an HTTP server that can stream a video to the web browser. So I’m inside of the exercise files under chapter three, chapter three lesson one. And within the start folder, we have a blank index JS.
And we’re just going to go ahead and create our server from scratch here. So the first thing I’m going to go ahead and do is I’m going to destructure the create server function from the HTTP module. And then we’re going to stream a video to the server, so I’m also going to pull out the create read stream method from the file system. And then finally, we’re going to stream a video file, so let me go ahead and add a reference to that file, so the file name.
And this video file is found in the root of chapter three, so we’ll get out of the start folder, out of chapter three lesson one, and we’ll look for a file called powder day dot MP4. And you can use any MP4 file that you like. If you have an MP4 video laying around, I suggest that you try to stream that. So I’m going to go ahead and create a new web server, using the create server function. And the create server function takes in a callback that it will send the request and the response to, so we can handle any request for our web server inside of this function.
And I will quickly just chain on a listen command, so we’ll tell our web server to listen at port 3000. And then we’ll go ahead and let ourselves know that it’s running, so console log server running, and I’ll go ahead and put the port in there as well. 3000. All right. So all requests will be handled right here. And what we want to do within this callback handler is send a video back. So the first thing we need to do is take the response, and tell it in the header that we have a successful response by setting a status code of 200, and that our content type is a video.
An MP4 video. So that will tell the browser to use the correct video component to handle the stream that’s going to be coming from local host 3000. So all we need to do is create a read stream. And send it our file name. And now because the response is a stream, we can simply pipe our read stream to the response. So there we go. There’s the code necessary for streaming a video to the browser. Let’s test it out. So I’m going to come over here to the terminal, and run our file.
It’s the index so I can run it with a node dot. We see we have our server running on 3000. So I can come in here and hit the server, and we see our video. So it looks like we have our ski video streaming to the server. This is good news. What we want to do is add a subtle improvement. We should tell the web browser how long the video is, and we can do that through the headers. So I’m going to come over here to the terminal and stop the app. Clear the screen. Get ready to run it the next time.
And I can get information about how big our video file is using the stat function from the file system. But the stat function uses callback handlers. So just like we did in the first chapter of this course, what I want to do is convert the stat function to a promise. So I’m going to need to pull out my promisify function from the util module. And now I can create a new function that will return a promise using stat. So I’ll create a function called file info, cause that’s what stat does, is give us information about the file, and we will promisify our stat function.
All right, so now that we have a promise, we can use this to make our code look nice. The first thing I want to do is make the callback handler for the create server an asynchronous function. So we’ll add the a sync in front of that. And by making this an asynchronous function, we can use the a sync await code, so that means I can get the size of the file by destructuring an await call to file info. And I can just send it the file name. And what this will do is it will actually calls the code to wait.
We won’t execute lines nine or ten until this promise file info has been resolved, and the only variable we need from that promise is the file size. So we can take that variable and add it to our headers, under the content length key. And I can just add the size like so. Great, so now we’re telling our web browser how long the video is that we’re sending. So lemme come over here to the terminal and run this again. And we can go ahead and make a request for local host 3000.
There we go, we see our video. Now we’re displaying this using the HTML five video component. The browser knows to use that because any requests to local host 3000 returns an MP4 video. But the problem is, if we request I don’t know, something else out here on this play head, a future point in this video, it doesn’t handle that. So these are called range requests. And what we need to do is make our video respond to range requests. This is very important because if I actually go over here into Safari, and go into local host 3000, we don’t see a video at all.
And the reason is that Safari requires that we handle these range requests. So in the next lesson, we’re going to go ahead and handle the range requests to make our video respond for requests of shorter clips or a future clip.