32 – YouTube Data API – Get All Playlists For A Channel

This is article 32 of the YouTube API With PHP series.

In this article, we examine how to fetch all the playlists created within a channel. There is no documented limit on the number of playlists a user can create within a channel. The YouTube Data API 3.0 also says that the api can fetch all the playlists in the channel. However, at this stage, I have not really tested this code with channels containing more than a 100 channels or so.

The logic to get playlists is the same as getting videos from a channel. Each request can get a maximum of 50 items. There is no option to sort the items on any field. And in case there are more playlists available, the nextPageToken will contain the token to do the next fetch request.

The Request URL is

GET https://www.googleapis.com/youtube/v3/playLists

Sample code to fetch the playlists of a Channel

<?php
    error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED);
    set_time_limit(60 * 3);
    
    $g_youtubeDataAPIKey = "xxxx";
    $totalCount = 0;
    $output = ""; 
    $channelId = "UC5_j0dmvXE0xs6ra-clGz4A";
        // make api request
        $url = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=" .
            $channelId. "&maxResults=50&key=" . $g_youtubeDataAPIKey;
	echo($url);
	//$handle = fopen('php://temp', 'w+');

        $curl = curl_init();
        curl_setopt_array($curl, array(
                    CURLOPT_RETURNTRANSFER => 1,
                    CURLOPT_URL => $url,
                    CURLOPT_USERAGENT => 'Codular Sample cURL Request',
                    CURLOPT_SSL_VERIFYPEER => 1,
                    CURLOPT_SSL_VERIFYHOST=> 0,
		    CURLOPT_VERBOSE=>false,
		    CURLOPT_FOLLOWLOCATION => TRUE
                    ));
        $resp = curl_exec($curl);

        curl_close($curl);

        if ($resp) {
        // first level search
            $json = json_decode($resp);
            if ($json) {
                $nextPageToken = $json->nextPageToken;
                $total = $json->pageInfo->totalResults;

                $items = $json->items;
                
            }
	    $totalCount += intval(count($items));
            foreach($items as $item) {
                $playlistId = $item->id;
                $playlistTitle = $item->snippet->title;
                $playlistDesc = $item->snippet->description;
                $thumbnail= $item->snippet->thumbnails->high->url;
                $rawDate = $item->snippet->publishedAt;

		$tnails = $item->snippet->thumbnails;
		$arrTNails = json_decode(json_encode($tnails), true);
		$tnOutput = "\t\tTHUMBNAILS:\n";
		foreach($arrTNails as $key=>$value) {
		    $tnOutput .= "\t\t" . $key . ":";
		    $tnOutput .= $value["url"] . "," . $value["width"] . " x " . $value["height"] . "\n";
		}
                $output .= $playlistId . ", " . $playlistTitle . "," . $rawDate . "\n" . $tnOutput . "\n\n";
                    
            }
            
	    // second level search using nextpage token
            echo("<br><h2>Second phase</h2><br>");
            while ($nextPageToken != null) {
		  $url = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=" .
            	  $channelId. "&maxResults=50&key=" . $g_youtubeDataAPIKey .  "&pageToken=" . $nextPageToken ;

                $curl = curl_init();
                curl_setopt_array($curl, array(
                            CURLOPT_RETURNTRANSFER => 1,
                            CURLOPT_URL => $url,
                            CURLOPT_USERAGENT => 'Codular Sample cURL Request',
                            CURLOPT_SSL_VERIFYPEER => 1,
                            CURLOPT_SSL_VERIFYHOST=> 0,
                            CURLOPT_FOLLOWLOCATION => TRUE
                            ));
                $resp = curl_exec($curl);

                 if ($resp) {
		    $json = json_decode($resp);
		    if ($json) {
			$nextPageToken = $json->nextPageToken;
			$total = $json->pageInfo->totalResults;

			$items = $json->items;
		    }
		    $totalCount += intval(count($items));

		    foreach($items as $item) {
			$playlistId = $item->id;
			$playlistTitle = $item->snippet->title;
			$playlistDesc = $item->snippet->description;
			$thumbnail= $item->snippet->thumbnails->high->url;
			$rawDate = $item->snippet->publishedAt;

			$tnails = $item->snippet->thumbnails;
			$arrTNails = json_decode(json_encode($tnails), true);
			$tnOutput = "\t\tTHUMBNAILS:\n";
			foreach($arrTNails as $key=>$value) {
			    $tnOutput .= "\t\t" . $key . ":";
			    $tnOutput .= $value["url"] . "," . $value["width"] . " x " . $value["height"] . "\n";
			}
			$output .= $playlistId . ", " . $playlistTitle . "," . $rawDate . "\n" . $tnOutput . "\n\n";
			    
		    }
	 
                // sometimes pagetoken is filled but no items are fetched , in such a case stop the code
                if (count($items) == 0)
                    $nextPageToken = null;
                    
              } // while $nextPageToken

	   } // if $resp
                
	    echo($output);
	    echo("total playlists="  . $totalCount . "\n");
            exit("done");
           	    
    } // if $resp || incremental
    else {
	exit("Youtube api request did not work");
    }

    
