/// <summary>
 ///  Initializes a new instance of the <see cref="OneDriveThumbnailSet"/> class.
 /// </summary>
 /// <param name="set">Original set from OneDrive SDK</param>
 internal OneDriveThumbnailSet(ThumbnailSet set)
 {
     Small  = set.Small.Url;
     Medium = set.Medium.Url;
     Large  = set.Large.Url;
     Source = set.Source?.Url;
 }
Exemplo n.º 2
0
        /// <inheritdoc />
        public List <Video> SearchVideosAsync(string query, int maxPages)
        {
            query.GuardNotNull(nameof(query));
            maxPages.GuardPositive(nameof(maxPages));

            // Get all videos across pages
            var videos = new List <Video>();

            for (var i = 1; i <= maxPages; i++)
            {
                // Get search results
                var searchResultsJson = GetSearchResultsAsync(query, i);

                // Get videos
                var videosJson = searchResultsJson["video"].EmptyIfNull().ToArray();

                // Break if there are no videos
                if (!videosJson.Any())
                {
                    break;
                }

                // Parse videos
                foreach (var videoJson in videosJson)
                {
                    // Basic info
                    var videoId     = videoJson["encrypted_id"].Value <string>();
                    var videoAuthor = videoJson["author"].Value <string>();
                    //var videoUploadDate = videoJson["added"].Value<string>().ParseDateTimeOffset("M/d/yy");
                    var videoUploadDate  = videoJson["added"].Value <string>().ParseDateTimeOffset();
                    var videoTitle       = videoJson["title"].Value <string>();
                    var videoDuration    = TimeSpan.FromSeconds(videoJson["length_seconds"].Value <double>());
                    var videoDescription = videoJson["description"].Value <string>().HtmlDecode();

                    // Keywords
                    var videoKeywordsJoined = videoJson["keywords"].Value <string>();
                    var videoKeywords       = Regex
                                              .Matches(videoKeywordsJoined, @"(?<=(^|\s)(?<q>""?))([^""]|(""""))*?(?=\<q>(?=\s|$))")
                                              .Cast <Match>()
                                              .Select(m => m.Value)
                                              .Where(s => s.IsNotBlank())
                                              .ToList();

                    // Statistics
                    var videoViewCount    = videoJson["views"].Value <string>().StripNonDigit().ParseLong();
                    var videoLikeCount    = videoJson["likes"].Value <long>();
                    var videoDislikeCount = videoJson["dislikes"].Value <long>();
                    var videoStatistics   = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);

                    // Video
                    var videoThumbnails = new ThumbnailSet(videoId);
                    var video           = new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                                    videoThumbnails, videoDuration, videoKeywords, videoStatistics);

                    videos.Add(video);
                }
            }

            return(videos);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets video information by ID.
        /// </summary>
        public async Task <Video> GetVideoAsync(string videoId)
        {
            videoId.GuardNotNull(nameof(videoId));
            if (!ValidateVideoId(videoId))
            {
                throw new ArgumentException($"Invalid YouTube video ID [{videoId}].", nameof(videoId));
            }

            // Get video info
            var videoInfo = await GetVideoInfoAsync(videoId).ConfigureAwait(false);

            // Extract values
            var title     = videoInfo["title"];
            var author    = videoInfo["author"];
            var duration  = TimeSpan.FromSeconds(videoInfo["length_seconds"].ParseDouble());
            var viewCount = videoInfo["view_count"].ParseLong();
            var keywords  = videoInfo["keywords"].Split(",");

            // Get video watch page
            var watchPage = await GetVideoWatchPageAsync(videoId).ConfigureAwait(false);

            // Extract values
            var description = watchPage.QuerySelector("p#eow-description").TextEx();
            var likeCount   = watchPage.QuerySelector("button.like-button-renderer-like-button").Text()
                              .StripNonDigit().ParseLongOrDefault();
            var dislikeCount = watchPage.QuerySelector("button.like-button-renderer-dislike-button").Text()
                               .StripNonDigit().ParseLongOrDefault();
            var statistics = new Statistics(viewCount, likeCount, dislikeCount);

            var thumbnails = new ThumbnailSet(videoId);

            return(new Video(videoId, author, title, description, thumbnails, duration, keywords, statistics));
        }
Exemplo n.º 4
0
 /// <summary>
 /// Initializes an instance of <see cref="Video"/>.
 /// </summary>
 public Video(
     VideoId id,
     string title,
     string author,
     ChannelId channelId,
     DateTimeOffset uploadDate,
     string description,
     TimeSpan duration,
     ThumbnailSet thumbnails,
     IReadOnlyList <string> keywords,
     Engagement engagement,
     IReadOnlyList <Chapter>?chapters = null)
 {
     Id          = id;
     Title       = title;
     Author      = author;
     ChannelId   = channelId;
     UploadDate  = uploadDate;
     Description = description;
     Duration    = duration;
     Thumbnails  = thumbnails;
     Keywords    = keywords;
     Engagement  = engagement;
     Chapters    = chapters;
 }
Exemplo n.º 5
0
        /// <inheritdoc />
        public async Task <Video> GetVideoAsync(string videoId)
        {
            videoId.GuardNotNull(nameof(videoId));

            if (!ValidateVideoId(videoId))
            {
                throw new ArgumentException($"Invalid YouTube video ID [{videoId}].", nameof(videoId));
            }

            // Get player response parser
            var playerResponseParser = await GetPlayerResponseParserAsync(videoId);

            // Parse info
            var author   = playerResponseParser.ParseAuthor();
            var title    = playerResponseParser.ParseTitle();
            var duration = playerResponseParser.ParseDuration();
            var keywords = playerResponseParser.ParseKeywords();

            // Get video watch page parser
            var videoWatchPageParser = await GetVideoWatchPageParserAsync(videoId);

            // Parse info
            var uploadDate   = videoWatchPageParser.ParseUploadDate();
            var description  = videoWatchPageParser.ParseDescription();
            var viewCount    = videoWatchPageParser.ParseViewCount();
            var likeCount    = videoWatchPageParser.ParseLikeCount();
            var dislikeCount = videoWatchPageParser.ParseDislikeCount();

            var statistics = new Statistics(viewCount, likeCount, dislikeCount);
            var thumbnails = new ThumbnailSet(videoId);

            return(new Video(videoId, author, uploadDate, title, description, thumbnails, duration, keywords,
                             statistics));
        }
        /// <inheritdoc />
        public async Task <IReadOnlyList <Video> > SearchVideosAsync(string query, int maxPages)
        {
            query.GuardNotNull(nameof(query));
            maxPages.GuardPositive(nameof(maxPages));

            // Get all videos across pages
            var videos = new List <Video>();

            for (var page = 1; page <= maxPages; page++)
            {
                // Get search results JSON
                var resultsJson = await GetSearchResultsJsonAsync(query, page).ConfigureAwait(false);

                // Get videos
                var countDelta = 0;
                foreach (var videoJson in resultsJson.SelectToken("video").EmptyIfNull())
                {
                    var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);

                    // Extract video info
                    var videoId           = videoJson.SelectToken("encrypted_id").Value <string>();
                    var videoAuthor       = videoJson.SelectToken("author").Value <string>();
                    var videoUploadDate   = epoch + TimeSpan.FromSeconds(videoJson.SelectToken("time_created").Value <long>());
                    var videoTitle        = videoJson.SelectToken("title").Value <string>();
                    var videoDescription  = videoJson.SelectToken("description").Value <string>();
                    var videoDuration     = TimeSpan.FromSeconds(videoJson.SelectToken("length_seconds").Value <double>());
                    var videoViewCount    = videoJson.SelectToken("views").Value <string>().StripNonDigit().ParseLong();
                    var videoLikeCount    = videoJson.SelectToken("likes").Value <long>();
                    var videoDislikeCount = videoJson.SelectToken("dislikes").Value <long>();

                    // Extract video keywords
                    var videoKeywordsJoined = videoJson.SelectToken("keywords").Value <string>();
                    var videoKeywords       = Regex.Matches(videoKeywordsJoined, "\"[^\"]+\"|\\S+")
                                              .Cast <Match>()
                                              .Select(m => m.Value)
                                              .Where(s => !s.IsNullOrWhiteSpace())
                                              .Select(s => s.Trim('"'))
                                              .ToArray();

                    // Create statistics and thumbnails
                    var videoStatistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
                    var videoThumbnails = new ThumbnailSet(videoId);

                    // Add to list
                    videos.Add(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                         videoThumbnails, videoDuration, videoKeywords, videoStatistics));

                    // Increment delta
                    countDelta++;
                }

                // If no distinct videos were added to the list - break
                if (countDelta <= 0)
                {
                    break;
                }
            }

            return(videos);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Retrieve a specific size thumbnail's metadata. If it isn't already
        /// available make a call to the service to retrieve it.
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public async Task <Thumbnail> ThumbnailUrlAsync(string size = "large")
        {
            bool loadedThumbnails = this._sourceItem != null && this._sourceItem.Thumbnails != null &&
                                    this._sourceItem.Thumbnails.CurrentPage != null;

            if (loadedThumbnails)
            {
                // See if we already have that thumbnail
                Thumbnail    thumbnail    = null;
                ThumbnailSet thumbnailSet = null;

                switch (size.ToLower())
                {
                case "small":
                    thumbnailSet = this._sourceItem.Thumbnails.CurrentPage.FirstOrDefault(set => set.Small != null);
                    thumbnail    = thumbnailSet == null ? null : thumbnailSet.Small;
                    break;

                case "medium":
                    thumbnailSet = this._sourceItem.Thumbnails.CurrentPage.FirstOrDefault(set => set.Medium != null);
                    thumbnail    = thumbnailSet == null ? null : thumbnailSet.Medium;
                    break;

                case "large":
                    thumbnailSet = this._sourceItem.Thumbnails.CurrentPage.FirstOrDefault(set => set.Large != null);
                    thumbnail    = thumbnailSet == null ? null : thumbnailSet.Large;
                    break;

                default:
                    thumbnailSet = this._sourceItem.Thumbnails.CurrentPage.FirstOrDefault(set => set[size] != null);
                    thumbnail    = thumbnailSet == null ? null : thumbnailSet[size];
                    break;
                }

                if (thumbnail != null)
                {
                    return(thumbnail);
                }
            }

            if (!loadedThumbnails)
            {
                try
                {
                    // Try to load the thumbnail from the service if we haven't loaded thumbnails.
                    return(await this.oneDriveClient.Drive.Items[this._sourceItem.Id].Thumbnails["0"][size].Request().GetAsync());
                }
                catch (OneDriveException exception)
                {
                    if (exception.IsMatch(OneDriveErrorCode.ItemNotFound.ToString()))
                    {
                        // Just swallow not found. We don't want an error popup and we just won't render a thumbnail
                        return(null);
                    }
                }
            }

            return(null);
        }
Exemplo n.º 8
0
 public Stream GetValidImage(ThumbnailSet imageSet)
 {
     return(GetImageStream(imageSet.HighResUrl) ??
            GetImageStream(imageSet.StandardResUrl) ??
            GetImageStream(imageSet.MaxResUrl) ??
            GetImageStream(imageSet.MediumResUrl) ??
            GetDefaultImage());
 }
Exemplo n.º 9
0
        public void ThumbnailSetExtensions_AdditionalDataNull()
        {
            var thumbnailSet = new ThumbnailSet();

            var thumbnail = thumbnailSet["custom"];

            Assert.IsNull(thumbnail, "Unexpected thumbnail returned.");
        }
Exemplo n.º 10
0
        private Video GetVideo()
        {
            var thumbnails = new ThumbnailSet("-TEST-TEST-");
            var statistics = new Statistics(1337, 13, 37);

            return(new Video("-TEST-TEST-", "Test Author", DateTimeOffset.Now, "Test Video", "test", thumbnails,
                             TimeSpan.FromMinutes(2), new string[0], statistics));
        }
        public void ThumbnailSetExtensions_AdditionalDataNull()
        {
            var thumbnailSet = new ThumbnailSet();

            var thumbnail = thumbnailSet["custom"];

            Assert.Null(thumbnail);
        }
Exemplo n.º 12
0
        /// <inheritdoc />
        public async Task <Video> GetVideoAsync(string videoId)
        {
            videoId.GuardNotNull(nameof(videoId));

            if (!ValidateVideoId(videoId))
            {
                throw new ArgumentException($"Invalid YouTube video ID [{videoId}].", nameof(videoId));
            }

            // Get video info dictionary
            var videoInfoDic = await GetVideoInfoDicAsync(videoId).ConfigureAwait(false);

            // Get player response JSON
            var playerResponseJson = JToken.Parse(videoInfoDic["player_response"]);

            // If video is unavailable - throw
            if (string.Equals(playerResponseJson.SelectToken("playabilityStatus.status")?.Value <string>(), "error",
                              StringComparison.OrdinalIgnoreCase))
            {
                throw new VideoUnavailableException(videoId, $"Video [{videoId}] is unavailable.");
            }

            // Extract video info
            var videoAuthor      = playerResponseJson.SelectToken("videoDetails.author").Value <string>();
            var videoTitle       = playerResponseJson.SelectToken("videoDetails.title").Value <string>();
            var videoDuration    = TimeSpan.FromSeconds(playerResponseJson.SelectToken("videoDetails.lengthSeconds").Value <double>());
            var videoKeywords    = playerResponseJson.SelectToken("videoDetails.keywords").EmptyIfNull().Values <string>().ToArray();
            var videoDescription = playerResponseJson.SelectToken("videoDetails.shortDescription").Value <string>();
            var videoViewCount   = playerResponseJson.SelectToken("videoDetails.viewCount")?.Value <long>() ?? 0; // some videos have no views
            var videoLoudness    = playerResponseJson.SelectToken("playerConfig.audioConfig.loudnessDb").Value <double>();

            // Get video watch page HTML
            var videoWatchPageHtml = await GetVideoWatchPageHtmlAsync(videoId).ConfigureAwait(false);

            // Extract upload date
            var videoUploadDate = videoWatchPageHtml.GetElementsBySelector("meta[itemprop=\"datePublished\"]")
                                  .First().GetAttribute("content").Value.ParseDateTimeOffset("yyyy-MM-dd");

            // Extract like count
            var videoLikeCountRaw = videoWatchPageHtml.GetElementsByClassName("like-button-renderer-like-button")
                                    .FirstOrDefault()?.GetInnerText().StripNonDigit();

            var videoLikeCount = !videoLikeCountRaw.IsNullOrWhiteSpace() ? videoLikeCountRaw.ParseLong() : 0;

            // Extract dislike count
            var videoDislikeCountRaw = videoWatchPageHtml.GetElementsByClassName("like-button-renderer-dislike-button")
                                       .FirstOrDefault()?.GetInnerText().StripNonDigit();

            var videoDislikeCount = !videoDislikeCountRaw.IsNullOrWhiteSpace() ? videoDislikeCountRaw.ParseLong() : 0;

            // Create statistics and thumbnails
            var statistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
            var thumbnails = new ThumbnailSet(videoId);

            return(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription, thumbnails, videoDuration, videoKeywords,
                             statistics, videoLoudness));
        }
Exemplo n.º 13
0
 private VideoInformation(VideoId id, string title, string author, DateTimeOffset?uploadDate, TimeSpan duration,
                          ThumbnailSet thumbnails)
 {
     Id         = id;
     Title      = title;
     Author     = author;
     UploadDate = uploadDate;
     Duration   = duration;
     Thumbnails = thumbnails;
 }
Exemplo n.º 14
0
        public override async Task <byte[]> GetItemThumbnail(string itemId, string relativePath)
        {
            ThumbnailSet thumbnailSet = await this.oneDriveClient.GetThumbnailsAsync(itemId).ConfigureAwait(false);

            ThumbnailInfo thumbnail;

            if (!thumbnailSet.Thumbnails.TryGetValue("medium", out thumbnail))
            {
                return(null);
            }

            return(await this.oneDriveClient.GetRawBytesFromOneDrive(thumbnail.Url).ConfigureAwait(false));
        }
Exemplo n.º 15
0
 /// <summary>
 ///     Initializes an instance of <see cref="Video" />.
 /// </summary>
 public Video(
     string id,
     string title,
     string author,
     DateTimeOffset uploadDate,
     ThumbnailSet thumbnails)
 {
     Id         = id;
     Title      = title;
     Author     = author;
     UploadDate = uploadDate;
     Thumbnails = thumbnails;
 }
Exemplo n.º 16
0
        private async void SetMetaData(int position, string title, string artist, ThumbnailSet thumbnails)
        {
            string filePath = queue[position].Path;

            await Task.Run(async() =>
            {
                Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
                var meta      = TagLib.File.Create(new StreamFileAbstraction(filePath, stream, stream));

                meta.Tag.Title      = title;
                meta.Tag.Performers = new string[] { artist };
                meta.Tag.Album      = title + " - " + artist;
                meta.Tag.Comment    = queue[position].YoutubeID;
                IPicture[] pictures = new IPicture[1];
                Bitmap bitmap       = Picasso.With(this).Load(await YoutubeManager.GetBestThumb(thumbnails)).Transform(new RemoveBlackBorder(true)).MemoryPolicy(MemoryPolicy.NoCache).Get();
                byte[] data;
                using (var MemoryStream = new MemoryStream())
                {
                    bitmap.Compress(Bitmap.CompressFormat.Png, 0, MemoryStream);
                    data = MemoryStream.ToArray();
                }
                bitmap.Recycle();
                pictures[0]       = new Picture(data);
                meta.Tag.Pictures = pictures;

                meta.Save();
                stream.Dispose();
            });

            MediaScannerConnection.ScanFile(this, new string[] { filePath }, null, this);

            if (queue[position].PlaylistName == null)
            {
                queue[position].State = DownloadState.Completed;
            }
            else
            {
                queue[position].State = DownloadState.Playlist;
            }

            if (!queue.Exists(x => x.State == DownloadState.None || x.State == DownloadState.Downloading || x.State == DownloadState.Initialization || x.State == DownloadState.MetaData || x.State == DownloadState.Playlist))
            {
                StopForeground(true);
                DownloadQueue.instance?.Finish();
                queue.Clear();
            }
            else
            {
                UpdateList(position);
            }
        }
Exemplo n.º 17
0
        /// <inheritdoc />
        public async Task <IReadOnlyList <Video> > SearchVideosAsync(string query, int maxPages)
        {
            query.GuardNotNull(nameof(query));
            maxPages.GuardPositive(nameof(maxPages));

            // Get all videos across pages
            var videos = new List <Video>();

            for (var page = 1; page <= maxPages; page++)
            {
                // Get parser
                var parser = await GetPlaylistAjaxParserForSearchAsync(query, page);

                // Parse videos
                var countDelta = 0;
                foreach (var videoParser in parser.GetVideos())
                {
                    // Parse info
                    var videoId           = videoParser.ParseId();
                    var videoAuthor       = videoParser.ParseAuthor();
                    var videoUploadDate   = videoParser.ParseUploadDate();
                    var videoTitle        = videoParser.ParseTitle();
                    var videoDescription  = videoParser.ParseDescription();
                    var videoDuration     = videoParser.ParseDuration();
                    var videoKeywords     = videoParser.ParseKeywords();
                    var videoViewCount    = videoParser.ParseViewCount();
                    var videoLikeCount    = videoParser.ParseLikeCount();
                    var videoDislikeCount = videoParser.ParseDislikeCount();

                    var videoStatistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
                    var videoThumbnails = new ThumbnailSet(videoId);

                    var video = new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                          videoThumbnails, videoDuration, videoKeywords, videoStatistics);

                    videos.Add(video);
                    countDelta++;
                }

                // Break if no distinct videos were added to the list
                if (countDelta <= 0)
                {
                    break;
                }
            }

            return(videos);
        }
 /// <summary>
 /// Update the navigation property thumbnails in workbooks
 /// <param name="body"></param>
 /// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
 /// </summary>
 public RequestInformation CreatePatchRequestInformation(ThumbnailSet body, Action<ThumbnailSetItemRequestBuilderPatchRequestConfiguration> requestConfiguration = default) {
     _ = body ?? throw new ArgumentNullException(nameof(body));
     var requestInfo = new RequestInformation {
         HttpMethod = Method.PATCH,
         UrlTemplate = UrlTemplate,
         PathParameters = PathParameters,
     };
     requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body);
     if (requestConfiguration != null) {
         var requestConfig = new ThumbnailSetItemRequestBuilderPatchRequestConfiguration();
         requestConfiguration.Invoke(requestConfig);
         requestInfo.AddRequestOptions(requestConfig.Options);
         requestInfo.AddHeaders(requestConfig.Headers);
     }
     return requestInfo;
 }
Exemplo n.º 19
0
        /// <inheritdoc />
        public async Task <Video> GetVideoAsync(string videoId)
        {
            videoId.GuardNotNull(nameof(videoId));

            if (!ValidateVideoId(videoId))
            {
                throw new ArgumentException($"Invalid YouTube video ID [{videoId}].", nameof(videoId));
            }

            // Get video info dictionary
            var videoInfoDic = await GetVideoInfoDicAsync(videoId);

            // Get player response JSON
            var playerResponseJson = JToken.Parse(videoInfoDic["player_response"]);

            // Extract video info
            var videoAuthor      = playerResponseJson.SelectToken("videoDetails.author").Value <string>();
            var videoTitle       = playerResponseJson.SelectToken("videoDetails.title").Value <string>();
            var videoDuration    = TimeSpan.FromSeconds(playerResponseJson.SelectToken("videoDetails.lengthSeconds").Value <double>());
            var videoKeywords    = playerResponseJson.SelectToken("videoDetails.keywords").EmptyIfNull().Values <string>().ToArray();
            var videoDescription = playerResponseJson.SelectToken("videoDetails.shortDescription").Value <string>();
            var videoViewCount   = playerResponseJson.SelectToken("videoDetails.viewCount")?.Value <long>() ?? 0; // some videos have no views

            // Get video watch page HTML
            var videoWatchPageHtml = await GetVideoWatchPageHtmlAsync(videoId);

            // Extract upload date
            var videoUploadDate = videoWatchPageHtml.QuerySelector("meta[itemprop=\"datePublished\"]").GetAttribute("content")
                                  .ParseDateTimeOffset("yyyy-MM-dd");

            // Extract like count
            var videoLikeCountRaw =
                videoWatchPageHtml.QuerySelector("button.like-button-renderer-like-button")?.Text().StripNonDigit();
            var videoLikeCount = !videoLikeCountRaw.IsNullOrWhiteSpace() ? videoLikeCountRaw.ParseLong() : 0;

            // Extract dislike count
            var videoDislikeCountRaw =
                videoWatchPageHtml.QuerySelector("button.like-button-renderer-dislike-button")?.Text().StripNonDigit();
            var videoDislikeCount = !videoDislikeCountRaw.IsNullOrWhiteSpace() ? videoDislikeCountRaw.ParseLong() : 0;

            // Create statistics and thumbnails
            var statistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
            var thumbnails = new ThumbnailSet(videoId);

            return(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                             thumbnails, videoDuration, videoKeywords, statistics));
        }
Exemplo n.º 20
0
        public void ThumbnailSetExtensions_CustomThumbnailNotFound()
        {
            var expectedThumbnail = new Thumbnail {
                Url = "https://localhost"
            };
            var thumbnailSet = new ThumbnailSet
            {
                AdditionalData = new Dictionary <string, object>
                {
                    { "custom", expectedThumbnail }
                }
            };

            var thumbnail = thumbnailSet["custom2"];

            Assert.IsNull(thumbnail, "Unexpected thumbnail returned.");
        }
        public void ThumbnailSetExtensions_CustomThumbnail()
        {
            var expectedThumbnail = new Thumbnail {
                Url = "https://localhost"
            };
            var thumbnailSet = new ThumbnailSet
            {
                AdditionalData = new Dictionary <string, object>
                {
                    { "custom", expectedThumbnail }
                }
            };

            var thumbnail = thumbnailSet["custom"];

            Assert.NotNull(thumbnail);
            Assert.Equal(expectedThumbnail.Url, thumbnail.Url);
        }
Exemplo n.º 22
0
 /// <summary>
 /// Initializes an instance of <see cref="Video"/>.
 /// </summary>
 public PlaylistVideo(
     VideoId id,
     string title,
     string author,
     ChannelId channelId,
     string description,
     TimeSpan duration,
     long viewCount,
     ThumbnailSet thumbnails)
 {
     Id          = id;
     Title       = title;
     Author      = author;
     ChannelId   = channelId;
     Description = description;
     Duration    = duration;
     ViewCount   = viewCount;
     Thumbnails  = thumbnails;
 }
Exemplo n.º 23
0
 /// <summary>
 /// Initializes an instance of <see cref="Video"/>.
 /// </summary>
 public Video(
     VideoId id,
     string title,
     string author,
     DateTimeOffset uploadDate,
     string description,
     TimeSpan duration,
     ThumbnailSet thumbnails,
     IReadOnlyList <string> keywords,
     Engagement engagement)
 {
     Id          = id;
     Title       = title;
     Author      = author;
     UploadDate  = uploadDate;
     Description = description;
     Duration    = duration;
     Thumbnails  = thumbnails;
     Keywords    = keywords;
     Engagement  = engagement;
 }
Exemplo n.º 24
0
        /// <summary>
        /// Return the thumbnail with the greatest quality.
        /// </summary>
        /// <param name="thumbnails">This will create an array of the thumbnails in this order: MaxResUrl, StandardResUrl, HighResUrl</param>
        /// <returns></returns>
        public async static Task <string> GetBestThumb(ThumbnailSet Thumbnails)
        {
            string[] thumbnails = new string[] { Thumbnails.MaxResUrl, Thumbnails.StandardResUrl, Thumbnails.HighResUrl };
            foreach (string thumb in thumbnails)
            {
                HttpWebRequest request = new HttpWebRequest(new Uri(thumb))
                {
                    Method = "HEAD"
                };
                try
                {
                    HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();

                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        return(thumb);
                    }
                }
                catch (WebException) { }
            }

            return(thumbnails.Last());
        }
Exemplo n.º 25
0
        /// <inheritdoc />
        public Video GetVideoAsync(string videoId)
        {
            videoId.GuardNotNull(nameof(videoId));

            if (!ValidateVideoId(videoId))
            {
                throw new ArgumentException($"Invalid YouTube video ID [{videoId}].", nameof(videoId));
            }

            // Get video info
            var videoInfo = GetVideoInfoAsync(videoId); // .ConfigureAwait(false);

            // Extract values
            var title     = videoInfo["title"];
            var author    = videoInfo["author"];
            var duration  = TimeSpan.FromSeconds(videoInfo["length_seconds"].ParseDouble());
            var viewCount = videoInfo["view_count"].ParseLong();
            var keywords  = videoInfo["keywords"].Split(",").ToList();

            // Get video watch page
            var watchPage = GetVideoWatchPageAsync(videoId); //.ConfigureAwait(false);

            // Extract values
            var uploadDate = watchPage.QuerySelector("meta[itemprop=\"datePublished\"]").GetAttributeValue("content", string.Empty)
                             .ParseDateTimeOffset("yyyy-MM-dd");
            var description = watchPage.QuerySelector("p#eow-description").TextEx();
            var likeCount   = watchPage.QuerySelector("button.like-button-renderer-like-button").InnerText
                              .StripNonDigit().ParseLongOrDefault();
            var dislikeCount = watchPage.QuerySelector("button.like-button-renderer-dislike-button").InnerText
                               .StripNonDigit().ParseLongOrDefault();
            var statistics = new Statistics(viewCount, likeCount, dislikeCount);

            var thumbnails = new ThumbnailSet(videoId);

            return(new Video(videoId, author, uploadDate, title, description, thumbnails, duration, keywords,
                             statistics));
        }
        /// <inheritdoc />
        public async Task <Playlist> GetPlaylistAsync(string playlistId, int maxPages)
        {
            if (!ValidatePlaylistId(playlistId))
            {
                throw new ArgumentException($"Invalid YouTube playlist ID [{playlistId}].", nameof(playlistId));
            }

            // Get all videos across pages
            JToken playlistJson;
            var    page     = 1;
            var    index    = 0;
            var    videoIds = new HashSet <string>();
            var    videos   = new List <Video>();

            do
            {
                // Get playlist JSON
                playlistJson = await GetPlaylistJsonAsync(playlistId, index).ConfigureAwait(false);

                // Get videos
                var countDelta = 0;
                foreach (var videoJson in playlistJson.SelectTokens("video[*]"))
                {
                    var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);

                    // Extract video info
                    var videoId           = videoJson.SelectToken("encrypted_id").Value <string>();
                    var videoAuthor       = videoJson.SelectToken("author").Value <string>();
                    var videoUploadDate   = epoch + TimeSpan.FromSeconds(videoJson.SelectToken("time_created").Value <long>());
                    var videoTitle        = videoJson.SelectToken("title").Value <string>();
                    var videoDescription  = videoJson.SelectToken("description").Value <string>();
                    var videoDuration     = TimeSpan.FromSeconds(videoJson.SelectToken("length_seconds").Value <double>());
                    var videoViewCount    = videoJson.SelectToken("views").Value <string>().StripNonDigit().ParseLong();
                    var videoLikeCount    = videoJson.SelectToken("likes").Value <long>();
                    var videoDislikeCount = videoJson.SelectToken("dislikes").Value <long>();

                    // Extract video keywords
                    var videoKeywordsJoined = videoJson.SelectToken("keywords").Value <string>();
                    var videoKeywords       = Regex.Matches(videoKeywordsJoined, "\"[^\"]+\"|\\S+")
                                              .Cast <Match>()
                                              .Select(m => m.Value)
                                              .Where(s => !string.IsNullOrWhiteSpace(s))
                                              .Select(s => s.Trim('"'))
                                              .ToArray();

                    // Create statistics and thumbnails
                    var videoStatistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
                    var videoThumbnails = new ThumbnailSet(videoId);

                    // Add video to the list if it's not already there
                    if (videoIds.Add(videoId))
                    {
                        videos.Add(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                             videoThumbnails, videoDuration, videoKeywords, videoStatistics));

                        // Increment delta
                        countDelta++;
                    }
                }

                // If no distinct videos were added to the list - break
                if (countDelta <= 0)
                {
                    break;
                }

                // Advance index and page
                index += countDelta;
                page++;
            } while (page <= maxPages);

            // Extract playlist info
            var author       = playlistJson.SelectToken("author")?.Value <string>() ?? ""; // system playlists have no author
            var title        = playlistJson.SelectToken("title").Value <string>();
            var description  = playlistJson.SelectToken("description")?.Value <string>() ?? "";
            var viewCount    = playlistJson.SelectToken("views")?.Value <long>() ?? 0;    // system playlists have no views
            var likeCount    = playlistJson.SelectToken("likes")?.Value <long>() ?? 0;    // system playlists have no likes
            var dislikeCount = playlistJson.SelectToken("dislikes")?.Value <long>() ?? 0; // system playlists have no dislikes

            // Create statistics
            var statistics = new Statistics(viewCount, likeCount, dislikeCount);

            return(new Playlist(playlistId, author, title, description, statistics, videos));
        }
        /// <inheritdoc />
        public async Task <Playlist> GetPlaylistAsync(string playlistId, int maxPages)
        {
            playlistId.GuardNotNull(nameof(playlistId));
            maxPages.GuardPositive(nameof(maxPages));

            if (!ValidatePlaylistId(playlistId))
            {
                throw new ArgumentException($"Invalid YouTube playlist ID [{playlistId}].", nameof(playlistId));
            }

            // Get all videos across pages
            JToken playlistJson;
            var    page     = 1;
            var    index    = 0;
            var    videoIds = new HashSet <string>();
            var    videos   = new List <Video>();

            do
            {
                // Get playlist JSON
                playlistJson = await GetPlaylistJsonAsync(playlistId, index);

                // Get videos
                var countTotal = 0;
                var countDelta = 0;
                foreach (var videoJson in playlistJson.SelectToken("video").EmptyIfNull())
                {
                    // Extract video info
                    var videoId           = videoJson.SelectToken("encrypted_id").Value <string>();
                    var videoAuthor       = videoJson.SelectToken("author").Value <string>();
                    var videoUploadDate   = videoJson.SelectToken("added").Value <string>().ParseDateTimeOffset("M/d/yy");
                    var videoTitle        = videoJson.SelectToken("title").Value <string>();
                    var videoDescription  = videoJson.SelectToken("description").Value <string>();
                    var videoDuration     = TimeSpan.FromSeconds(videoJson.SelectToken("length_seconds").Value <double>());
                    var videoViewCount    = videoJson.SelectToken("views").Value <string>().StripNonDigit().ParseLong();
                    var videoLikeCount    = videoJson.SelectToken("likes").Value <long>();
                    var videoDislikeCount = videoJson.SelectToken("dislikes").Value <long>();

                    // Extract video keywords
                    var videoKeywordsJoined = videoJson.SelectToken("keywords").Value <string>();
                    var videoKeywords       = Regex.Matches(videoKeywordsJoined, @"(?<=(^|\s)(?<q>""?))([^""]|(""""))*?(?=\<q>(?=\s|$))")
                                              .Cast <Match>()
                                              .Select(m => m.Value)
                                              .Where(s => !s.IsNullOrWhiteSpace())
                                              .ToArray();

                    // Create statistics and thumbnails
                    var videoStatistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
                    var videoThumbnails = new ThumbnailSet(videoId);

                    // Add video to the list if it's not already there
                    if (videoIds.Add(videoId))
                    {
                        videos.Add(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                             videoThumbnails, videoDuration, videoKeywords, videoStatistics));

                        // Increment delta
                        countDelta++;
                    }

                    // Increment total count
                    countTotal++;
                }

                // If no distinct videos were added to the list - break
                if (countDelta <= 0)
                {
                    break;
                }

                // Advance index and page
                index += countTotal;
                page++;
            } while (page <= maxPages);

            // Extract playlist info
            var author       = playlistJson.SelectToken("author")?.Value <string>() ?? ""; // system playlists have no author
            var title        = playlistJson.SelectToken("title").Value <string>();
            var description  = playlistJson.SelectToken("description")?.Value <string>() ?? "";
            var viewCount    = playlistJson.SelectToken("views")?.Value <long>() ?? 0;    // system playlists have no views
            var likeCount    = playlistJson.SelectToken("likes")?.Value <long>() ?? 0;    // system playlists have no likes
            var dislikeCount = playlistJson.SelectToken("dislikes")?.Value <long>() ?? 0; // system playlists have no dislikes

            // Create statistics
            var statistics = new Statistics(viewCount, likeCount, dislikeCount);

            return(new Playlist(playlistId, author, title, description, statistics, videos));
        }
