I'm backend developer and I want to use YouTube Data API for getting video descriptions and tags, but when using this API, sometimes the API is not responsive. After a while, the API returns to normal and works again.
How can solve this problem?
youtubeClass.php
:
<?php
class Youtube
{
/**
* @var string
*/
protected $youtube_key; //pass in by constructor
/**
* @var string
*/
protected $referer;
/**
* @var array
*/
var $APIs = array(
'videos.list' => 'https://www.googleapis.com/youtube/v3/videos',
'search.list' => 'https://www.googleapis.com/youtube/v3/search',
'channels.list' => 'https://www.googleapis.com/youtube/v3/channels',
'playlists.list' => 'https://www.googleapis.com/youtube/v3/playlists',
'playlistItems.list' => 'https://www.googleapis.com/youtube/v3/playlistItems',
'activities' => 'https://www.googleapis.com/youtube/v3/activities',
);
/**
* @var array
*/
public $page_info = array();
/**
* Constructor
* $youtube = new Youtube(array('key' => 'KEY HERE'))
*
* @param array $params
* @throws Exception
*/
public function __construct($params = array())
{
if (!is_array($params)) {
// throw new InvalidArgumentException('The configuration options must be an array.');
}
if (!array_key_exists('key', $params)) {
// throw new InvalidArgumentException('Google API key is required, please visit http://code.google.com/apis/console');
}
$this->youtube_key = $params['key'];
if (array_key_exists('referer', $params)) {
$this->referer = $params['referer'];
}
}
/**
* @param $vId
* @return StdClass
* @throws Exception
*/
public function getVideoInfo($vId)
{
$API_URL = $this->getApi('videos.list');
$params = array(
'id' => $vId,
'key' => $this->youtube_key,
'part' => 'id, snippet, contentDetails,status'
);
$apiData = $this->api_get($API_URL, $params);
return $this->decodeSingle($apiData);
}
/**
* @param $vIds
* @return StdClass
* @throws Exception
*/
public function getVideosInfo($vIds)
{
$ids = is_array($vIds) ? implode(',', $vIds) : $vIds;
$API_URL = $this->getApi('videos.list');
$params = array(
'id' => $ids,
'part' => 'id, snippet, contentDetails, player, statistics, status'
);
$apiData = $this->api_get($API_URL, $params);
return $this->decodeList($apiData);
}
/**
* Parse a youtube URL to get the youtube Vid.
* Support both full URL (www.youtube.com) and short URL (youtu.be)
*
* @param string $youtube_url
* @throws Exception
* @return string Video Id
*/
public static function parseVIdFromURL($youtube_url)
{
if (strpos($youtube_url, 'youtube.com')) {
$params = static::_parse_url_query($youtube_url);
return $params['v'];
} else if (strpos($youtube_url, 'youtu.be')) {
$path = static::_parse_url_path($youtube_url);
$vid = substr($path, 1);
return $vid;
} else {
// throw new Exception('The supplied URL does not look like a Youtube URL');
}
}
/*
* Internally used Methods, set visibility to public to enable more flexibility
*/
/**
* @param $name
* @return mixed
*/
public function getApi($name)
{
return $this->APIs[$name];
}
public function searchAdvanced($params, $pageInfo = false)
{
$API_URL = $this->getApi('search.list');
if (empty($params) || !isset($params['q'])) {
// throw new InvalidArgumentException('at least the Search query must be supplied');
}
$apiData = $this->api_get($API_URL, $params);
if ($pageInfo) {
return array(
'results' => $this->decodeList($apiData),
'info' => $this->page_info
);
} else {
return $this->decodeList($apiData);
}
}
/**
* Decode the response from youtube, extract the single resource object.
* (Don't use this to decode the response containing list of objects)
*
* @param string $apiData the api response from youtube
* @throws Exception
* @return StdClass an Youtube resource object
*/
public function decodeSingle(&$apiData)
{
$resObj = json_decode($apiData);
if (isset($resObj->error)) {
$msg = "Error " . $resObj->error->code . " " . $resObj->error->message;
if (isset($resObj->error->errors[0])) {
$msg .= " : " . $resObj->error->errors[0]->reason;
}
// throw new Exception($msg,$resObj->error->code);
} else {
$itemsArray = $resObj->items;
if (!is_array($itemsArray) || count($itemsArray) == 0) {
return false;
} else {
return $itemsArray[0];
}
}
}
/**
* Queries a single video
* @param $video
* @return Array
**/
public function Single($id = false) {
if($id){
return $this->vMake($this->getVideoInfo($id));
}
}
/**
* Returns a basic video array
* @param $video
* @return Array
**/
public function vMake($video) {
$v = array();
$v['videoid'] = $v['id'] = $video->id;
$v['url'] = 'https://www.youtube.com/watch?v='.$video->id;
$v['thumb'] = $v['thumbnail'] = $video->snippet->thumbnails->medium->url;
$v['title'] = htmlentities($video->snippet->title, ENT_QUOTES, "UTF-8");
$v['description'] = htmlentities($video->snippet->description, ENT_QUOTES, "UTF-8");
$v['duration'] = $this->getDurationSeconds($video->contentDetails->duration);
$v['ptime'] = $video->contentDetails->duration;
$v['privacy'] = $video->status->privacyStatus;
$v['embeddable'] = (bool)$video->status->embeddable;
$v['ytChannelID'] = $video->snippet->channelId;
$v['author'] = $v['ytChannelTitle'] = $video->snippet->channelTitle;
$v['ytPublished'] = $video->snippet->publishedAt;
return $v;
}
/**
* Decodes PT*M*S to seconds
* @param $duration
* @return String
**/
public function getDurationSeconds($duration){
preg_match_all('/[0-9]+[HMS]/',$duration,$matches);
$duration=0;
foreach($matches as $match){
foreach($match as $portion){
$unite=substr($portion,strlen($portion)-1);
switch($unite){
case 'H':{
$duration += substr($portion,0,strlen($portion)-1)*60*60;
}break;
case 'M':{
$duration +=substr($portion,0,strlen($portion)-1)*60;
}break;
case 'S':{
$duration += substr($portion,0,strlen($portion)-1);
}break;
}
}
}
return $duration -1;
/* seems to add +1 to actual duration */
}
/**
* Decode the response from youtube, extract the list of resource objects
*
* @param string $apiData response string from youtube
* @throws Exception
* @return array Array of StdClass objects
*/
public function decodeList(&$apiData)
{
$resObj = json_decode($apiData);
if (isset($resObj->error)) {
$msg = "Error " . $resObj->error->code . " " . $resObj->error->message;
if (isset($resObj->error->errors[0])) {
$msg .= " : " . $resObj->error->errors[0]->reason;
}
// throw new Exception($msg,$resObj->error->code);
} else {
$this->page_info = array(
'resultsPerPage' => $resObj->pageInfo->resultsPerPage,
'totalResults' => $resObj->pageInfo->totalResults,
'kind' => $resObj->kind,
'etag' => $resObj->etag,
'prevPageToken' => NULL,
'nextPageToken' => NULL
);
if(isset($resObj->prevPageToken)){
$this->page_info['prevPageToken'] = $resObj->prevPageToken;
}
if(isset($resObj->nextPageToken)){
$this->page_info['nextPageToken'] = $resObj->nextPageToken;
}
$itemsArray = $resObj->items;
if (!is_array($itemsArray) || count($itemsArray) == 0) {
return false;
} else {
return $itemsArray;
}
}
}
/**
* Using CURL to issue a GET request
*
* @param $url
* @param $params
* @return mixed
* @throws Exception
*/
public function api_get($url, $params)
{
//set the youtube key
$params['key'] = $this->youtube_key;
//boilerplates for CURL
$tuCurl = curl_init();
curl_setopt($tuCurl, CURLOPT_URL, $url . (strpos($url, '?') === false ? '?' : '') . http_build_query($params));
if (strpos($url, 'https') === false) {
curl_setopt($tuCurl, CURLOPT_PORT, 80);
} else {
curl_setopt($tuCurl, CURLOPT_PORT, 443);
}
if ($this->referer !== null) {
curl_setopt($tuCurl, CURLOPT_REFERER, $this->referer);
}
curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);
$tuData = curl_exec($tuCurl);
if (curl_errno($tuCurl)) {
// throw new Exception('Curl Error : ' . curl_error($tuCurl));
}
return $tuData;
}
/**
* Parse the input url string and return just the path part
*
* @param string $url the URL
* @return string the path string
*/
public static function _parse_url_path($url)
{
$array = parse_url($url);
return $array['path'];
}
/**
* Parse the input url string and return an array of query params
*
* @param string $url the URL
* @return array array of query params
*/
public static function _parse_url_query($url)
{
$array = parse_url($url);
$query = $array['query'];
$queryParts = explode('&', $query);
$params = array();
foreach ($queryParts as $param) {
$item = explode('=', $param);
$params[$item[0]] = empty($item[1]) ? '' : $item[1];
}
return $params;
}
}
index.php
:
<?php
if($_POST['q']){
include("./youtubeClass.php");
$youtube = new Youtube(array('key' => 'YOUTUBETOKEN'));
$params = array(
'q' => $_POST['q'],
'type' => $_POST['type'],
'part' => $_POST['part'],