How do I check if a video exists on YouTube, using PHP?
-
Please be more precise. What do you consider a valid Youtube URL? – Gumbo Sep 05 '09 at 11:15
-
4I assume he means to check if the video exists or not – Alec Smart Sep 05 '09 at 11:18
15 Answers
Youtube has support for the oEmbed format.
Compared to the xml responsed provided by Pascal MARTIN, mine has only to download 600 bytes against 3800 bytes, making it faster and less bandwidth cosuming (only 1/6 of the size).
function yt_exists($videoID) {
$theURL = "http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=$videoID&format=json";
$headers = get_headers($theURL);
return (substr($headers[0], 9, 3) !== "404");
}
$id = 'yyDUC1LUXSU'; //Video id goes here
if (yt_exists($id)) {
// Yep, video is still up and running :)
} else {
// These aren't the droids you're looking for :(
}

- 2,256
- 27
- 36
-
only i'm adding control 401 too.. if not embeddable video this is too must control... if (substr($headers[0], 9, 3) !== "404" || substr($headers[0], 9, 3) !== "401") { – gokhan Dec 15 '14 at 00:38
-
2this is the quickest method. No API-Registration, just a plain request. Thx! – hi im zvaehn Jan 12 '16 at 09:07
-
-
It should be the best answer for all check youtube video exist question. – Khai Nguyen May 26 '17 at 19:06
-
-
1A cleaner way to do this could be ` list($protocol, $statusCode, $statusMsg) = explode(' ', $headers[0]); return $statusCode === '200';` – Profet Nov 21 '17 at 16:57
-
Great solution! Do you know if there are any limits when using the same IP? – John T Dec 17 '18 at 01:53
-
To save more bandwidth, use à PHP stream_context with method HEAD. For exemple stream_context_set_default(array( 'http' => array( 'method' => 'HEAD' ) )) ; – fred727 Jun 14 '19 at 12:08
-
-
-
Looks like a cool solution but it seems like it doesn't work anymore. :/ – stavros.3p Mar 26 '22 at 12:48
-
@Student Are you sure this doesn't work anymore, because it appears that it does, see this for infos on youtube video with [id = 2j7G4vxoDF8](https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=2j7G4vxoDF8&format=json), changing it to [id = 2j7G4vxoDF9](https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=2j7G4vxoDF9&format=json) (which doesn't exists) return an error code of 400 – Giacomo Pigani Mar 26 '22 at 14:13
What about using Youtube's API?
After all, that would mean using some official, which is less likely to change than going with parsing some HTML page.
For more information: YouTube APIs and Tools - Developer's Guide: PHP
The Retrieving a specific video entry seems quite interesting: if you send a request to an URL like this one:
http://gdata.youtube.com/feeds/api/videos/videoID
(replacing "videoID" by the ID of the video, of course – "GeppLPQtihA" in your example), you'll get some ATOM feed if the video is valid; and "Invalid id" if it's not
And, I insist: this way, you rely on a documented API, and not on some kind of behavior that exists today, but is not guaranteed.

- 49,044
- 25
- 144
- 182

- 395,085
- 80
- 655
- 663
-
13An easier way is to just get the response from YouTube's OEMBED page, which is a standard: http://apiblog.youtube.com/2009/10/oembed-support.html EX: http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch%3Fv%3DbDOYN-6gdRE&format=json – streetlogics Feb 13 '12 at 21:16
-
-
@Pascal MARTIN - http://apiblog.youtube.com/2009/10/oembed-support.html- is this link reliable – Hitesh Mar 02 '15 at 10:23
-
Can we use ajax call for this - http://jsfiddle.net/hiteshbhilai2010/vzysD/60/ .... for wrong url it does not shows anything – Hitesh Mar 02 '15 at 11:18
-
4This API version (v2) was deprecated on March 4, 2014 and is now unavailable. You should use this request instead: https://developers.google.com/youtube/v3/docs/videos/list – dbroeks Jun 04 '15 at 08:16
-
2Would you happen to know an equivalent method to this? This method has been depreciated sadly – Webeng Jun 11 '16 at 12:43
-
I am also looking for a current solution @Webeng have you found anything ? – mcgrailm Jun 11 '16 at 23:32
-
@mcgrailm Haven't yet but I'm still looking. I recently posted a question on this with some more info: http://stackoverflow.com/questions/37764851/video-id-validation-for-youtube-api if you hapen to find the answer, let me know pls? I'll also let you know if I happen to find the answer – Webeng Jun 12 '16 at 09:32
-
2
-
3This option is no longer available. I used Giacomo's option to check whether a Youtube's video is available. – imelgrat Feb 21 '18 at 17:45
Here is the solution that I use to check if YouTube video exists using video id. This is C# code, but basically you can check if the thumbnail of the video exists, you will either get 200 or 404 which is very convenient.
private async Task<bool> VideoExists(string id)
{
var httpClient = new HttpClient();
var video = await httpClient.GetAsync($"https://img.youtube.com/vi/{id}/0.jpg");
return video.IsSuccessStatusCode;
}