Exemplo n.º 28
0
        /// <inheritdoc />
        public async Task <IReadOnlyList <Video> > SearchVideosByFilterAsync(string query, int maxPages = 1, int pageSize = 20, SearchFilterType searchType = SearchFilterType.Default)
        {
            var videos = new List <Video>();

            for (var page = 1; page <= maxPages; page++)
            {
                var counter = 0;
                var doc     = await GetYoutubeHtmlResultAsync(query, page, searchType);

                var children = doc.GetElementsByClassName("item-section").FirstOrDefault()?.Children;
                if (children != null)
                {
                    foreach (HtmlElement videoItem in children)
                    {
                        var videoType = VideoType.Video;
                        if (videoItem.GetElementsByClassName("yt-lockup-playlist").Any())
                        {
                            videoType = VideoType.Playlist;
                        }
                        else if (videoItem.GetElementsByClassName("yt-lockup-channel").Any())
                        {
                            videoType = VideoType.Channel;
                        }
                        string         videoId;
                        string         thumbVideoId;
                        string         videoAuthor;
                        DateTimeOffset?videoUploadDate = null;  // Need help converting 1 year ago, 1 day ago etc. the problem is with the language. it could be diffrent
                        string         videoTitle;
                        string         videoDescription;
                        TimeSpan       videoDuration;
                        long           videoViewCount;
                        long           videoLikeCount    = 0;             // cant find this
                        long           videoDislikeCount = 0;             // cant find this
                        string[]       videoKeywords     = new string[0]; // are not available
                        int?           totalVideos;

                        ThumbnailSet videoThumbnails;
                        Statistics   videoStatistics;
                        if (videoType == VideoType.Channel)
                        {
                            videoId = videoItem.Find("[data-channel-external-id]").FirstOrDefault()?.GetAttribute("data-channel-external-id")?.Value;
                            if (string.IsNullOrEmpty(videoId))
                            {
                                videoId = videoItem.Find("a [href]").FirstOrDefault()?.GetAttribute("href")?.Value;
                            }
                            thumbVideoId = videoItem.Find(".video-thumb span img").FirstOrDefault()?.GetAttribute("src")?.Value;
                        }
                        else if (string.IsNullOrWhiteSpace(videoId = thumbVideoId = videoItem.Find("[data-context-item-id]").FirstOrDefault()?.GetAttribute("data-context-item-id").Value))
                        {
                            var idEl = videoItem.Find(".yt-lockup-thumbnail a [href]").FirstOrDefault();
                            if (idEl == null)
                            {
                                continue; // not valid div
                            }
                            var id = "youtube.com" + idEl?.GetAttribute("href").Value;
                            if (videoType != VideoType.Video)
                            {
                                videoId      = YoutubeClient.ParsePlaylistId(id);
                                thumbVideoId = YoutubeClient.ParseVideoId(id);
                            }
                            else
                            {
                                videoId = thumbVideoId = YoutubeClient.ParseVideoId(id);
                            }
                        }
                        if (string.IsNullOrWhiteSpace(videoTitle = videoItem.Find(".yt-lockup-title a span").FirstOrDefault()?.GetInnerText()))
                        {
                            videoTitle = videoItem.Find(".yt-lockup-title a").FirstOrDefault()?.GetInnerText();
                        }

                        if (videoTitle.IsDeletedVideo())
                        {
                            continue;
                        }

                        videoThumbnails  = new ThumbnailSet(thumbVideoId, videoType);
                        videoAuthor      = (videoItem.Find(".yt-lockup-byline a").FirstOrDefault()?.GetInnerText() ?? videoTitle).Split("-").FirstOrDefault();
                        videoDescription = videoItem.Find(".yt-lockup-description").FirstOrDefault()?.GetInnerText() ?? string.Empty;
                        videoDuration    = videoItem.Find(".video-time").FirstOrDefault()?.GetInnerText().ParseTime() ?? TimeSpan.FromSeconds(0);
                        videoViewCount   = videoItem.Find(".yt-lockup-meta-info li").LastOrDefault()?.GetInnerText()?.StripNonDigit().ParseLongOrDefault() ?? 0;
                        totalVideos      = videoItem.Find(".formatted-video-count-label").FirstOrDefault()?.GetInnerText().StripNonDigit().ParseIntOrDefault();
                        videoStatistics  = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);
                        videos.Add(new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription, videoThumbnails, videoDuration, videoKeywords, videoStatistics, totalVideos, videoType));

                        if (counter >= pageSize)
                        {
                            break;
                        }
                        counter++;
                    }
                }
            }
            return(videos);
        }
