I am trying to download the most recent items from a YouTube playlist in a C# .NET program. Right now I have a program that successfully gets the necessary data from my channel's Uploads playlist using "channel.ContentDetails.RelatedPlaylists.Uploads;", which I got from the sample program on the API page. But I can't find any information in the api docs about how to switch that line or lines around it to get a playlist by ID rather than my own uploads.
This is not a duplicate because other examples on this page explain how to find it through an http link, as in "http://gdata.youtube.com/feeds/api/playlists/..." etc. I want to do it directly through the API's methods. The part of my code that downloads the data is included below.
private async Task Run()
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "API KEY HERE",
ApplicationName = this.GetType().ToString()
});
//MAYBE I NEED TO CHANGE THIS? SOMETHING LIKE
//'youtubeservice.Playlists.IDUNNOWHAT'
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Id = "CHANNEL ID HERE";
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
{
//OR MAYBE I NEED TO CHANGE THIS PART?
//LIKE 'channel.ContentDetails.SOMETHING
var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;
var nextPageToken = "";
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
/*
* DO A BUNCH OF STUFF WITH THE YOUTUBE DATA
*/
nextPageToken = playlistItemsListResponse.NextPageToken;
}
}
}
In the documentation, it lists the playlists you can get by using ContentDetails.RelatedPlaylists:
likes
favorites
uploads
watchHistory
watchLater
Therefore, if you want to get the items for a playlist you created you won't be able to do it using ContentDetails.RelatedPlaylists, you'll have to provide the playlist ID. I believe it should work with the code you provided (might need a few tweaks) if you change
playlistItemsListRequest.PlaylistId = uploadsListId;
to use the ID of the playlist whose videos you want to get.
Related
I'm trying to download captions from some videos on Youtube using their nuget package. Here's some code:
var request = _youtube.Search.List("snippet,id");
request.Q = "Bill Gates";
request.MaxResults = 50;
request.Type = "video";
var results = request.Execute();
foreach (var result in results.Items)
{
var captionListRequest = _youtube.Captions.List("id,snippet", result.Id.VideoId);
var captionListResponse = captionListRequest.Execute();
var russianCaptions =
captionListResponse.Items.FirstOrDefault(c => c.Snippet.Language.ToLower() == "ru");
if (russianCaptions != null)
{
var downloadRequest = _youtube.Captions.Download(russianCaptions.Id);
downloadRequest.Tfmt = CaptionsResource.DownloadRequest.TfmtEnum.Srt;
var ms = new MemoryStream();
downloadRequest.Download(ms);
}
}
When the Download method is called I'm getting a weird Newtonsoft.JSON Exception that says:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: T. Path '', line 0, position 0.'
at Newtonsoft.Json.JsonTextReader.ParseValue()
I've read some other threads on captions downloading problems and have tried to change my authorization workflow: first I've tried to use just the ApiKey but then also tried OAuth. Here's how it looks now:
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "CLIENT_ID",
ClientSecret = "CLIENT_SECRET"
},
new[] { YouTubeService.Scope.YoutubeForceSsl },
"user",
CancellationToken.None,
new FileDataStore("Youtube.CaptionsCrawler")).Result;
_youtube = new YouTubeService(new BaseClientService.Initializer
{
ApplicationName = "LKS Captions downloader",
HttpClientInitializer = credential
});
So, is it even possible to do what I'm trying to achieve?
P.S. I was able to dig deep into the youtube nuget package and as I see, the actual message, that I get (that Newtonsoft.JSON is trying to deserialize, huh!) is "The permissions associated with the request are not sufficient to download the caption track. The request might not be properly authorized, or the video order might not have enabled third-party contributions for this caption."
So, do I have to be the video owner to download captions? But if so, how do other programs like Google2SRT work?
Found this post How to get "transcript" in youtube-api v3
You can get them via GET request on: http://video.google.com/timedtext?lang={LANG}&v={VIDEOID}
Example:
http://video.google.com/timedtext?lang=en&v=-osCkzoL53U
Note that they should have subtitles added, will not work if auto-generated.
I've some difficulty providing a login form for authentication with onedrive.
The scenario: a Windows 7 software is made to retrieve and upload some data, a user should login into onedrive (personal onedrive) to achieve this.
According to this doc (http://msdn.microsoft.com/en-US/library/dn631823.aspx)
I should write:
var authClient = new LiveAuthClient();
LiveLoginResult result = await authClient.LoginAsync("wl.signin", "wl.skydrive");
if (result.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
var connectClient = new LiveConnectClient(result.Session);
var meResult = await connectClient.GetAsync("me");
dynamic meData = meResult.Result;
updateUI(meData);
}
}
In my version (the last one) of live sdk I must optain an API key:
var _authClient = new LiveAuthClient("000xxxxxxxxxxxxxxxx"); //LiveAuthClient() simply not exist
var scopes = new string[] { "wl.signin", "wl.skydrive" }; // "wl.skydrive_update"
LiveLoginResult result = await _authClient.InitializeAsync(scopes);
if (result.Status == LiveConnectSessionStatus.Connected)
{
Debug.WriteLine("Connected");
}
The problem is that I can't find LoginAsync method and why must I obtain an API key? I'm a bit confused. Thanks.
You should see a "GetLoginUrl" method that you can use to render the login page for the user. Here's a link to a sample application that shows you how this can be accomplished:
https://github.com/liveservices/LiveSDK-for-Windows/tree/master/src/Desktop/Samples/ApiExplorer
Try reading this doc on Desktop apps: http://msdn.microsoft.com/en-us/library/dn631817.aspx
It shows a different way to provide login on desktop.
I would like to execute a query on google images to fetch images using htmlagilitypack in c#.
For this I used an xpath request to the image
//*[#id="rg_s"]/div[1]/a/img
But it fails to fetch the image that way. What could be the correct way of doing this?
you can try this too : Here its possible to get the links of images by following
var links = HtmlDocument.DocumentNode.SelectNodes("//a").Where(a => a.InnerHtml.Contains("<img")).Select(b => b.Attributes["href"].Value).ToList();
foreach(var link in links)
{
// you can save the link or do your process here
}
Google keeps found images in div tags with class rg_di. Here is a query to get all links to images:
var links = hdoc.DocumentNode.SelectNodes(#"//div[#class='rg_di']/a")
.Select(a => a.GetAttributeValue("href", ""));
Searching google programmatically outside of their API's is against the TOS. Consider Google Custom Search or Bing Search API, both of which have established JSON and SOAP interfaces.
Both are free for a couple thousand queries per month and comply with the service's TOS.
Edit: Examples of using Bing API with C# below:
const string bingKey = "[your key here]";
var bing = new BingSearchContainer(new Uri("https://api.datamarket.azure.com/Bing/Search/"))
{
Credentials = new NetworkCredential(bingKey, bingKey)
};
var query = bing.Web("Jon Gallant blog", null, null, null, null, null, null, null);
var results = query.Execute();
foreach(var result in results)
{
Console.WriteLine(result.Url);
}
Console.ReadKey();
Google custom search API:
string apiKey = "Your api key";
string cx = "Your custom search engine id";
string query = "Your query";
var svc = new Google.Apis.Customsearch.v1.CustomsearchService(new BaseClientService.Initializer { ApiKey = apiKey });
var listRequest = svc.Cse.List(query);
listRequest.Cx = cx;
var search = listRequest.Fetch();
foreach (var result in search.Items)
{
Response.Output.WriteLine("Title: {0}", result.Title);
Response.Output.WriteLine("Link: {0}", result.Link);
}
I have a question regarding using facebook graph API (OAuth) to upload photo.
I have created one company page under my account.
When I use my account to upload photo to my company page, my user name appears as a user who uploaded the page.
Is there anyway I can upload page so that company name appears?
Below is the code that I currently implemented.
string access_token = FacebookSystem.RetrieveToken(UserEmail, AppID);
string query = string.Empty;
if (string.IsNullOrEmpty(PageID) || PageID.Equals("default", StringComparison.InvariantCultureIgnoreCase))
{
query = "me/photos";
}
else
{
query = string.Format("{0}/photos", PageID);
}
var fb = new FacebookClient(access_token);
try
{
dynamic parameters = new ExpandoObject();
foreach (string i in args.FileList)
{
parameters.message = args.Comment;
parameters.source = new FacebookMediaObject
{
ContentType = "image",
FileName = Path.GetFileName(i)
}.SetValue(File.ReadAllBytes(i));
fb.Post(query, parameters);
}
}
in order to use Graph API on behalf of a Page, you need to get Page access token - see here for more details: https://developers.facebook.com/docs/facebook-login/access-tokens/#pagetokens
Authenticate the user and request the manage_pages permission
Get the list of pages the user manages from (1): https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN
Parse the list and get the token - and use it to post to the feed.
you will do (1) in graph API explorer - and you will get user token. Then insert that token into URL in (2) - and you will see all your pages and corresponding token. Take the one you need and use it in your C# code to upload images.
I have been using this library for accessing youtube. I want to list the user's history from youtube.I have googled it but couldn't find an example for this Youtube API V3.
In the code below I was able to list the feed from User's home.
public void GetRecommended(ref List<string> videoList)
{
YouTubeService youtube = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = GoogleCredentials.apiKey,
Authenticator = this.authenticator
});
// Create the request
ActivitiesResource.ListRequest listRequest = youtube.Activities.List("contentDetails");
listRequest.Home = true;
listRequest.MaxResults = 10;
// Fetch the response
ActivityListResponse listResponse = listRequest.Execute();
foreach (var item in listResponse.Items)
{
videoList.Add(item.ContentDetails.Upload.VideoId);
}
}
How can I list the user's history from Youtube?
You can do that with channels->list request.
In the response, contentDetails.relatedPlaylists will give you playlists ids for "likes", "favorites", "uploads", "watchHistory" and "watchLater".
Then you can call playlistItems->list with setting playlistId paramater to those ids to iterate through videos.