?>

It is assumed that the code will be run on the command so the output uses newline and tab symbols for basic formatting. You can use html tags if the code will be run in a browser. Here is some part of the output:

https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLC98ABC853EAEFD7F&maxResults=50&key=AIzaSyAJrlFVIJEP0ZgT9tMCJZp_ILy6MsjGhTAstring(48729) "{
  "kind": "youtube#playlistItemListResponse",
  "etag": "e_pqYErRLaDDTHJ5sxSDQWPJGCI",
  "items": [
    {
      "kind": "youtube#playlistItem",
      "etag": "q23V9zOdoZrUg3Jg4ljH1c_1yX0",
      "id": "UExDOThBQkM4NTNFQUVGRDdGLjEyRjM4QTM3OTYwODNCMDA",
      "snippet": {
        "publishedAt": "2011-12-31T07:55:09Z",
        "channelId": "UC5_j0dmvXE0xs6ra-clGz4A",
        "title": "Corso Pascal (Turbo/FPC)  - 01 Struttura del corso",
        "description": "01 Prima lezione di un corso completo (principianti e avanzato) di ben 15 ore.\r\n\r\nPerchè seguire questo corso:\r\n- molti aspiranti programmatori si 'buttano' direttamente su linguaggi più ostici come il C o il C++ (tranquilli, ho un corso completo anche di quello!) e sbattono la testa; il Pascal è come la bici con le 'rotelline' che ti aiutano finchè hai bisogno\r\n- ha tutte le caratteristiche fondamentali di un buon linguaggio\r\n- il corso insegna a programmare e non semplicemente il Pascal, cosa MOLTO diversa!\r\n- è un linguaggio elegante e 'puro', ti aiuta a non commettere errori e ad acquisire uno stile di programmazione corretto\r\n- il mio metodo prevede prima il Pascal, poi il C/C++  (escludendo la OOP) che a questo punto sembrerà molto più semplice, poi Visual Studio con C# / .Net e ASP .NET \r\n- ha una fantastica base di programmatori affezionati e molti siti dedicati\r\n- nelle lezioni non dò praticamente nulla per scontato e si procede realmente passo passo\r\n- accompagnerò le videolezioni con molti esercizi risolti\r\n- renderò disponibile anche una dispensa scritta che ricalca il videocorso, ricca di esercizi risolti\r\n- vengono trattati in modo esteso argomenti che difficilmente lo sono (ricorsione, strutture dati dinamiche con puntatori)",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/C1ttJju1RKc/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/C1ttJju1RKc/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/C1ttJju1RKc/hqdefault.jpg",
            "width": 480,
            "height": 360
          },
          "standard": {
            "url": "https://i.ytimg.com/vi/C1ttJju1RKc/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/C1ttJju1RKc/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "channelTitle": "fcamuso",
        "playlistId": "PLC98ABC853EAEFD7F",
        "position": 0,
        "resourceId": {
          "kind": "youtube#video",
          "videoId": "C1ttJju1RKc"
        },
        "videoOwnerChannelTitle": "fcamuso",
        "videoOwnerChannelId": "UC5_j0dmvXE0xs6ra-clGz4A"
      }
    },
    {
      "kind": "youtube#playlistItem",
      "etag": "_a7BLTinCeLWdQv--2f-Sc7unpM",
      "id": "UExDOThBQkM4NTNFQUVGRDdGLjI3MzZBQkIyODJDNUEyM0U",
      "snippet": {
        "publishedAt": "2011-12-31T07:55:09Z",
        "channelId": "UC5_j0dmvXE0xs6ra-clGz4A",
        "title": "Corso Pascal (Turbo/FPC)  02 Struttura. Identificatori. Principali errori.",
        "description": "Struttura di un programma Pascal. Scegliere al meglio i nomi per gli identificatori. Evitare i principali errori. L'importanza del commento del codice. I primi programmi di calcolo.",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/cblRxEP9wo0/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/cblRxEP9wo0/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/cblRxEP9wo0/hqdefault.jpg",
            "width": 480,
            "height": 360
          },
          "standard": {
            "url": "https://i.ytimg.com/vi/cblRxEP9wo0/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/cblRxEP9wo0/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "channelTitle": "fcamuso",
        "playlistId": "PLC98ABC853EAEFD7F",
        "position": 1,
        "resourceId": {
          "kind": "youtube#video",
          "videoId": "cblRxEP9wo0"
        },
        "videoOwnerChannelTitle": "fcamuso",
        "videoOwnerChannelId": "UC5_j0dmvXE0xs6ra-clGz4A"
      }
    },

Be the first to comment

Leave a Reply

Your email address will not be published.


*