- 727
- 8
- 13
-
3I've compare this approach with the oembed one. See https://github.com/lycheeverse/lychee/issues/214#issuecomment-819103393 – Micael Levi Apr 14 '21 at 16:40
-
1
-
Be aware that, if the video exists, but this method fails for whatever reason in the future, it will say that the video doesn't exist. – Binar Web Jan 07 '22 at 08:00
Request the URLs with the HEAD method, like so:
HEAD /watch?v=p72I7g-RXpg HTTP/1.1
Host: www.youtube.com
HTTP/1.1 200 OK
[SNIP]
HEAD /watch?v=p72I7g-BOGUS HTTP/1.1
Host: www.youtube.com
HTTP/1.1 303 See Other
[SNIP]
Location: http://www.youtube.com/index?ytsession=pXHSDn5Mgc78t2_s7AwyMvu_Tvxn6szTJFAbsYz8KifV-OP20gt7FShXtE4gNYS9Cb7Eh55SgoeFznYK616MmFrT3Cecfu8BcNJ7cs8B6YPddHQSQFT7fSIXFHd5FmQBk299p9_YFCrEBBwTgtYhzKL-jYKPp2zZaACNnDkeZxCr9JEoNEDXyqLvgbB1w8zgOjJacI4iIS6_QvIdmdmLXz7EhBSl92O-qHOG9Rf1HNux_xrcB_xCAz3P3_KbryeQk_9JSRFgCWWgfwWMM3SjrE74-vkSDm5jVRE3ZlUI6bHLgVb7rcIPcg

- 77,584
- 5
- 64
- 78
-
3youtube returns 200 even for videos that don't exist, as long as the id seems correct – yoniLavi Apr 28 '14 at 20:53
A new way to get a YouTube video data after September 2021, is by cURL in PHP:
function getYouTubeData($videoId) {
$theURL = "https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=$videoId&format=json";
$curl = curl_init($theURL);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($curl);
curl_close($curl);
return json_decode($body, true);
}
Usage:
$ytData = getYouTubeData($video_id);
if (empty($ytData)) {
$error = 'YouTube movie data could not be fetched.';
}
$title = $ytData['title'];
Sample output:
Array
(
[title] => Use online tools available at Laminas Starter Kit - Laminas MVC
[author_name] => Divix
[author_url] => https://www.youtube.com/channel/UC6lBQpNdQH6cu0j15qhkCAg
[type] => video
[height] => 113
[width] => 200
[version] => 1.0
[provider_name] => YouTube
[provider_url] => https://www.youtube.com/
[thumbnail_height] => 360
[thumbnail_width] => 480
[thumbnail_url] => https://i.ytimg.com/vi/LjDdAcB9-Mo/hqdefault.jpg
[html] => <iframe width="200" height="113" src="https://www.youtube.com/embed/LjDdAcB9-Mo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
)

- 1,265
- 13
- 27
-
1If video not have allowed embedding, this API not working. – Ivijan Stefan Stipić Dec 13 '21 at 20:13
-
Also, if the video exists, but this method fails in the future, it will say the video doesn't exist. – Binar Web Jan 07 '22 at 07:58
-
As commented by @dbro, the answer by Pascal MARTIN was an acceptable answer at that time. However, since the API had moved forward, fixed and improved, a new solution that works is the following. Please take note that this is based on the technique provided by @Pascal and I quote:
...if you send a request to an URL like this one
http://gdata.youtube.com/feeds/api/videos/videoID
(Replacing "videoID" by the idea of the video, of course -- "GeppLPQtihA" in your example)
You'll get some ATOM feed (**STOP HERE**)
The new URL to use and this is for V3 of the API is https://www.googleapis.com/youtube/v3/videos?id={the_id_of_the_video}&key={your_api_key}&part={parts}
WHERE
{the_id_of_the_video}
you should know what this is{your_api_key}
is your app's key that can be found in your Developer Console{parts}
a comma-separated list, check here for valid values
Now for the Result
If the Video Id is VALID you will get data in the items field that includes the Id of the video and the information you queried through the parts parameter.
If the Video Id is NOT VALID then you will get an empty items.
Supplying a wrong key gives you an ERROR 400 (an error object).
You should request to this URL
https://www.googleapis.com/youtube/v3/videos?id={the_id_of_the_video}&key={your_api_key}&part=status
After that, you will receive the response json that contains uploadStatus
field
{
etag = "\"I_8xdZu766_FSaexEaDXTIfEWc0/8QgL7Pcv5G8OwpNyKYJa8PaQTc0\"";
items = (
{
...
status = {
embeddable = 1;
license = youtube;
privacyStatus = public;
publicStatsViewable = 1;
uploadStatus = processed;
};
}
);
...
}
And there are 5 possible value for uploadStatus
deleted, failed, processed, rejected, uploaded
For uploadStatus
= processed
or uploaded
=> your youtube video is available

