How to build your own Youtube – Part 5

Introduction: If you missed the earlier parts, in this series we are covering how to build your own YouTube clone, Click here.

Note: You need to have at least some prior experience with client-side Javascript frameworks  and Node.js to get the most out of this tutorial.

We have been able to upload some video, but those video files we experimented with are actually very small files. How do we deal with large video files?

Chunked Video Upload

As users, when you try to upload a large file, you experience timeouts over and over again. Let’s look at a better way to upload large video files.

Cloudinary  offers a better method to upload large files, which offers a degree of tolerance for network issues. It allows video files to be uploaded in chunks.

By default, chunk size defaults to 20 Megabytes but can be set to as low as 5 Megabytes by using the chunk_size parameter. Let’s take a spin!

Step 1: Set up a new branch

If you haven’t been committing to git, please do. Check out into a new branch, maybe called chunk-video-upload.

Step 2: Use the upload_large method

Open up server/controllers/upload.server.controller.js 

In the uploadVideo method, we’ll switch up the Cloudinary upload method with the upload_large method like so:

Current – upload

New – upload_large

Now, try to upload a file larger than the previous ones that have been uploaded.

Let’s set the chunk size to 10 Megabytes like so:

Are you surprised that it’s that simple?…That’s all :smile:

The source code for chunked video upload is here

Note: By default, the maximum video file size to upload is 50MB, you need to upgrade to a paid plan if you want to upload larger file sizes.

Video Transformations

Let’s perform some nice video transformations on our yourtube platform. We want to be able to tag the video, change the background of the video and also remove audio from the video.

Next, Let’s create a section to view the videos a user has uploaded.

Step 3: Open up your index.html file and add a new nav item like so:

Step 4: Open up your server/models/video.server.model.js and update it like so:

From what’s obtainable above, we have added new fields to our Video Schema. In a real-life production environment, you should consider using migrations to change or add anything in your Schema.

Step 5: Create a new file my_videos.client.view.html in public/views/pages and add this to it like so:

Here, you’ll discover that we are using a VideoController. Next, let’s create that.

Step 6: Create a file video.client.controller.js and add this to it like so:

Note: Don’t forget to link this file in index.html. If you don’t your app won’t recognize the VideoController.

Here, we have the retrieveMyVideos method from the Video service that returns all videos uploaded by someone. The $ fetches the person’s email from localStorage.

So many moving parts? Don’t worry, It will all make sense soon :smile:

Step 7: Open up public/js/services/video.client.service.js and add this method to it like so:

Here, we are making use of query strings to fetch all videos uploaded by a particular user from the backend. Next, let’s tweak a method in the server controller to accommodate this new query string behavior.

Step 8:  Open up server/controllers/video.server.controller.js and update the retrieveAll method like so:

If the query parameter uploaded_by is present, it goes ahead to query the Video Schema with the new parameter.

Step 9: Open up public/js/controllers/auth.client.controller.js and update it like so:

What changed? Here, we inject the $localStorage service and also added this line of code.

Once a user logs in now, it stores the email of the user in the browser local Storage for later use.

Step 10: Open up public/js/controllers/upload.client.controller.js and update it like so:

Here you’ll discover we are storing more details about a video in this portion of the code

Step 11: Open up public/js/routes.js and add this route like so:

Step 12: Refresh your page, logout, and log in a new user. Upload some new videos, then click on the My Videos nav item to see all the videos you have uploaded as the logged-in user.

screen shot 2016-06-30 at 5 05 33 am

Next, we need to be able to click the “Edit” button and it should redirect to a new page with that particular video and the options to update the video and its content.

Step 13:  Open up public/js/routes.js and add this route like so:

Step 14: Create a file edit_video.client.view.html in public/views/pages directory and add this like so:

Boom!!! we have a new controller called TransformController. Let’s create that in the next step.

Step 15: Create a file transform.client.controller.js in public/js/controllers directory and add this to it like so:

Note: Don’t forget to link this file in index.html. If you don’t your app won’t recognize the TransformController.

We injected $routeParams service to enable the application get the id of the video in the Url. The Video service also has a new method updateVideoDetails. Let’s create that in the next Step.

Step 16: Open up public/js/services/video.client.service.js and add this method like so:

Next, let’s the put method for this route in our backend

Step 17: Open up server/routes.js and add this route like so:

From the code above, it means we have a new method updateVideoDetails in our Video Server Controller. Let’s add that in the next step.

Before we move to the next step, our page should be looking like this now:

screen shot 2016-06-30 at 5 54 21 am

screen shot 2016-06-30 at 5 54 34 am

Step 18: Open up server/controllers/video.server.controller.js and add this piece of code like so:

Look at the code above closely, you’ll discover that we have three methods tagVideos, removeAudio and changeBackground from the Upload server controller. Let’s add that in the next step.

Step 19: Open up server/controllers/upload.server.controller.js and add these methods this like so:

To add tags to the video, all you need is the add_tag cloudinary method, then pass in the tag and the public id of the video you want to tag.

This piece of code below is a typical way of adding tags, where animal is the tag, dog and lion are the public_ids of the video.

screen shot 2016-06-30 at 6 55 52 am

Those are the tags I have been adding.

Note: I was too lazy to implement a proper tagging system, so you can get your hands dirty by using angular-selectize or even ng-selectize to implement a cool tag feature.

To remove audio from a video, this is the typical way

where dog.mp4 is the name of the video, and the audio_codec property is set to none. I discovered that the cloudinary API is so easy to use, just ensure you have this upload/ac_none/ in the URL and the audio will be stripped off. So a typical video URL with audio removed will look like so:

To change a video’s background color, this is the typical way

which actually translates to this :,h_250,c_pad,b_black/dog.mp4

Note: One thing I really love about these transformations is that they are simply API based. Find out more here

Look at our changeBackground method, I ensured this upload/w_300,h_300,c_pad,b_  was included the video url. We passed the color the user chose from the frontend. If the user doesn’t add any background color, it uses yellow by default.

Note: I hard-coded the width and height of the color area like so w_300, h_300. You can also decide to get that from the frontend instead of hard coding it like I did. I also didn’t validate the form fields. I’ll leave that for you to do.

Get your hands dirty!!! :smile:

Step 20: Now, try updating a video, check the remove audio box, add a color, and update like so:

screen shot 2016-06-30 at 6 33 27 am


In this post, we have looked at chunked video uploading, saving more video details, assigning tags to a video, video transformations like removing audio, displaying video dimensions, changing video background and also delivering the videos. In the next post, we’ll look at video resizing & cropping, renaming, trimming, deleting, concatenating, rotating, and creating rounding corners/circular videos.

The source code for this project is on GitHub.

If you have any questions or observations, please drop your thoughts in the comment section below :smile:



Food Ninja, Code Slinger, Technical Trainer, Accidental Writer, Open Source Advocate and Developer Evangelist.