Introduction:
In today's digital age, video content is king, and YouTube is the reigning monarch. However, sometimes you may want to watch your favorite YouTube videos offline. In this tutorial, we'll show you how to create a PHP-based YouTube video downloader that you can integrate into your website.
Step 1: Obtaining a YouTube Data API Key:
To interact with the YouTube Data API, you'll need an API key. Follow these steps to obtain one:
- Go to the Google Developers Console.
- Create a new project (if you don't have one already).
- Enable the YouTube Data API for your project.
- Create credentials and obtain your API key.
<?php
$apiKey = "API_KEY";
$videoUrl = "YOUTUBE_VIDEO_URL";
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $videoUrl, $match);
$youtubeVideoId = $match[1];
$videoMeta = json_decode(getYoutubeVideoMeta($youtubeVideoId, $apiKey));
$videoTitle = $videoMeta->videoDetails->title;
$videoFormats = $videoMeta->streamingData->formats;
foreach ($videoFormats as $videoFormat) {
$url = $videoFormat->url;
if ($videoFormat->mimeType)
$mimeType = explode(";", explode("/", $videoFormat->mimeType)[1])[0];
else
$mimeType = "mp4";
?>
<a
href="video-downloader.php?link=<?php echo urlencode($url)?>&title=<?php echo urlencode($videoTitle)?>&type=<?php echo $mimeType; ?>">
Download Video</a>
<?php
}
function getYoutubeVideoMeta($videoId, $key)
{
$ch = curl_init();
$curlUrl = 'https://www.youtube.com/youtubei/v1/player?key=' . $key;
curl_setopt($ch, CURLOPT_URL, $curlUrl);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$curlOptions = '{"context": {"client": {"hl": "en","clientName": "WEB",
"clientVersion": "2.20210721.00.00","clientFormFactor": "UNKNOWN_FORM_FACTOR","clientScreen": "WATCH",
"mainAppWebInfo": {"graftUrl": "/watch?v=' . $videoId . '",}},"user": {"lockedSafetyMode": false},
"request": {"useSsl": true,"internalExperimentFlags": [],"consistencyTokenJars": []}},
"videoId": "' . $videoId . '", "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_POSTFIELDS, $curlOptions);
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$curlResult = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $curlResult;
}
?>
This example code works in the following flow to output the link to download the YouTube video.
- Get the unique id of the YouTube video from the input URL.
- Request YouTube API via PHP cURL post to access the video metadata.
- Get the video title, data array in various formats, and MIME type by parsing the cURL response.
- Pass the video links, title, and mime types to the video downloader script.
- Apply PHP readfile() to download the video file by setting the PHP header Content-type.
video-downloader.php
<?php
$downloadURL = urldecode($_GET['link']);
$downloadFileName = urldecode($_GET['title']) . '.' . urldecode($_GET['type']);
if (! empty($downloadURL) && substr($downloadURL, 0, 8) === 'https://') {
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment;filename=\"$downloadFileName\"");
header("Content-Transfer-Encoding: binary");
readfile($downloadURL);
}
?>
index.php
<form method="post" action="">
<h1>PHP YouTube Video Downloader Script</h1>
<div class="row">
<input type="text" class="inline-block" name="youtube-video-url">
<button type="submit" name="submit" id="submit">Download Video</button>
</div>
</form>
<?php
if (isset($_POST['youtube-video-url'])) {
$videoUrl = $_POST['youtube-video-url'];
?>
<p>
URL: <a href="<?php echo $videoUrl;?>"><?php echo $videoUrl;?></a>
</p>
<?php
}
if (isset($_POST['submit'])) {
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $videoUrl, $match);
$youtubeVideoId = $match[1];
require './youtube-video-meta.php';
$videoMeta = json_decode(getYoutubeVideoMeta($youtubeVideoId, $key));
$videoThumbnails = $videoMeta->videoDetails->thumbnail->thumbnails;
$thumbnail = end($videoThumbnails)->url;
?>
<p>
<img src="<?php echo $thumbnail; ?>">
</p>
<?php $videoTitle = $videoMeta->videoDetails->title; ?>
<h2>Video title: <?php echo $videoTitle; ?></h2>
<?php
$shortDescription = $videoMeta->videoDetails->shortDescription;
?>
<p><?php echo str_split($shortDescription, 100)[0];?></p>
<?php
$videoFormats = $videoMeta->streamingData->formats;
if (! empty($videoFormats)) {
if (@$videoFormats[0]->url == "") {
?>
<p>
<strong>This YouTube video cannot be downloaded by the downloader!</strong><?php
$signature = "https://example.com?" . $videoFormats[0]->signatureCipher;
parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature);
$url = $parse_signature['url'] . "&sig=" . $parse_signature['s'];
?>
</p>
<?php
die();
}
?>
<h3>With Video & Sound</h3>
<table class="striped">
<tr>
<th>Video URL</th>
<th>Type</th>
<th>Quality</th>
<th>Download Video</th>
</tr>
<?php
foreach ($videoFormats as $videoFormat) {
if (@$videoFormat->url == "") {
$signature = "https://example.com?" . $videoFormat->signatureCipher;
parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature);
$url = $parse_signature['url'] . "&sig=" . $parse_signature['s'];
} else {
$url = $videoFormat->url;
}
?>
<tr>
<td><a href="<?php echo $url; ?>">View Video</a></td>
<td><?php if($videoFormat->mimeType) echo explode(";",explode("/",$videoFormat->mimeType)[1])[0]; else echo "Unknown";?></td>
<td><?php if($videoFormat->qualityLabel) echo $videoFormat->qualityLabel; else echo "Unknown"; ?></td>
<td><a
href="video-downloader.php?link=<?php echo urlencode($url)?>&title=<?php echo urlencode($videoTitle)?>&type=<?php if($videoFormat->mimeType) echo explode(";",explode("/",$videoFormat->mimeType)[1])[0]; else echo "mp4";?>">
Download Video</a></td>
</tr>
<?php } ?>
</table>
<?php
$adaptiveFormats = $videoMeta->streamingData->adaptiveFormats;
include 'adaptive-formats.php';
?>
<?php
}
}
?>
adaptive-formats.php
<h3>YouTube Videos Adaptive Formats</h3>
<table class="striped">
<tr>
<th>Type</th>
<th>Quality</th>
<th>Download Video</th>
</tr>
<?php
foreach ($adaptiveFormats as $videoFormat) {
try {
$url = $videoFormat->url;
} catch (Exception $e) {
$signature = $videoFormat->signatureCipher;
parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature);
$url = $parse_signature['url'];
}
?>
<tr>
<td><?php if(@$videoFormat->mimeType) echo explode(";",explode("/",$videoFormat->mimeType)[1])[0]; else echo "Unknown";?></td>
<td><?php if(@$videoFormat->qualityLabel) echo $videoFormat->qualityLabel; else echo "Unknown"; ?></td>
<td><a
href="video-downloader.php?link=<?php print urlencode($url)?>&title=<?php print urlencode($videoTitle)?>&type=<?php if($videoFormat->mimeType) echo explode(";",explode("/",$videoFormat->mimeType)[1])[0]; else echo "mp4";?>">Download
Video</a></td>
</tr>
<?php }?>
</table>
View Demo Download
2 Comments
Very nice, its really helpful article thank for sharing sir
ReplyDeletewe are using the above code but presently its not working can you please fix the code and update
ReplyDelete