Exemplo n.º 29
0
        /// <inheritdoc />
        public async Task <Playlist> GetPlaylistAsync(string playlistId, int maxPages)
        {
            playlistId.GuardNotNull(nameof(playlistId));
            maxPages.GuardPositive(nameof(maxPages));

            if (!ValidatePlaylistId(playlistId))
            {
                throw new ArgumentException($"Invalid YouTube playlist ID [{playlistId}].", nameof(playlistId));
            }

            // Get all videos across pages
            var    pagesDone = 0;
            var    offset    = 0;
            JToken playlistJson;
            var    videoIds = new HashSet <string>();
            var    videos   = new List <Video>();

            do
            {
                // Get playlist info
                playlistJson = await GetPlaylistInfoAsync(playlistId, offset).ConfigureAwait(false);

                // Parse videos
                var total = 0;
                var delta = 0;
                foreach (var videoJson in playlistJson["video"])
                {
                    // Basic info
                    var videoId          = videoJson["encrypted_id"].Value <string>();
                    var videoAuthor      = videoJson["author"].Value <string>();
                    var videoUploadDate  = videoJson["added"].Value <DateTime>();
                    var videoTitle       = videoJson["title"].Value <string>();
                    var videoDuration    = TimeSpan.FromSeconds(videoJson["length_seconds"].Value <double>());
                    var videoDescription = videoJson["description"].Value <string>();

                    // Keywords
                    var videoKeywordsJoined = videoJson["keywords"].Value <string>();
                    var videoKeywords       = Regex
                                              .Matches(videoKeywordsJoined, @"(?<=(^|\s)(?<q>""?))([^""]|(""""))*?(?=\<q>(?=\s|$))")
                                              .Cast <Match>()
                                              .Select(m => m.Value)
                                              .Where(s => s.IsNotBlank())
                                              .ToArray();

                    // Statistics
                    var videoViewCount    = videoJson["views"].Value <string>().StripNonDigit().ParseLong();
                    var videoLikeCount    = videoJson["likes"].Value <long>();
                    var videoDislikeCount = videoJson["dislikes"].Value <long>();
                    var videoStatistics   = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount);

                    // Video
                    var videoThumbnails = new ThumbnailSet(videoId);
                    var video           = new Video(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription,
                                                    videoThumbnails, videoDuration, videoKeywords, videoStatistics);

                    // Add to list if not already there
                    if (videoIds.Add(video.Id))
                    {
                        videos.Add(video);
                        delta++;
                    }
                    total++;
                }

                // Break if no distinct videos were added to the list
                if (delta <= 0)
                {
                    break;
                }

                // Prepare for next page
                pagesDone++;
                offset += total;
            } while (pagesDone < maxPages);

            // Extract playlist info
            var title       = playlistJson["title"].Value <string>();
            var author      = playlistJson["author"]?.Value <string>() ?? "";      // system playlists don't have an author
            var description = playlistJson["description"]?.Value <string>() ?? ""; // system playlists don't have description

            // Statistics
            var viewCount    = playlistJson["views"]?.Value <long>() ?? 0;    // watchlater does not have views
            var likeCount    = playlistJson["likes"]?.Value <long>() ?? 0;    // system playlists don't have likes
            var dislikeCount = playlistJson["dislikes"]?.Value <long>() ?? 0; // system playlists don't have dislikes
            var statistics   = new Statistics(viewCount, likeCount, dislikeCount);

            return(new Playlist(playlistId, author, title, description, statistics, videos));
        }
Exemplo n.º 30
0
        private async void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _cancelGetDetails.Cancel(false);
            _cancelGetDetails.Dispose();
            _cancelGetDetails = new CancellationTokenSource();
            if (_list.SelectedItem is DriveItem driveItem && driveItem.File != null)
            {
                try
                {
                    SelectedFile = driveItem;
                    FileSize     = driveItem.Size ?? 0;
                    LastModified = driveItem.LastModifiedDateTime?.LocalDateTime.ToString() ?? string.Empty;
                    if (FileSelected != null)
                    {
                        FileSelected.Invoke(this, new FileSelectedEventArgs(driveItem));
                    }

                    ThumbnailImageSource = null;
                    VisualStateManager.GoToState(this, NavStatesFileReadonly, false);
                    GraphServiceClient graphClient = await GraphServiceHelper.GetGraphServiceClientAsync();

                    if (graphClient != null)
                    {
                        Task <IDriveItemPermissionsCollectionPage> taskPermissions = graphClient.Drives[_driveId].Items[driveItem.Id].Permissions.Request().GetAsync(_cancelGetDetails.Token);
                        IDriveItemPermissionsCollectionPage        permissions     = await taskPermissions;
                        if (!taskPermissions.IsCanceled)
                        {
                            foreach (Permission permission in permissions)
                            {
                                if (permission.Roles.Contains("write") || permission.Roles.Contains("owner"))
                                {
                                    VisualStateManager.GoToState(this, NavStatesFileEdit, false);
                                    break;
                                }
                            }

                            Task <IDriveItemThumbnailsCollectionPage> taskThumbnails = graphClient.Drives[_driveId].Items[driveItem.Id].Thumbnails.Request().GetAsync(_cancelGetDetails.Token);
                            IDriveItemThumbnailsCollectionPage        thumbnails     = await taskThumbnails;
                            if (!taskThumbnails.IsCanceled)
                            {
                                ThumbnailSet thumbnailsSet = thumbnails.FirstOrDefault();
                                if (thumbnailsSet != null)
                                {
                                    Thumbnail thumbnail = thumbnailsSet.Large;
                                    if (thumbnail.Url.Contains("inputFormat=svg"))
                                    {
                                        SvgImageSource source = new SvgImageSource();
                                        using (Stream inputStream = await graphClient.Drives[_driveId].Items[driveItem.Id].Content.Request().GetAsync())
                                        {
                                            SvgImageSourceLoadStatus status = await source.SetSourceAsync(inputStream.AsRandomAccessStream());

                                            if (status == SvgImageSourceLoadStatus.Success)
                                            {
                                                ThumbnailImageSource = source;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        ThumbnailImageSource = new BitmapImage(new Uri(thumbnail.Url));
                                    }
                                }
                            }

                            IsDetailPaneVisible = true;
                            ShowDetailsPane();
                        }
                    }
                }
                catch (Exception exception)
                {
                    MessageDialog messageDialog = new MessageDialog(exception.Message);
                    await messageDialog.ShowAsync();
                }
            }