- 57,942
- 23
- 262
- 279
Found this solution on github: Check if youtube video exists
Easy to use:
$headers = get_headers('http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=nonexistingid');
if (!strpos($headers[0], '200')) {
echo "The YouTube video you entered does not exist";
}
Working fine.

- 74
- 11
-
-
2
-
Note that this won't work for not embeddable videos like `http://www.youtube.com/watch?v=MCs5OvhV9S4` (see: https://stackoverflow.com/a/5655148/270334) – Micael Levi Apr 14 '21 at 16:38
Here is a solution that doesn't involve using youtube api, it checks if the video id exists when the url is loaded
function checkYoutubeUrlIsValid($url) {
$buffer = file_get_contents($url);
$matches = [];
preg_match('#[a-zA-Z0-9_-]{11}$#', $url, $matches);
return strpos($buffer, $matches[0]) !== false;
}
Hope that helps

- 212
- 1
- 2
- 16
You want to validate if a youtube url is an url to a real youtube video? This is quite hard, you could use regular expressions, but keep in mind that there are loads of valid ways to express a youtube url:
- http://www.youtube.com/watch?v=p72I7g-RXpg
- http://www.youtube.com/watch?asv=76621-2&v=p72I7g-RXpg
- http://www.youtube.com/v/RdPxlTX27Fk
- etc.
Also the video code can contain alphanumeric characters, underscores, -characters (dunno what they are called) and possibly more.

- 31,965
- 17
- 72
- 98
Another (kind of inefficient) way is to use cURL to get the HTML of the supposed video page and run some regular expressions to verify that it's an actual video page.

- 1,921
- 1
- 20
- 34
/**
* Check youtube url, check video exists or not,
*
* @param $url full youtube video url
*
* @return string - yotube video id
*/
public static function checkYoutube($url)
{
if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match))
{
$headers = get_headers('http://gdata.youtube.com/feeds/api/videos/' . $match[1]);
if (strpos($headers[0], '200'))
{
return $match[1];
}
return false;
}
return false;
}
link:

- 474
- 5
- 10
-
This is no longer supported, at every video there is a result "No longer available" – simon Jan 10 '16 at 23:38
I used the YouTube API for checking if a video exists on You Tube. I downloaded the Google API Client Library for PHP. I used the following function:
/**
* Used to check if the given movie is availabe on youtube
*
* It uses youtube api and checks if given movie is available on youtube
* If a movie is not available then it returns false
*
* @param string $youtube_video_url the youtube movie url
*
* @return boolean $is_available indicates if the given video is available on youtube
*/
private function IsMovieAvailable($youtube_video_url)
{
/** The autoload.php file is included */
include_once("autoload.php");
/** Is available is set to false */
$is_available = false;
/** The youtube video id is extracted */
$video_id = str_replace("https://www.youtube.com/watch?v=", "", $youtube_video_url);
$DEVELOPER_KEY = $google_api_key;
$client = new \Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new \Google_Service_YouTube($client);
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->videos->listVideos('status', array('id' => $video_id));
/** Each item in the search results is checked */
foreach ($searchResponse['items'] as $video) {
/** If the video id matches the given id then function returns true */
if ($video['id'] == $video_id) {
$is_available = true;
break;
}
}
return $is_available;
}

- 3,690
- 1
- 15
- 24
Here's a quick simple faster solution using the HEAD request method.
function check_youtube_video_exists($video_url) {
if (strpos($video_url, 'youtube.com') > 0 || strpos($video_url, 'youtu.be') > 0) {
$video_url = 'https://www.youtube.com/oembed?url='. $video_url .'&format=json';
}
$headers = @get_headers($video_url);
return (strpos($headers[0], '200') > 0) ? true : false;
}
Check your YouTube URL like so:
if (check_remote_video_exists('YOUR_YOUTUBE_VIDEO_URL')) {
// video exists, do stuff
} else {
// video does not exist, do other stuff
}

- 535
- 5
- 9
http://www.youtube.com/watch?v=bQVoAWSP7k4 http://www.youtube.com/watch?v=bQVoAWSP7k4&feature=popular http://www.youtube.com/watch?v=McNqjYiFmyQ&feature=related&bhablah http://youtube.com/watch?v=bQVoAWSP7k4
var matches = $('#videoUrl').val().match(/http:\/\/(?:www\.)?youtube.*watch\?v=([a-zA-Z0-9\-_]+)/);
if (matches) {
alert('valid');
} else {
alert('Invalid');
}
-
This one cannot detect if the video is removed from youtube, it's not related to the question – Anh Hoang Oct 29 '18 at 04:14