Skip to content

Instantly share code, notes, and snippets.

@embix
Created May 23, 2017 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save embix/31342b89218ecf7673fbb930f1a4d99d to your computer and use it in GitHub Desktop.
Save embix/31342b89218ecf7673fbb930f1a4d99d to your computer and use it in GitHub Desktop.
qnd youtube api v3 video duration stats
/*
<Query Kind="Program">
<Reference>&lt;RuntimeDirectory&gt;\System.Net.Http.dll</Reference>
<NuGetReference>Google.Apis.YouTube.v3</NuGetReference>
<Namespace>Google.Apis.Auth.OAuth2</Namespace>
<Namespace>Google.Apis.YouTube.v3</Namespace>
<Namespace>Google.Apis.Services</Namespace>
<Namespace>System.Threading.Tasks</Namespace>
<Namespace>Google.Apis.YouTube.v3.Data</Namespace>
</Query>
*/
void Main()
{
// todo: you need an account, see: https://console.developers.google.com/apis/dashboard
var applicationName = "yourappname";//associated with your google account
var apiKey = Util.GetPassword(applicationName);
var credentials = new BaseClientService.Initializer() { ApiKey = apiKey, ApplicationName = applicationName };
var youtubeService = new YouTubeService(credentials);
// see Terms of Service: https://console.developers.google.com/tos?id=youtube
// dont wanna get banned again...
millisecsTimeout = 100;
var to = DateTime.Now;//30 videos in 14 days?! -> we need to use NextPageToken for paging
var from = to.AddDays(-31);
var results = GatherResults(from,to, youtubeService).Result;
results.Dump();
var durations = GetDurations(results, youtubeService).Result;
durations.Dump();
Visualize(durations);
}
private Int32 millisecsTimeout=1000;
public async Task<List<SearchResult>> GatherResults(DateTime from, DateTime to, YouTubeService youtubeService)
{
var gathered = new List<SearchResult>();
var nextPageToken = (String)null;
do
{
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.ChannelId = "UCv1WDP5EiipMQ__C4Cg6aow";// Channel "Tilo Jung"
searchListRequest.PublishedAfter = from;
searchListRequest.PublishedBefore = to;
searchListRequest.Type = "video";
// MaxResults: Values must be within the range: [0, 50] :-(
// => we need to use nextpagetoken
searchListRequest.MaxResults = 50;
searchListRequest.PageToken = nextPageToken;
var searchListResponse = await searchListRequest.ExecuteAsync();
nextPageToken = searchListResponse.NextPageToken;
searchListResponse.Dump();
gathered.AddRange(searchListResponse.Items);
Thread.Sleep(millisecsTimeout);
} while (nextPageToken!=null);
return gathered;
}
public async Task<List<TimeSpan>> GetDurations(List<SearchResult> results, YouTubeService youtubeService)
{
var durations = new List<TimeSpan>();
foreach (var result in results/*.Take(2)*/)
{
var videoId = result.Id.VideoId;
var videoListRequest = youtubeService.Videos.List("contentDetails");// maybe we can get this all at once with the search query?!
videoListRequest.Id=videoId;
var videoResult = await videoListRequest.ExecuteAsync();
//videoResult.Dump();
var videoDuration = XmlConvert.ToTimeSpan(videoResult.Items.First().ContentDetails.Duration);
durations.Add(videoDuration);
Thread.Sleep(millisecsTimeout);
}
return durations;
}
public void Visualize(List<TimeSpan> durations)
{
durations.GroupBy(d => 1, (k, g) => new
{
VideoCount=g.Count(),
MinSecs=g.Min(d=>d.TotalSeconds),
MaxSecs=g.Max(d=>d.TotalSeconds),
AvgSecs=g.Average(d=>d.TotalSeconds),
// todo: median
SumSecs=g.Sum(d=>d.TotalSeconds),
}).Dump();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment