Hello I'm am now on a project that using YouTube api,
I am bit of stuck on how to fetch top 10 channel of a content owner at YouTube by using their api.
Right now what i am doing is that i need to loop all the channel i had and sort it by their views.
loop {
$analytics = $youtube->reports->query('contentOwner==$content_id', $start_date , $end_date , 'views,comments,likes,dislikes,estimatedMinutesWatched,averageViewDuration,shares,estimatedRevenue,estimatedAdRevenue,monetizedPlaybacks,adImpressions',array('filters'=> $id ,'max-results'=>$max_result));
}
It is fine but as it need to loop all the channel it takes quite some time. Is there any other way to fetch top 10 channel directly ?
By the way, is there any other way to by pass user consent?
problem solved after i do a lot of try and error,
youtube provide an api explorer for developer to test query parameter right away.
as i explain in the question i had successfully able to fetch/retrieve the data for a channel by using loop.
actually i can just put every channel id with comma to retrieve all the channel i manage.
before PHP example
loop {
$id = 'channel==' . $id;
$analytics = $youtube->reports->query('contentOwner==$content_id', $start_date , $end_date , 'views,comments,likes,dislikes,estimatedMinutesWatched,averageViewDuration,shares,estimatedRevenue,estimatedAdRevenue,monetizedPlaybacks,adImpressions',array('filters'=> $id ,'max-results'=>$max_result));
}
new or solved php example
$id = 'channel==' . implode(',', $id);
$analytics = $youtube->reports->query('contentOwner==$content_id', $start_date , $end_date,'views,comments,likes,dislikes,estimatedMinutesWatched,averageViewDuration,shares,estimatedRevenue,estimatedAdRevenue,monetizedPlaybacks,adImpressions',array('filters'=> $id ,'max-results'=>$max_result));
youtube already give the documentation on how to use their api, but i think it is quite hard to understand. Therefore i am able to use the api only when i do alot of try and error.
Thank you.
Related
My inexperience has left me short of understanding how to hide an API Key. Sorry, but I've been away from web development for 15 years as I specialized in relational databases, and a lot has changed.
I've read a ton of articles, but don't understand how to take advantage of them. I want to put my YouTube API key(s) on the server, but have the client able to use them w/o exposure. I don't understand how setting an API Key on my server (ISP provided) enables the client to access the YouTube channel associated with the project. Can someone explain this to me?
I am not sure what you want to do but for a project I worked on I needed to get a specific playlist from YouTube and make the contents public to the visitors of the website.
What I did is a sort of proxy. I set up a php file contains the api key, and then have the end user get the YT content through this php file.
The php file gets the content form YT using curl.
I hope it helps.
EDIT 1
The way to hide the key is to put it in a PHP file on the server.
This PHP file will the one connecting to youtube and retrieving the data you want on your client page.
This example of code, with the correct api key and correct playlist id will get a json file with the 10 first tracks of the play list.
The $resp will have the json data. To extract it, it has to be decoded for example into an associative array. Once in the array it can be easily mixed in to the html that will be rendered on the client browser.
<?php
$apiKey = "AIza...";
$results = "10";
$playList = "PL0WeB6UKDIHRyXXXXXXXXXX...";
$request = "https://www.googleapis.com/youtube/v3/playlistItems?part=id,contentDetails,snippet&maxResults=" . $results .
"&fields=items(contentDetails%2FvideoId%2Cid%2Csnippet(position%2CpublishedAt%2Cthumbnails%2Fdefault%2Ctitle))" .
"&playlistId=" . $playList .
"&key=" . $apiKey;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $request,
CURLOPT_SSL_VERIFYPEER => false
));
$resp = curl_exec($curl);
if (curl_errno($curl)) {
$status = "CURL_ERROR";
}else{
// check the HTTP status code of the request
$resultStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($resultStatus == 200) {
$status = "OK";
//Do something with the $resp which is in JSON format.
//Like decoding it into an associative array
} else {
$status = "YT_ERROR";
}
}
curl_close($curl);
?>
<html>
<!-- your html here -->
</html>
Note: CURLOPT_SSL_VERIFYPEER is set to false. This is in development. For prod it should be true.
Also note that using the api this way, you can restrict the calls to your api key bounding them to your domain. You do that in the googla api console. (Tip for production)
i want to show public contents from instagram related to a specific hashtag (everything works fine with that) but i can't to renew the access_token everytime it expires.
("do not assume your access_token is valid forever." -
https://www.instagram.com/developer/authentication/)
To renew it manually is not an option i have to make sure there is a valid access_token at ANY time without re-authenticating.
Any ideas or questions? :)
I have one idea, but without API (and access_token). You can make requests to the web-version of Instagram with ?__a=1 parameter. I do not know how long it will work but now there is workflow:
You want to show public content with hashtag space, for example.
Add it to url and add GET-parameter ?__a=1: https://www.instagram.com/explore/tags/space/?__a=1
Make the GET-request. It returns json with nodes in top_posts (8) and media (18). Each node has owner, caption, number of comments and likes. But the most important part is in thumbnail_src and display_src.
There is page_info in media object which helps to paginate results. You need end_cursor (for example, J0HWE9rjAAAAF0HWE9qvgAAAFiYA)
Add the value from end_cursor to the url: https://www.instagram.com/explore/tags/space/?__a=1&max_id=J0HWE9rjAAAAF0HWE9qvgAAAFiYA
Repeat 3-6 to get newest posts with specific hashtag.
Update to the ?__a=1 url param. This appears to have stopped working with users '/account/?__a=1' endpoints.:( Still works on tags apparently.
Instagram shut down their public API. Here's a quick and dirty workaround in PHP:
<?php
function getPublicInfo($username) {
$url = sprintf("https://www.instagram.com/$username");
$content = file_get_contents($url);
$content = explode("window._sharedData = ", $content)[1];
$content = explode(";</script>", $content)[0];
$data = json_decode($content, true);
return $data['entry_data']['ProfilePage'][0];
}
Not sure for how long it's gonna work. Here's one for Javascript.
i am trying with youtube api v3 php search...
first time i'm using this api for this i am beginner...
i have 3 question;
1) how can below search list showing pagination numbers? (per page 50 result)
2) how can video duration show in list? (3:20 min:second)
3) how can order viewCount
if ($_GET['q']) {
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_YoutubeService.php';
$DEVELOPER_KEY = 'my key';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
$youtube = new Google_YoutubeService($client);
try {
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $_GET['q'],
'maxResults' => 50,
'type' => "video",
));
foreach ($searchResponse['items'] as $searchResult) {
$videos .= '<li style="clear:left"><img src="'.$searchResult['snippet']['thumbnails']['default']['url'].'" style="float:left; margin-right:18px" alt="" /><span style="float:left">'.$searchResult['snippet']['title'].'<br />'.$searchResult['id']['videoId'].'<br />'.$searchResult['snippet']['publishedAt'].'<br />'.$item['contentDetails']['duration'].'</span></li>';
}
$htmlBody .= <<<END
<ul>$videos</ul>
END;
} catch (Google_ServiceException $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
}
1) how can below search list showing pagination numbers? (per page 50 result)
You need to write your own cacheing logic to implement this feature because with every result you get two tokens "NextPageToken" and "PreviousPageToken" and subsequent query must contain that token number to get next page or previous page token like below.
So whenever results are not available at cache then you should send either nextpagetoken or previous page token.
https://www.googleapis.com/youtube/v3/search?key=API_KEY&part=snippet&q=japan&maxResults=10&order=date&pageToken=NEXT_or_PREVIOUS_PAGE_TOKEN
In particular your case where you need 50 pages per page and you are showing 3 pagination like (1,2,NEXT) then you need to fetch results two times. Both the results you will keep in cache so for page 1 and 2 results will be retrieved from cache. For next you make it sure that you are making query google again by sending nextPageToken.
Thus to show pagination 1-n and every page 50 results then you need to make n-1 queries to google api. But if you are showing 10 results per page then you cane make single query of 50 results using which you can show first 5 pages (1-5) with the help of retrieved results and at next you should again send next page token like above.
NOTE- Google youtube api provide 50 results max.
2) how can video duration show in list? (3:20 min:second)
Youtube API v3 do not return video duration at simple first search response. To get video duration we need to make one extra call to youtube api like below.
https://www.googleapis.com/youtube/v3/videos?id=VIDEO_ID1%2CVIDEO_ID2&part=contentDetails&key=API_KEY (max 50 IDs)
This issue is highlighted in "http://code.google.com/p/gdata-issues/issues/detail?id=4294".I posted my answer here too.
Hence if we want to display video duration then we need to make two calls every time.
3) how can order viewCount
Trigger below query it will provide results ordered by view count.
https://www.googleapis.com/youtube/v3/search?key=KEY&part=snippet&q=japan&maxResults=5&order=viewCount
For detail please refer this - https://developers.google.com/youtube/v3/docs/search/list#order
The youTube API V3 is somehow complicated compare to API V2.
To the question above, my approach is not for search result rather is to retrieve user uploaded videos. I believe this can be useful
References
The way you create pagination in v3 is not the same as in v2 where you can make your call simply like
$youtube = "http://gdata.youtube.com/feeds/api/users/Qtube247/uploads?v=2&alt=jsonc&start-index=1&max-results=50";
In v3 you need to make two or three calls the first one will be to get the channel detail and second call will be to retrieve playlist from where we will get the channel playlist Id and finally retrieve individual video data.
I am using Php CURL
$youtube = “https://www.googleapis.com/youtube/v3/channels?part=snippet%2CcontentDetails%2Cstatistics&id=yourChannelIdgoeshere&key=yourApiKey”;
Here we retrieve user playlist ID
$result = json_decode($return, true);
$playlistId=$result['items'][0]['contentDetails']['relatedPlaylists']['uploads'];
we define pagetoken
$pageToken=’’;
Each time user click control button we retrieve pagetoken from session[] and feed the curl url, and in turn will produce nextpagetoken or prevpagetoken. Whatever you feed the url the Api know what set of list to populate.
if(isset($_REQUEST['ptk']) && $_REQUEST['ptk’]!==''){
$pageToken=$_REQUEST['ptk’];
}
Here we retrieve user playlist
$ playlistItems =”https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&pageToken=”.$pageToken.”&maxResults=50&playlistId=$playlistId&key= yourApiKey”;
If user has more than maxResult, we should have nextPageToken, take for an example user has 200 uploaded videos,the first pagetoken may be CDIQAA and next pagetoken may be CGQQAA while previous may be CDIQAQ , something like that so is not a number.
Here we save the pagetoken
if(isset($result['nextPageToken'])) { $_SESSION[nextToken]=$result['nextPageToken'];
}
if(isset($result['prevPageToken'])) { $_SESSION[prevToken]=$result['prevPageToken'];
}
we can then create our control button <>
$next=$_SESSION[nextToken];
$prev=$_SESSION[prevToken];
The control button here
<a href=”?ptk=<?php echo $prev?>” ><<prev</a>
<a href=”?ptk=<?php echo $next?>” >next>></a>
From here when user click link it set either next or prev page in session variable (go to up to see how this work)
To get video duration we use same Php curl
$videoDetails="https://www.googleapis.com/youtube/v3/videos?part=id,snippet,contentDetails,statistics,status&id=videoIdHere&key=yourApiKey";
$videoData = json_decode($return, true);
$duration = $videoData['items'][0]['contentDetails']['duration'];
$viewCount = $videoData['items'][0]['statistics']['viewCount'];
you may get something like this ('PT2H34M25S')
I have answer a question Here which show you how to convert the duration data
See Working Demo Here
I do have a hughe database where some data sets link to certain youtube videos. As we all know some youtube videos disappear after a while from youtube and this leads to my solution and my problem as well --> I'd like to check if the youtube video still exists by simply checking via JSON if there is data to retrieve from a video. If not than I'd simply delete that certain data set.
So the first part of my solution would be to go through each row of my data table and checking for each id if there is data to retrieve from youtube as seen in the following code:
$result = $db->query("SELECT id, link FROM songs");
while($row = $result->fetch_assoc())
{
$number = 1+$rown++;
$id = $row['id'];
$link = $row['link'];
$video_ID = $link;
$JSON = file_get_contents("https://gdata.youtube.com/feeds/api/videos/{$video_ID}?v=2&alt=json");
$JSON_Data = json_decode($JSON);
$views = $JSON_Data->{'entry'}->{'yt$statistics'}->{'viewCount'};
echo $number .' row<br />';
echo $link .' link<br />';
echo $views .' views<br /><br />';
}
This attempt works fine and outputs me the data I need. The only problem is, that it just gets me data from the first 150-190 rows and that's it. Now I am checking for a solution that checks each row for empty youtube data and this lead to two concrete questions I have:
1st) Might youtube be responsible for that due to a restriction in retrieving data from one single query?
2nd) Might this be a server issue of mine that stops queries after x-seconds (but I already expand the time limit by putting a line set_time_limit (10000000); into my php code but without success)?
Hope you can help, thanks in advance.
YouTube, naturally, enforces limits on how many requests you can make per period of time. Unfortunately, there are no clear guidelines on what those limits are ... for v2, the guidelines merely state:
The YouTube API enforces quotas to prevent problems associated with
irregular API usage. Specifically, a too_many_recent_calls error
indicates that the API servers have received too many calls from the
same caller in a short amount of time. If you receive this type of
error, then we recommend that you wait a few minutes and then try your
request again.
If time isn't an issue for you, you could slow down each query so that you only make 1 request per every 10-15 seconds or so. Alternatively, you'd probably have better luck batch processing. With this, you can make up to 50 requests at once (this counts as 50 requests against your overall request per day quota, but only as one against your per time quota). Batch processing with v2 of the API is a little involved, as you make a POST request to a batch endpoint first, and then based on those results you can send in the multiple requests. Here's the documentation:
https://developers.google.com/youtube/2.0/developers_guide_protocol?hl=en#Batch_processing
Batch processing is much easier with v3, as you just have the videoId parameter be a comma delimited list of the videos you want info on -- so in your case, you'd execute file_get_contents on a URL like this:
https://www.googleapis.com/youtube/v3/videos?part=id&id={comma-separated-list-of-IDs}&maxResults=50&key={YOUR_API_KEY}
Any video ID in your list that doesn't come back in the JSON response doesn't exist anymore. IF you do 50 at a time, wait for 15 seconds, do another 50, etc., that should give you better performance.
I'm currently in the middle of a project that involves YouTube API. I'm using the Zend Gdata, and everything has gone nicely until this.
I need to get a Zend_Gdata_YouTube_PlaylistListEntry based on the ID of the playlist. I have managed to retrieve the videos with some fiddling:
$feed = $yt->getVideoFeed('http://gdata.youtube.com/feeds/api/playlists/'.$id.'?v=2');
$playlist = new Zend_Gdata_YouTube_PlaylistListEntry($feed->getDOM());
However, I need to use the method $playlist->getPlaylistVideoFeedUrl(), and it returns NULL in this case.
Any help regarding this is appreciated =)
Got it:
$url = 'http://gdata.youtube.com/feeds/api/playlists/'.$input['id'].'?v=2';
$feed = $yt->getPlaylistVideoFeed($url);