31

How do I check if a video exists on YouTube, using PHP?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Fero
  • 12,969
  • 46
  • 116
  • 157

15 Answers15

52

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 :(
}
Giacomo Pigani
  • 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
  • 2
    this is the quickest method. No API-Registration, just a plain request. Thx! – hi im zvaehn Jan 12 '16 at 09:07
  • This is what I needed! Thanks. – Davey D May 22 '16 at 11:20
  • It should be the best answer for all check youtube video exist question. – Khai Nguyen May 26 '17 at 19:06
  • Handling 401, unauthorized is important as brought up by @gokhan – Mohit Nov 10 '17 at 00:07
  • 1
    A 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
  • Also check for "403". – David Vielhuber Mar 23 '21 at 14:12
  • can't believe this still works! WAY better than using API v3 – Matt Lo Aug 13 '21 at 17:14
  • 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
41

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.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • 13
    An 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
  • how to check it in client side ? using javascript or jquery – Hitesh Mar 02 '15 at 10:03
  • @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
  • 4
    This 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
  • 2
    Would 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
    Please update your answer. API is no longer available. – Jammer Aug 15 '16 at 14:31
  • 3
    This 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
5

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;
    }
Filix Mogilevsky
  • 727
  • 8
  • 13
2

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
gnud
  • 77,584
  • 5
  • 64
  • 78
2

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>
)

divix
  • 1,265
  • 13
  • 27
1

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).

Community
  • 1
  • 1
von v.
  • 16,868
  • 4
  • 60
  • 84
1

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

Linh
  • 57,942
  • 23
  • 262
  • 279
1

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.

Andras Barth
  • 74
  • 11
1

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

paris93
  • 212
  • 1
  • 2
  • 16
0

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:

Also the video code can contain alphanumeric characters, underscores, -characters (dunno what they are called) and possibly more.

Pim Jager
  • 31,965
  • 17
  • 72
  • 98
0

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.

Daniel Sorichetti
  • 1,921
  • 1
  • 20
  • 34
0
/**
* 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:

https://github.com/DimitriMikadze/php-helpers

Dimi Mikadze
  • 474
  • 5
  • 10
0

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;
}
Nadir Latif
  • 3,690
  • 1
  • 15
  • 24
0

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
}
Rodgath
  • 535
  • 5
  • 9
0
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');
}
GSerg
  • 76,472
  • 17
  • 159
  • 346
mahesh
  • 37
  • 2