Sick Gaming
[Tut] PHP YouTube Video Downloader Script - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Programming (https://www.sickgaming.net/forum-76.html)
+--- Forum: PHP Development (https://www.sickgaming.net/forum-82.html)
+--- Thread: [Tut] PHP YouTube Video Downloader Script (/thread-99953.html)



[Tut] PHP YouTube Video Downloader Script - xSicKxBot - 09-16-2022

PHP YouTube Video Downloader Script

<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2022/09/php-youtube-video-downloader-script.jpg" width="550" height="282" title="" alt="" /></div><div><div class="modified-on" readability="7.1666666666667"> by <a href="https://phppot.com/about/">Vincy</a>. Last modified on September 15th, 2022.</div>
<p>YouTube is almost the numero uno platform for hosting videos. It allows users to publish and share videos, more like a social network.</p>
<p>Downloading YouTube videos is sometimes required. You must read through the YouTube terms and conditions before downloading videos and act according to the permissions given. For example you may wish to download to <a href="https://phppot.com/php/php-database-backup-client-for-mysql/">have a backup</a> of older videos that are going to be replaced or removed.</p>
<p>This quick example provides a YouTube Video downloader script in PHP. It has a video URL defined in a <a href="https://phppot.com/php/php-variables/">PHP variable</a>. It also establishes a key to access the YouTube video meta via API.</p>
<p><span>Configure the key</span> and store the video URL to get the video downloader link using this script.</p>
<h2>Quick example</h2>
<pre class="prettyprint"><code class="language-php-template">&lt;?php
$apiKey = "API_KEY";
$videoUrl = "YOUTUBE_VIDEO_URL";
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})%i', $videoUrl, $match);
$youtubeVideoId = $match[1];
$videoMeta = json_decode(getYoutubeVideoMeta($youtubeVideoId, $apiKey));
$videoTitle = $videoMeta-&gt;videoDetails-&gt;title;
$videoFormats = $videoMeta-&gt;streamingData-&gt;formats;
foreach ($videoFormats as $videoFormat) { $url = $videoFormat-&gt;url; if ($videoFormat-&gt;mimeType) $mimeType = explode(";", explode("/", $videoFormat-&gt;mimeType)[1])[0]; else $mimeType = "mp4"; ?&gt;
&lt;a href="video-downloader.php?link=&lt;?php echo urlencode($url)?&gt;&amp;title=&lt;?php echo urlencode($videoTitle)?&gt;&amp;type=&lt;?php echo $mimeType; ?&gt;"&gt; Download Video&lt;/a&gt;
&lt;?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;
}
?&gt;
</code></pre>
<p>This example code works in the following flow to output the link to download the YouTube video.</p>
<ol>
<li>Get the unique id of the YouTube video from the input URL.</li>
<li>Request YouTube API via <a href="https://phppot.com/php/php-curl-post/">PHP cURL post</a> to access the video metadata.</li>
<li>Get video title, data array in various formats, and MIME type by parsing the cURL response.</li>
<li>Pass the video links, title and mime types to the video downloader script.</li>
<li>Apply PHP <em>readfile()</em> to download the video file by setting the <a href="https://phppot.com/php/php-header/">PHP header</a> <em>Content-type</em>.</li>
</ol>
<p><img loading="lazy" class="alignnone size-large wp-image-19390" src="https://phppot.com/wp-content/uploads/2022/09/youtube-video-downloader-links-php-550x282.jpg" alt="youtube video downloader links php" width="550" height="282" srcset="https://phppot.com/wp-content/uploads/2022/09/youtube-video-downloader-links-php-550x282.jpg 550w, https://phppot.com/wp-content/uploads/2022/09/youtube-video-downloader-links-php-300x154.jpg 300w, https://phppot.com/wp-content/uploads/2022/09/youtube-video-downloader-links-php-768x394.jpg 768w, https://phppot.com/wp-content/uploads/2022/09/youtube-video-downloader-links-php.jpg 1000w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>The below video downloader script is called by clicking the “Download video” link in the browser.</p>
<p>It receives the video title, and extension to define the output video file name. It also gets the video link from which it reads the video to be downloaded to the browser.</p>
<p>This script sets the content header in PHP to output the <a href="https://phppot.com/php/search-videos-by-keyword-using-php-youtube-data-api/">YouTube video</a> file.</p>
<p class="code-heading">video-downloader.php</p>
<pre class="prettyprint"><code class="language-php">&lt;?php
// this PHP script reads and downloads the video from YouTube
$downloadURL = urldecode($_GET['link']);
$downloadFileName = urldecode($_GET['title']) . '.' . urldecode($_GET['type']);
if (! empty($downloadURL) &amp;&amp; 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);
}
?&gt;
</code></pre>
<p><a class="demo" href="https://phppot.com/demo/youtube-video-downloader/">View Demo</a></p>
<h2>Collect YouTube video URL via form and process video downloader script</h2>
<p>In the quick example, it has a sample to hardcode the YouTube video URL to a PHP variable.</p>
<p>But, the below code will allow users to enter the video URL instead of the hardcode.</p>
<p>An HTML form will post the entered video URL to process the PHP cURL request to the YouTube API.</p>
<p>After posting the video URL, the PHP flow is the same as the quick example. But, the difference is, that it displays more links to download videos in all the adaptive formats.</p>
<p class="code-heading">index.php</p>
<pre class="prettyprint"><code class="language-php-template">&lt;form method="post" action=""&gt; &lt;h1&gt;PHP YouTube Video Downloader Script&lt;/h1&gt; &lt;div class="row"&gt; &lt;input type="text" class="inline-block" name="youtube-video-url"&gt; &lt;button type="submit" name="submit" id="submit"&gt;Download Video&lt;/button&gt; &lt;/div&gt;
&lt;/form&gt;
&lt;?php
if (isset($_POST['youtube-video-url'])) { $videoUrl = $_POST['youtube-video-url']; ?&gt;
&lt;p&gt; URL: &lt;a href="&lt;?php echo $videoUrl;?&gt;"&gt;&lt;?php echo $videoUrl;?&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;?php
}
if (isset($_POST['submit'])) { preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&amp;]v=)|youtu\.be/)([^"&amp;?/ ]{11})%i', $videoUrl, $match); $youtubeVideoId = $match[1]; require './youtube-video-meta.php'; $videoMeta = json_decode(getYoutubeVideoMeta($youtubeVideoId, $key)); $videoThumbnails = $videoMeta-&gt;videoDetails-&gt;thumbnail-&gt;thumbnails; $thumbnail = end($videoThumbnails)-&gt;url; ?&gt;
&lt;p&gt; &lt;img src="&lt;?php echo $thumbnail; ?&gt;"&gt;
&lt;/p&gt;
&lt;?php $videoTitle = $videoMeta-&gt;videoDetails-&gt;title; ?&gt;
&lt;h2&gt;Video title: &lt;?php echo $videoTitle; ?&gt;&lt;/h2&gt;
&lt;?php $shortDescription = $videoMeta-&gt;videoDetails-&gt;shortDescription; ?&gt;
&lt;p&gt;&lt;?php echo str_split($shortDescription, 100)[0];?&gt;&lt;/p&gt;
&lt;?php $videoFormats = $videoMeta-&gt;streamingData-&gt;formats; if (! empty($videoFormats)) { if (@$videoFormats[0]-&gt;url == "") { ?&gt;
&lt;p&gt; &lt;strong&gt;This YouTube video cannot be downloaded by the downloader!&lt;/strong&gt;&lt;?php $signature = "https://example.com?" . $videoFormats[0]-&gt;signatureCipher; parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature); $url = $parse_signature['url'] . "&amp;sig=" . $parse_signature['s']; ?&gt; &lt;/p&gt;
&lt;?php die(); } ?&gt;
&lt;h3&gt;With Video &amp; Sound&lt;/h3&gt;
&lt;table class="striped"&gt; &lt;tr&gt; &lt;th&gt;Video URL&lt;/th&gt; &lt;th&gt;Type&lt;/th&gt; &lt;th&gt;Quality&lt;/th&gt; &lt;th&gt;Download Video&lt;/th&gt; &lt;/tr&gt; &lt;?php foreach ($videoFormats as $videoFormat) { if (@$videoFormat-&gt;url == "") { $signature = "https://example.com?" . $videoFormat-&gt;signatureCipher; parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature); $url = $parse_signature['url'] . "&amp;sig=" . $parse_signature['s']; } else { $url = $videoFormat-&gt;url; } ?&gt; &lt;tr&gt; &lt;td&gt;&lt;a href="&lt;?php echo $url; ?&gt;"&gt;View Video&lt;/a&gt;&lt;/td&gt; &lt;td&gt;&lt;?php if($videoFormat-&gt;mimeType) echo explode(";",explode("/",$videoFormat-&gt;mimeType)[1])[0]; else echo "Unknown";?&gt;&lt;/td&gt; &lt;td&gt;&lt;?php if($videoFormat-&gt;qualityLabel) echo $videoFormat-&gt;qualityLabel; else echo "Unknown"; ?&gt;&lt;/td&gt; &lt;td&gt;&lt;a href="video-downloader.php?link=&lt;?php echo urlencode($url)?&gt;&amp;title=&lt;?php echo urlencode($videoTitle)?&gt;&amp;type=&lt;?php if($videoFormat-&gt;mimeType) echo explode(";",explode("/",$videoFormat-&gt;mimeType)[1])[0]; else echo "mp4";?&gt;"&gt; Download Video&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt; &lt;?php } ?&gt; &lt;/table&gt;
&lt;?php // if you wish to provide formats based on different formats // then keep the below two lines $adaptiveFormats = $videoMeta-&gt;streamingData-&gt;adaptiveFormats; include 'adaptive-formats.php'; ?&gt; &lt;?php }
}
?&gt;
</code></pre>
<p>This program will output the following once it has the video downloader response.</p>
<p><img loading="lazy" class="alignnone size-large wp-image-19388" src="https://phppot.com/wp-content/uploads/2022/09/php-youtube-video-downloader-550x446.jpg" alt="php youtube video downloader" width="550" height="446" srcset="https://phppot.com/wp-content/uploads/2022/09/php-youtube-video-downloader-550x446.jpg 550w, https://phppot.com/wp-content/uploads/2022/09/php-youtube-video-downloader-300x243.jpg 300w, https://phppot.com/wp-content/uploads/2022/09/php-youtube-video-downloader-768x622.jpg 768w, https://phppot.com/wp-content/uploads/2022/09/php-youtube-video-downloader.jpg 1000w" sizes="(max-width: 550px) 100vw, 550px"></p>
<h2>PHP cURL script to get the video metadata</h2>
<p>The PHP cURL script used to access the YouTube endpoint to read the file meta is already seen in the quick example.</p>
<p>The above code snippet has a PHP require_once statement for having the cURL post handler.</p>
<p>The&nbsp;<em>youtube-video-meta.php</em> file has this handler to read the video file meta. It receives the unique id of the video and the key used in the PHP cURL parsing.</p>
<p>In a recently posted article, we have collected <a href="https://phppot.com/javascript/google-drive-upload-javascript/">file meta to upload to Google Drive</a>.</p>
<h2>Display YouTube video downloaders in adaptive formats</h2>
<p>The landing page shows another table of downloads to get the video file in the available adaptive formats.</p>
<p>The PHP script accesses the <strong>adaptiveFormats</strong> property of the Youtube video meta-object to display these downloads.</p>
<p class="code-heading">adaptive-formats.php</p>
<pre class="prettyprint"><code class="language-php-template">&lt;h3&gt;YouTube Videos Adaptive Formats&lt;/h3&gt;
&lt;table class="striped"&gt; &lt;tr&gt; &lt;th&gt;Type&lt;/th&gt; &lt;th&gt;Quality&lt;/th&gt; &lt;th&gt;Download Video&lt;/th&gt; &lt;/tr&gt; &lt;?php foreach ($adaptiveFormats as $videoFormat) { try { $url = $videoFormat-&gt;url; } catch (Exception $e) { $signature = $videoFormat-&gt;signatureCipher; parse_str(parse_url($signature, PHP_URL_QUERY), $parse_signature); $url = $parse_signature['url']; } ?&gt; &lt;tr&gt; &lt;td&gt;&lt;?php if(@$videoFormat-&gt;mimeType) echo explode(";",explode("/",$videoFormat-&gt;mimeType)[1])[0]; else echo "Unknown";?&gt;&lt;/td&gt; &lt;td&gt;&lt;?php if(@$videoFormat-&gt;qualityLabel) echo $videoFormat-&gt;qualityLabel; else echo "Unknown"; ?&gt;&lt;/td&gt; &lt;td&gt;&lt;a href="video-downloader.php?link=&lt;?php print urlencode($url)?&gt;&amp;title=&lt;?php print urlencode($videoTitle)?&gt;&amp;type=&lt;?php if($videoFormat-&gt;mimeType) echo explode(";",explode("/",$videoFormat-&gt;mimeType)[1])[0]; else echo "mp4";?&gt;"&gt;Download Video&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt; &lt;?php }?&gt;
&lt;/table&gt;
</code></pre>
<p><a class="demo" href="https://phppot.com/demo/youtube-video-downloader/">View Demo</a><a class="download" href="https://phppot.com/downloads/php/youtube-video-downloader.zip">Download</a></p>
<p> <!-- #comments --> </p>
<div class="related-articles">
<h2>Popular Articles</h2>
</p></div>
<p> <a href="https://phppot.com/php/php-youtube-video-downloader/#top" class="top">↑ Back to Top</a> </p>
</div>


https://www.sickgaming.net/blog/2022/09/15/php-youtube-video-downloader-script/