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:
<?phpclass 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:
<?phpif($_POST['q']){ include("./youtubeClass.php"); $youtube = new Youtube(array('key' => 'YOUTUBETOKEN')); $params = array('q' => $_POST['q'],'type' => $_POST['type'],'part' => $_POST['part'],'videoEmbeddable' => $_POST['videoEmbeddable'],'maxResults' => $_POST['maxResults'],'pageToken' =>$_POST['pageToken'] ); $ytVideos = $youtube->searchAdvanced($params,true); $videos = array(); foreach($ytVideos['results'] as $vd){ $video = $youtube->Single($vd->id->videoId); $videoInf = array("title" => $video['title'],"description" => $video['description'],"id" => $video['id'],"duration" => $video['duration'],"author" => $video['author'] ); // $videos[] = $videoInf; array_push($videos,$videoInf); } $videos = json_encode($videos); print_r($videos);}else{ echo '';}and the third file to call index.php, callApi.php:
$ch = curl_init('http://www.sample.com/youtube/index.php'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); // execute! $response = curl_exec($ch); // close the connection, release resources used curl_close($ch); // do anything you want with your response $response = json_decode($response); var_dump($response);$response is NULL.