Are you tired of trying different youtube downloaders and with all their limitations? Or you might be tired of seeing all the tutorials that are using the “https://youtube.com/get_video_info” parameter which doesn’t work anymore? Well, not anymore, let’s break the ice and build our own youtube video downloader today. So, without further talking, let’s get started!
Here is a quick overview of what we need in order to download a video.
- Get video info
- Extract the video stream URL
- Download the file from the stream URL
Before we get started, we need to get info about the video we want to download from youtube. This method has been updated recently. That’s why most of the old tutorials about youtube video downloaders are broken. So, let’s take a look at the new method. Please save this function in a file called function.php
<?php
function getVideoInfo($video_id){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "context": { "client": { "hl": "en", "clientName": "WEB", "clientVersion": "2.20210721.00.00", "clientFormFactor": "UNKNOWN_FORM_FACTOR", "clientScreen": "WATCH", "mainAppWebInfo": { "graftUrl": "/watch?v='.$video_id.'", } }, "user": { "lockedSafetyMode": false }, "request": { "useSsl": true, "internalExperimentFlags": [], "consistencyTokenJars": [] } }, "videoId": "'.$video_id.'", "playbackContext": { "contentPlaybackContext": { "vis": 0, "splay": false, "autoCaptionsDefaultOn": false, "autonavState": "STATE_NONE", "html5Preference": "HTML5_PREF_WANTS", "lactMilliseconds": "-1" } }, "racyCheckOk": false, "contentCheckOk": false}');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $result;
}
In the code above, we created a PHP function called getVideoInfo. If you call the function with a youtube video id as a parameter, it will return all the information about the video in object format. Now that we have the code to get all information about a video, let’s build a youtube video downloader form right away.
YouTube Video Downloader Form
To provide users a nice interface to put a video URL, we should create an HTML form first. Create a file called index.php in the same folder you created the function.php before. Now, write the code below in your index.php file.
Note: You can download a form generator provided by blog desire for free from here.
<?php require './function.php'; $error = "";?>
<html lang="en" class="h-100">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Download YouTube video</title>
<!-- Font-->
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400&display=swap" rel="stylesheet">
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.css" rel="stylesheet">
<style>
body {
font-family: 'Montserrat', sans-serif;
}
.formSmall {
width: 700px;
margin: 20px auto 20px auto;
}
</style>
</head>
<body>
<div class="container">
<form method="post" action="" class="formSmall">
<div class="row">
<div class="col-lg-12">
<h7 class="text-align"> Download YouTube Video</h7>
</div>
<div class="col-lg-12">
<div class="input-group">
<input type="text" class="form-control" name="video_link" placeholder="Paste link.. e.g. https://www.youtube.com/watch?v=5cpIZ8zHHXw" <?php if(isset($_POST['video_link'])) echo "value='".$_POST['video_link']."'"; ?>>
<span class="input-group-btn">
<button type="submit" name="submit" id="submit" class="btn btn-primary">Go!</button>
</span>
</div><!-- /input-group -->
</div>
</div><!-- .row -->
</form>
<!-- Place Your Video Downloader Code Here -->
</div>
</body>
</html>
You might have noticed that we have used a couple of PHP codes in the form. That’s because we want to keep track of user input in the input field. Now that we have an HTML form for user input and a function that returns any video information, we may proceed furthermore.
Generate a download link
We have a function that can return any video info and a form that accepts user input. Now, it’s our task to combine them both and get info about any video that a user may provide using our form. And after that, we should provide them a download button as well. Once again, here is what we need to do in order to achieve this.
- Get user input using the $_POST method
- Extract the video id from the user input
- Call the getVideoInfo function and pass the extracted video id as a parameter
- Extract the video stream URL from the response returned by the function
- Create a download button using the Stream URL
To do so, we need to place some code in our index.php file and here they are
<?php if(isset($_POST['submit'])): ?>
<?php
$video_link = $_POST['video_link'];
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $video_link, $match);
$video_id = $match[1];
$video = json_decode(getVideoInfo($video_id));
$formats = $video->streamingData->formats;
$adaptiveFormats = $video->streamingData->adaptiveFormats;
$thumbnails = $video->videoDetails->thumbnail->thumbnails;
$title = $video->videoDetails->title;
$short_description = $video->videoDetails->shortDescription;
$thumbnail = end($thumbnails)->url;
?>
<div class="row formSmall">
<div class="col-lg-3">
<img src="<?php echo $thumbnail; ?>" style="max-width:100%">
</div>
<div class="col-lg-9">
<h2><?php echo $title; ?> </h2>
<p><?php echo str_split($short_description, 100)[0]; ?></p>
</div>
</div>
<?php if(!empty($formats)): ?>
<?php if(@$formats[0]->url == ""): ?>
<div class="card formSmall">
<div class="card-header">
<strong>This video is currently not supported by our downloader!</strong>
<small><?php
$signature = "https://example.com?".$formats[0]->signatureCipher;
parse_str( parse_url( $signature, PHP_URL_QUERY ), $parse_signature );
$url = $parse_signature['url']."&sig=".$parse_signature['s'];
?>
</small>
</div>
</div>
<?php
die();
endif;
?>
<div class="card formSmall">
<div class="card-header">
<strong>With Video & Sound</strong>
</div>
<div class="card-body">
<table class="table ">
<tr>
<td>URL</td>
<td>Type</td>
<td>Quality</td>
<td>Download</td>
</tr>
<?php foreach($formats as $format): ?>
<?php
if(@$format->url == ""){
$signature = "https://example.com?".$format->signatureCipher;
parse_str( parse_url( $signature, PHP_URL_QUERY ), $parse_signature );
$url = $parse_signature['url']."&sig=".$parse_signature['s'];
}else{
$url = $format->url;
}
?>
<tr>
<td><a href="<?php echo $url; ?>">Test</a></td>
<td>
<?php if($format->mimeType) echo explode(";",explode("/",$format->mimeType)[1])[0]; else echo "Unknown";?>
</td>
<td>
<?php if($format->qualityLabel) echo $format->qualityLabel; else echo "Unknown"; ?>
</td>
<td>
<a
href="downloader.php?link=<?php echo urlencode($url)?>&title=<?php echo urlencode($title)?>&type=<?php if($format->mimeType) echo explode(";",explode("/",$format->mimeType)[1])[0]; else echo "mp4";?>"
>
Download
</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
<!-- Your code here for additional formats -->
<?php endif; ?>
<?php endif; ?>
Please replace the <!– Place Your Video Downloader Code Here –> part with the code snippet above. At this point, users can provide any video URL and they will get a download link for that particular video. Pretty cool right? But wait, this is not the end. We still need to create a downloader file.
Create the downloader file
You might be wondering why we’re going to create another downloader file when we already have the stream URL. Well, this file is to download the video from the Stream URL. This is the last file we will be creating for this tutorial. So, let’s just create another file called downloader.php in the same directory. Done? Now save the code below in your downloader.php file.
<?php
$downloadURL = urldecode($_GET['link']);
$type = urldecode($_GET['type']);
$title = urldecode($_GET['title']);
$fileName = $title.'.'.$type;
if (!empty($downloadURL) && substr($downloadURL, 0, 8) === 'https://') {
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment;filename=\"$fileName\"");
header("Content-Transfer-Encoding: binary");
readfile($downloadURL);
}
and boom, you are good to go with your own youtube video downloader!
Bonus!
You can replace the <!– Your code here for additional formats –> in your index.php with the code below to provide users all additional formats of the video to download!
<div class="card formSmall">
<div class="card-header">
<strong>Videos video only/ Audios audio only</strong>
</div>
<div class="card-body">
<table class="table ">
<tr>
<td>Type</td>
<td>Quality</td>
<td>Download</td>
</tr>
<?php foreach ($adaptiveFormats as $video) :?>
<?php
try{
$url = $video->url;
}catch(Exception $e){
$signature = $video->signatureCipher;
parse_str( parse_url( $signature, PHP_URL_QUERY ), $parse_signature );
$url = $parse_signature['url'];
}
?>
<tr>
<td><?php if(@$video->mimeType) echo explode(";",explode("/",$video->mimeType)[1])[0]; else echo "Unknown";?></td>
<td><?php if(@$video->qualityLabel) echo $video->qualityLabel; else echo "Unknown"; ?></td>
<td><a href="downloader.php?link=<?php print urlencode($url)?>&title=<?php print urlencode($title)?>&type=<?php if($video->mimeType) echo explode(";",explode("/",$video->mimeType)[1])[0]; else echo "mp4";?>">Download</a> </td>
</tr>
<?php endforeach;?>
</table>
</div>
</div>
Demo and Source Code
You can check a demo version of the YouTube Video Downloader from here. Or you can download the source code from here
Please Note: Some video doesn’t return a Stream URL, the script currently doesn’t support such videos. But I’m working on it and will update the tutorial as soon as I can find a solution for such videos.
I hope you found this article helpful. If so, a share from you will make my day. If you face any problems, please let me know in the comment section. Stay safe, have a great day.
Update:
For anyone, who wants to accept a youtube short link like “https://youtu.be/5cpIZ8zHHXw”, should update your downloaded index.php file with the code given for this file in this article. Because this article has been updated but the source code is still old.
Hope this helps. If you still need further assistance, you can let me know via email or a comment. Thanks
Blog Desire is Up for Sale!
Ready for a new chapter? Blog Desire could be yours!
Inquire Now!
Hey bro I found a project that can decode signature cipher(https://github.com/Athlon1600/youtube-downloader).
You should check it out.
Thanks bro, I’ll definitely check this out
download speeds are too slow! I am getting only 70KBps in a 50Mbps connection!.
why is that?
We can’t control the delivery speed of the server. It’s not entirely related to your internet speed.
so what is the solution ?
A new script is coming up, please stay tuned. Cheers
okay cool , I already subscribe on your Blog.
please be fast <3.
Sure, thank you 😊
anything new about youtube downloader ?
and how about tiktok downloder ?
Hi, the new YouTube downloader is about to be released next week. I appreciate your patience and I will provide you with updates asap.
hi, anything new ?
Hi thank you so much for the script, it works fine. But there are some issues I found in the code which are
1. The code does not support any youtube short videos.
2. There are some videos the code cant download and showed this (This video is currently not supported by our downloader!) that other downloaders on the internet can download. If you can fix these issues then the code will be perfect.
But still thank you so much for creating this it works better than other codes on the internet.
Hi Subhajit, thank you for your feedback. I’ll consider the points you’ve mentioned.
It works, but the download speeds are too slow! I am getting less than 100KBps in a 100Mbps connection! Without faster downloads there is no meaning in using this. Is there a way to improve the speed ?
Hi, we cannot modify the speed of the server.
Hi, its not working now. All the time mp4 url (googlevideo.com) says access denied 403 error. I have tried many videos but none work. While the same youtube videos are working on other youtube downloaders like killerplayer.com
Hi, did you downloaded the source code or did you restructured the code from the blog post. In case you restructured the code, make sure you didn’t have any typos while building the link part.
Hey the downloader.php does not working please Check it once
Sure, I will check it and will provide you update. Thanks for reporting the issue
This video is not supported by our downloader, have you found the solution?
Hi Zain, thanks for your comment. No, I haven’t found yet, actually I didn’t find a chance to give a deep effort on this after I published the article. But I hope I will asap.
hi, broo this code note work in mobile video download and add .html extension??
Hi, as I’ve mentioned in the article, some videos are not supported in my current version of codes. Also, you don’t need to add a .html extension because it’s a PHP file.
I even see demo, there are error, then i download and run on local host same error
https://prnt.sc/quSx4Wc2XHtz
Hi, it’s because the demo isn’t updated with the short links. Please check the short link portion from the bottom of the article and update your local code accordingly. Hope this helps
When I click on the Download button, the file is saved to the ‘/home’ folder on the server.
Thank you for your work! It works great!
I installed your script on the server. How to make a file saved in a folder on the server? The folder does not need to be selected, it will be registered permanently.
Do you want to save the videos on your server or do you want to modify the default download folder of local machine while downloading?
Thanks
When I click on the Download button, the file is saved to the ‘/home’ folder on the server.
You might try to read/write files in PHP. But most provably, you’ll get a server timeout error.
This video is not supported by our downloader, do you already have a solution for this problem?
Not yet, I didn’t have much chance to work on this after I published the article. But I will work on this asap and will post an update as soon as I have a solution for this.
Hello, do you have a specific method to allow the user to download the video in mp3 format, I see that your script only displays mp4, webm formats, and how do I display the size in MB in the description of each format if possible?
Hi,
if you add the bonus code that I have given in the article, you’ll be able to download the mp3 format as well.
But, showing the file size in advance will require a bit of extra time and work.
Since today morning I see code doesn’t work. Please fix it. And give us solution.
Can you share a screenshot of what type of error are you getting?
Thanks
Screenshot: https://prnt.sc/267×907
Did you update the code from the blog post to support short youtube video links?
Some videos are not supported, why?
Please make a solution for this
Because their response type is different compared to other responses. I’ll surely update the article if I find a solution for those type of videos.
Thanks
i have no idea why this video not work:
https://www.youtube.com/watch?v=MZvSX7wcHf8
solved
Sir,
I was searching for the documentation of the above api. But I was unsuccessful.
Kindly share the link of that webpage sir.
https://developers.google.com/youtube/v1_deprecation_notice
This one I guess, But I forgot actually.
i just wanna ask about this:
“`
url == “”): ?>
This video is currently not supported by our downloader!
signatureCipher;
parse_str( parse_url( $signature, PHP_URL_QUERY ), $parse_signature );
$url = $parse_signature[‘url’].”&sig=”.$parse_signature[‘s’];
?>
“`
do you mean if youtube url doesn’t have url in its format, we can’t download the video?
but what is your purpose on your second code which is like this ? :
“`
if (@$format->url == “”) {
$signature = “https://example.com?” . $format->signatureCipher;
parse_str( parse_url( $signature, PHP_URL_QUERY ), $parse_signature );
$url = $parse_signature[‘url’].”&sig=”.$parse_signature[‘s’];
} else {
$url = $format->url;
}
“`
just confused.
Hi,
Thanks for pointing out this one. Basically, for our unsupported videos, they send us a signature cipher. So, on the second part, I was checking if I can find any way to decrypt the signature cipher to get download links for those videos as well. I included that so if anyone wants to work with those videos, they can continue from where I left it.
Hope this helps.
thanks
ahh okay, i see.
btw how do you get that api key? is it youtube api key v1?
It’s the default youtube player API
This is how I make a mistake when typing youtube.be
https://prnt.sc/1yv1ycz
Pls help me
youtu.be link dont working. pls help me
With Video & Sound
Hello there. How can I show all quality here?
The script should show all quality. And on the bonus script, it should show all quality in video format and audio format separately. Hope this helps.
This script doesn’t provide mp3 format,
Please include it also and display video size
Please
If you include the additional bonus code, it will include the mp3 format as well.
Please check that and let me know if you still need any assistance.
What are the server requirements and modifications sir,
Thanks in advance
PHP 7.4+ on apache server are recommended.
Brother, a small problem, I copied your code and hosted on some where here(http://videonition.epizy.com/?i=1)
All is going good, but when I download the video it comes as broken for me, when I downloaded on your demo version, it’s the video is clear is crystal. What I am telling is the video downloaded on my website is 7.00 mb but downloaded on your demo version it is like 15.00 mb, both same quality. I used this video https://youtu.be/dbV3qODiBGc
Plz tell me whether I should change my phone version or modify anything. Plz download this video on my website and yours and see the difference.
Awesome tutorial.
One question, can i use some pcs of code to build a downloader of my own , i will give credits too.
Sure, you can.
I gotta confess, that it is not working as I expected. Cruciotech is right, update the main code at your leisure time plz.
Hi, just updated the code in the article. Hope this help. Thanks
Since today morning I see code doesn’t working. Please fix it. Give us solution.
I have pasted your function on my function.php but it gives me a 500 error, plz don’t get tensed for wasting your time.
I always fail on php. Maybe if you have the kindness to change the main code on this blog with that code.
Sure. I’ll update the code
Thanks bro, but clear my doubt, should I need to pass the $full_url parameter into get video Id function. Like should I need to have both $video_id and $full_url as the parameters in my function or does it need some tweaks.
You just need to pass your video url, it can be full url or a short url, and the function will give you the video id.
Super bro, can you update the code to accept all types YouTube link formats just like a guy commented abow and also plz tell how to get the api key which you coded on function.php
Sure, I’ll update the article shortly. Thanks for the suggestion.
bro ,wonderful piece of work
can you give me a idea how to tweak the function.php code as to accept the short YouTube links like “https://youtu.be/zSbicGH3qCg”
Instead of “https://m.youtube.com/watch?v=n7Ns6_NxEZg&feature=youtu.be”
Hi, thanks for your support.
Here is a piece of code that will generate a video id from almost any format.
$url = “YOUR_VIDEO_URL”;
preg_match(‘%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^”&?/ ]{11})%i’, $url, $match);
$youtube_id = $match[1];
Where do we add this code you wrote?
Can you just replace these few lines on your index.php file?
$video_link = $_POST['video_link'];
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $video_link, $match);
$video_id = $match[1];
this should solve your problem. If you need further help, please reach me at info@blogdesire.com
I will be more than happy to assist you.
thank you
Thanks brother, btw any updates for some no streams url video?
Not yet, I’ll update the tutorial and will notify you once I have the solution.
Thanks