Ejemplo n.º 1
0
        /// <summary>
        /// Gets the play list songs internal asynchronous.
        /// </summary>
        /// <param name="userEmail">The user email.</param>
        /// <param name="playListId">The play list identifier.</param>
        private async Task GetPlayListSongsInternalAsync(string userEmail, string playListId, List <string> playListSongs)
        {
            var youtubeService = await GetYouTubeService(userEmail);

            var channelsListRequest = youtubeService.Channels.List("contentDetails");

            channelsListRequest.Mine = true;
            var nextPageToken = "";

            while (nextPageToken != null)
            {
                PlaylistItemsResource.ListRequest listRequest = youtubeService.PlaylistItems.List("contentDetails");
                listRequest.MaxResults = 50;
                listRequest.PlaylistId = playListId;
                listRequest.PageToken  = nextPageToken;
                var response = await listRequest.ExecuteAsync();

                if (playListSongs == null)
                {
                    playListSongs = new List <string>();
                }
                foreach (var playlistItem in response.Items)
                {
                    VideosResource.ListRequest videoR = youtubeService.Videos.List("snippet");
                    videoR.Id = playlistItem.ContentDetails.VideoId;
                    var responseV = await videoR.ExecuteAsync();

                    playListSongs.Add(responseV.Items[0].Snippet.Title);
                }
                nextPageToken = response.NextPageToken;
            }
        }
Ejemplo n.º 2
0
        private async Task Run()
        {
            UserCredential credential;
            string         clientSecretsPath = CredentialsManager.GetClientSecretsLocation();

            using (FileStream stream = new FileStream(clientSecretsPath, FileMode.Open, FileAccess.Read))
            {
                // This OAuth 2.0 access scope allows for read-only access to the authenticated
                // user's account, but not other types of account access.
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { YouTubeService.Scope.YoutubeReadonly },
                    "user",
                    CancellationToken.None,
                    new FileDataStore(GetType().ToString())
                    );
            }

            BaseClientService.Initializer baseClientServiceInitializer = new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName       = GetType().ToString()
            };
            YouTubeService youtubeService = new YouTubeService(baseClientServiceInitializer);

            ChannelsResource.ListRequest channelsListRequest = youtubeService.Channels.List("contentDetails");
            channelsListRequest.Mine = true;

            // Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
            ChannelListResponse channelsListResponse = await channelsListRequest.ExecuteAsync();

            foreach (Channel channel in channelsListResponse.Items)
            {
                // From the API response, extract the playlist ID that identifies the list
                // of videos uploaded to the authenticated user's channel.
                string uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;

                Console.WriteLine("Videos in list {0}", uploadsListId);

                string nextPageToken = "";
                while (nextPageToken != null)
                {
                    PlaylistItemsResource.ListRequest 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.
                    PlaylistItemListResponse playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();

                    foreach (PlaylistItem playlistItem in playlistItemsListResponse.Items)
                    {
                        // Print information about each video.
                        Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId);
                    }

                    nextPageToken = playlistItemsListResponse.NextPageToken;
                }
            }
        }
        /// <summary>
        /// Gets the play list songs internal asynchronous.
        /// </summary>
        /// <param name="userEmail">The user email.</param>
        /// <param name="playListId">The play list identifier.</param>
        private async Task GetPlayListSongsInternalAsync(string userEmail, string playListId, List <IYouTubeSong> playListSongs)
        {
            var youtubeService = await this.GetYouTubeService(userEmail);

            var channelsListRequest = youtubeService.Channels.List("contentDetails");

            channelsListRequest.Mine = true;
            var nextPageToken = "";

            while (nextPageToken != null)
            {
                PlaylistItemsResource.ListRequest listRequest = youtubeService.PlaylistItems.List("contentDetails");
                listRequest.MaxResults = 50;
                listRequest.PlaylistId = playListId;
                listRequest.PageToken  = nextPageToken;
                var response = await listRequest.ExecuteAsync();

                if (playListSongs == null)
                {
                    playListSongs = new List <IYouTubeSong>();
                }
                foreach (var playlistItem in response.Items)
                {
                    VideosResource.ListRequest videoR = youtubeService.Videos.List("snippet");
                    videoR.Id = playlistItem.ContentDetails.VideoId;
                    var responseV = await videoR.ExecuteAsync();

                    KeyValuePair <string, string> parsedSong = SongTitleParser.ParseTitle(responseV.Items[0].Snippet.Title);
                    IYouTubeSong currentSong = new YouTubeSong(parsedSong.Key, parsedSong.Value, responseV.Items[0].Id, playlistItem.Id, null);
                    playListSongs.Add(currentSong);
                    Debug.WriteLine(playlistItem.Snippet.Title);
                }
                nextPageToken = response.NextPageToken;
            }
        }
Ejemplo n.º 4
0
        public static async Task <PlaylistItemListResponse> ExecuteAllAsync(this PlaylistItemsResource.ListRequest request, CancellationToken ct = default(CancellationToken))
        {
            request.MaxResults = request.MaxResults ?? 50;
            var response = await request.ExecuteAsync(ct);

            if (!response.Items.Any())
            {
                return(response);
            }
            var collection = response.Items.ToList();

            while (!ct.IsCancellationRequested)
            {
                if (string.IsNullOrWhiteSpace(response.NextPageToken))
                {
                    break;
                }
                request.PageToken = response.NextPageToken;
                response          = await request.ExecuteAsync(ct);

                if (response.Items.Any())
                {
                    collection.AddRange(response.Items);
                }
            }

            response.Items = collection;
            return(response);
        }
        /// <summary>
        /// Refreshes the cached data in Cassandra for a given YouTube playlist.
        /// </summary>
        internal async Task RefreshPlaylist(YouTubeVideoSource.VideosFromPlaylist playlistSource)
        {
            // Statement for inserting the video into the sample table
            PreparedStatement preparedInsert = await _statementCache.NoContext.GetOrAddAsync(
                "INSERT INTO sample_data_youtube_videos (sourceid, published_at, youtube_video_id, name, description) VALUES (?, ?, ?, ?, ?)");

            bool   getMoreVideos = true;
            string nextPageToken = null;
            var    insertTasks   = new List <Task>();

            do
            {
                // Create playlist items request
                PlaylistItemsResource.ListRequest playlistRequest = _youTubeService.PlaylistItems.List("snippet");
                playlistRequest.MaxResults = MaxVideosPerRequest;
                playlistRequest.PlaylistId = playlistSource.PlaylistId;
                if (string.IsNullOrEmpty(nextPageToken) == false)
                {
                    playlistRequest.PageToken = nextPageToken;
                }

                // Get the results and insert as rows in Cassandra
                PlaylistItemListResponse playlistItems = await playlistRequest.ExecuteAsync().ConfigureAwait(false);

                foreach (var playlistItem in playlistItems.Items)
                {
                    // If we've reached the max, no need to continue
                    if (insertTasks.Count >= MaxVideosPerSource)
                    {
                        getMoreVideos = false;
                        break;
                    }

                    DateTimeOffset publishedAt = playlistItem.Snippet.PublishedAt.HasValue
                                                     ? playlistItem.Snippet.PublishedAt.Value.ToUniversalTime()
                                                     : Epoch;

                    Task <RowSet> insertTask =
                        _session.ExecuteAsync(preparedInsert.Bind(playlistSource.UniqueId, publishedAt, playlistItem.Snippet.ResourceId.VideoId,
                                                                  playlistItem.Snippet.Title, playlistItem.Snippet.Description));
                    insertTasks.Add(insertTask);
                }

                // If we don't have a next page, we can bail
                nextPageToken = playlistItems.NextPageToken;
                if (string.IsNullOrEmpty(nextPageToken))
                {
                    getMoreVideos = false;
                }
            } while (getMoreVideos);

            // Wait for any insert tasks to finish
            if (insertTasks.Count > 0)
            {
                await Task.WhenAll(insertTasks).ConfigureAwait(false);
            }
        }
Ejemplo n.º 6
0
        private async Task RunYoutubeService(int checkInterval)
        {
            _tempDateTime = DateTime.Now;              // saving time of launch
            _yts          = new YouTubeService(new BaseClientService.Initializer
            {
                ApiKey          = _ytApiKey,
                ApplicationName = "leetbot"
            });

            PlaylistItemsResource.ListRequest playlistItemsListRequest = _yts.PlaylistItems.List("contentDetails");
            playlistItemsListRequest.MaxResults = 5;                // last 5 videos
            playlistItemsListRequest.Fields     = "items(contentDetails(videoId,videoPublishedAt))";

            _discordClient.Logger.LogInformation("[YoutubeService] Service started.");

            _isRunning = true;

            while (true)
            {
                foreach (string uploadsId in _youtubeChannelList)
                {
                    playlistItemsListRequest.PlaylistId = uploadsId;
                    PlaylistItemListResponse playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();

                    foreach (PlaylistItem playlistItem in playlistItemsListResponse.Items)
                    {
                        if (playlistItem.ContentDetails.VideoPublishedAt == null ||
                            playlistItem.ContentDetails.VideoPublishedAt.GetValueOrDefault().CompareTo(_tempDateTime) <= 0)
                        {
                            continue;
                        }

                        _discordClient.Logger.LogInformation("[YoutubeService] " +
                                                             "New video uploaded: https://www.youtube.com/watch?v=" +
                                                             $"{playlistItem.ContentDetails.VideoId}");

                        foreach (DiscordChannel logChannel in _logChannelsList)
                        {
                            try
                            {
                                await _discordClient.SendMessageAsync(logChannel,
                                                                      "@everyone NEW VIDEO\nhttps://www.youtube.com/watch?v=" +
                                                                      $"{playlistItem.ContentDetails.VideoId}");
                            }
                            catch (Exception e)
                            {
                                _discordClient.Logger.LogError($"[YoutubeVideoMonitor] Discord message error: {e.Message}");
                            }
                        }
                        _tempDateTime = DateTime.Now;
                    }
                }
                await Task.Delay(checkInterval * 60 * 1000);    // once in checkInterval minutes

                _discordClient.Logger.LogDebug("[YoutubeVideoMonitor] Service tick.");
            }
        }
Ejemplo n.º 7
0
 public PlaylistItemsResource.ListRequest ToActualRequest(YouTubeService service)
 {
     PlaylistItemsResource.ListRequest actual = service.PlaylistItems.List(Part);
     actual.Id                     = Id;
     actual.MaxResults             = MaxResults;
     actual.OnBehalfOfContentOwner = OnBehalfOfContentOwner;
     actual.PageToken              = PageToken;
     actual.PlaylistId             = PlaylistId;
     actual.VideoId                = VideoId;
     return(actual);
 }
Ejemplo n.º 8
0
        public async Task <ActionResult <PlaylistItemListResponse> > List([Required, FromQuery] AppPlaylistItemListRequest request)
        {
            YouTubeService service = await serviceAccessor.InitializeServiceAsync();

            PlaylistItemsResource.ListRequest requestActual = request.ToActualRequest(service);

            try {
                PlaylistItemListResponse response = await requestActual.ExecuteAsync();

                return(new ActionResult <PlaylistItemListResponse>(response));
            } catch (GoogleApiException ex) {
                return(StatusCode((int)ex.HttpStatusCode, ex.ToString()));
            }
        }
Ejemplo n.º 9
0
        public Youtube(IHelpers helpers)
        {
            _youtubeService = new YouTubeService(new BaseClientService.Initializer
            {
                ApplicationName = helpers.UserAgent,

                // Create the following class in a separate file to supply
                // the google api key. Mark it as ignored by source controll.
                //
                // public partial class Youtube
                // {
                //    private const string key = "";
                // }
                ApiKey = key,
            });;
            _playlistItems            = _youtubeService.PlaylistItems.List("contentDetails");
            _playlistItems.MaxResults = 100;
        }
Ejemplo n.º 10
0
        public static async Task <List <PlaylistItem> > ExecuteWithPagingAsync(this PlaylistItemsResource.ListRequest request)
        {
            var    result         = new List <PlaylistItem>();
            var    remainingCount = request.MaxResults;
            string nextPageToken  = null;

            do
            {
                request.MaxResults = remainingCount;
                request.PageToken  = nextPageToken;
                var response = await request.ExecuteAsync();

                result.AddRange(response.Items);
                nextPageToken   = response.NextPageToken;
                remainingCount -= response.Items.Count;
            }while (nextPageToken != null && remainingCount != 0);

            return(result);
        }
Ejemplo n.º 11
0
        private static IEnumerable <PlaylistItem> PlaylistItems(PlaylistItemsResource.ListRequest request)
        {
            request.MaxResults = 50;
            while (true)
            {
                var response = request.Execute();

                foreach (var item in response.Items)
                {
                    yield return(item);
                }

                if (response.NextPageToken == null)
                {
                    yield break;
                }

                request.PageToken = response.NextPageToken;
            }
        }
Ejemplo n.º 12
0
        internal async Task <IEnumerable <PlaylistItem> > GetPlaylistItems(string playlistID, int maxResults = 1)
        {
            return(await this.YouTubeServiceWrapper(async() =>
            {
                List <PlaylistItem> results = new List <PlaylistItem>();
                string pageToken = null;
                do
                {
                    PlaylistItemsResource.ListRequest request = this.connection.GoogleYouTubeService.PlaylistItems.List("snippet,contentDetails");
                    request.PlaylistId = playlistID;
                    request.MaxResults = Math.Min(maxResults, 50);
                    request.PageToken = pageToken;

                    PlaylistItemListResponse response = await request.ExecuteAsync();
                    results.AddRange(response.Items);
                    maxResults -= response.Items.Count;
                    pageToken = response.NextPageToken;
                } while (maxResults > 0 && !string.IsNullOrEmpty(pageToken));
                return results;
            }));
        }
Ejemplo n.º 13
0
        public async Task <IEnumerable <YouTubeVideo> > GetVideos(string playlistId)
        {
            List <YouTubeVideo> videos = new List <YouTubeVideo>();

            string pageToken = null;

            do
            {
                PlaylistItemsResource.ListRequest listPlaylistRequest = _youTubeApiService.PlaylistItems.List("snippet");
                listPlaylistRequest.PlaylistId = playlistId;
                listPlaylistRequest.MaxResults = 50;
                listPlaylistRequest.PageToken  = pageToken;

                PlaylistItemListResponse response = await listPlaylistRequest.ExecuteAsync();

                pageToken = response.NextPageToken;

                videos.AddRange(response.Items.Select(video => new YouTubeVideo(video.Id, video.Snippet.Title)));
            } while (pageToken != null);

            return(videos);
        }
Ejemplo n.º 14
0
        private async Task <IEnumerable <YouTubeVideo> > GetPlaylistVideos(string playlistId)
        {
            List <YouTubeVideo> videos = new List <YouTubeVideo>();

            string pageToken = null;

            do
            {
                PlaylistItemsResource.ListRequest playlistRequest = _youTubeApiService.PlaylistItems.List("snippet");
                playlistRequest.PlaylistId = playlistId;
                playlistRequest.MaxResults = MaxQueryResults;
                playlistRequest.PageToken  = pageToken;

                PlaylistItemListResponse playlistResponse = await playlistRequest.ExecuteAsync();

                pageToken = playlistResponse.NextPageToken;

                videos.AddRange(await GetVideos(playlistResponse.Items.Select(playlistItem => playlistItem.Snippet.ResourceId.VideoId)));
            } while (pageToken != null);

            return(videos);
        }
Ejemplo n.º 15
0
 private void TrackDependency(string url, PlaylistItemsResource.ListRequest listRequest, PlaylistItemListResponse playlistItems, long started)
 {
     if (_telemetry.IsEnabled())
     {
         Uri.TryCreate(url, UriKind.Absolute, out Uri uri);
         var duration   = Timing.GetDuration(started);
         var dependency = new DependencyTelemetry
         {
             Type      = "HTTP",
             Target    = uri?.Host ?? url,
             Name      = listRequest.RestPath,
             Data      = listRequest.CreateRequest().RequestUri.ToString(),
             Timestamp = DateTimeOffset.UtcNow,
             Duration  = duration,
             Success   = playlistItems != null
         };
         dependency.Properties.Add("HTTP Method", listRequest.HttpMethod);
         dependency.Properties.Add("Event Id", playlistItems.EventId);
         dependency.Properties.Add("Total Results", (playlistItems.PageInfo.TotalResults ?? 0).ToString());
         _telemetry.TrackDependency(dependency);
     }
 }
        public async static Task <List <PlaylistItem> > GetMostRecentUploadsAsync(Subscription sub, DateTime?sinceDate = null)
        {
            List <PlaylistItem> resultsByDate = new List <PlaylistItem>();

            if (!string.IsNullOrWhiteSpace(sub.PlaylistIdToWatch))
            {
                try
                {
                    PlaylistItemsResource.ListRequest listRequest = Service.PlaylistItems.List("snippet,status");
                    listRequest.PlaylistId = sub.PlaylistIdToWatch;
                    PlaylistItemListResponse response = null;

                    List <PlaylistItem> results         = new List <PlaylistItem>();
                    List <PlaylistItem> privateToPublic = new List <PlaylistItem>();
                    if (sub.IsPlaylist && !sub.IsPlaylistUploadsPlaylist) //If this is the uploads playlist for the channel, it WILL be at least somewhat ordered by most recent
                    {
                        //A playlist isn't necessarily in date order (the owner of the playlist could put them in any order).
                        //Unfortunately, that means we have to get every video in the playlist and order them by date. This will be costly for large playlists

                        listRequest.MaxResults = 50; //50 is the maximum

                        try
                        {
                            response = await listRequest.ExecuteAsync();
                        }
                        catch (Google.GoogleApiException e)
                        {
                            if (e.HttpStatusCode == HttpStatusCode.NotFound)
                            {
                                MessageBox.Show($"There was a problem accessing the playlist for {sub.Title}.\n\nPerhaps it has been deleted?");
                                return(resultsByDate);
                            }
                            else
                            {
                                throw;
                            }
                        }

                        results.AddRange(response.Items);

                        while (response.NextPageToken != null)
                        {
                            listRequest.PageToken = response.NextPageToken;
                            response = await listRequest.ExecuteAsync();

                            results.AddRange(response.Items);
                        }
                    }
                    else
                    {
                        listRequest.MaxResults = 50;
                        response = await listRequest.ExecuteAsync();

                        results.AddRange(response.Items);

                        //If we still haven't gotten any items older than the "sinceDate", get more
                        if (sinceDate != null)
                        {
                            while (!results.Any(p => p.Snippet.PublishedAt < sinceDate) && response.NextPageToken != null)
                            {
                                listRequest.PageToken = response.NextPageToken;
                                response = await listRequest.ExecuteAsync();

                                results.AddRange(response.Items);
                            }
                        }
                    }

                    //Remove any that do not match the regex filter
                    if (!string.IsNullOrEmpty(sub.FilterRegex))
                    {
                        results.RemoveAll(p => !Regex.IsMatch(p.Snippet.Title, sub.FilterRegex));
                    }

                    //Check to see if any of the sub's private videos have change to public
                    foreach (string videoId in sub.PrivateVideosToWatch)
                    {
                        PlaylistItem matchingItem = results.Find(p => p.Snippet.ResourceId.VideoId == videoId);
                        if (matchingItem != null && matchingItem.Status.PrivacyStatus == "public")
                        {
                            privateToPublic.Add(matchingItem);
                        }
                    }

                    //Stop watching for private video status change if it is now in "privateToPublic"
                    sub.PrivateVideosToWatch.RemoveAll(p => privateToPublic.Find(o => o.Snippet.ResourceId.VideoId == p) != null);

                    List <PlaylistItem> recentPrivateVideos = results.Where(p => p.Status != null && p.Status.PrivacyStatus == "private").ToList();
                    foreach (PlaylistItem video in recentPrivateVideos)
                    {
                        string videoId = video.Snippet.ResourceId.VideoId;
                        if (!sub.PrivateVideosToWatch.Contains(videoId))
                        {
                            sub.PrivateVideosToWatch.Add(videoId);
                        }

                        results.Remove(video);
                    }

                    if (sinceDate != null)
                    {
                        results = results.Where(p => p.Snippet.PublishedAt > sinceDate).ToList();
                    }

                    results.AddRange(privateToPublic);

                    ////------------------------------------
                    ////   There is currently a bug with retrieving uploads playlists where the returned order does not match
                    ////   the order shown on YouTube https://issuetracker.google.com/issues/65067744 . To combat this, we
                    ////   will get the top 50 results and order them by upload date

                    resultsByDate = results.OrderByDescending(p => p.Snippet.PublishedAt).ToList();
                    ////------------------------------------
                }
                catch (Exception ex)
                {
                    Common.HandleException(ex);
                }
            }

            //Sometimes we sense a new video twice in "newUploads". Not sure why (if it's a YouTube API bug or my code), but this will prevent
            //notifying for that video twice (removes duplicate videoIds from the results list)
            resultsByDate = (from v in resultsByDate
                             group v by v.Snippet.ResourceId.VideoId into g
                             select g.First()).ToList();

            return(resultsByDate);
        }
        private List <PlaylistItem> GetMostRecentUploads(Subscription sub, DateTime?sinceDate = null)
        {
            List <PlaylistItem> resultsByDate = new List <PlaylistItem>();

            if (!string.IsNullOrWhiteSpace(sub.PlaylistIdToWatch))
            {
                PlaylistItemsResource.ListRequest listRequest = service.PlaylistItems.List("snippet,status");
                listRequest.PlaylistId = sub.PlaylistIdToWatch;
                PlaylistItemListResponse response;

                List <PlaylistItem> results         = new List <PlaylistItem>();
                List <PlaylistItem> privateToPublic = new List <PlaylistItem>();
                if (sub.IsPlaylist &&
                    GetChannelUploadsPlaylistId(sub) != sub.PlaylistIdToWatch) //If this is the uploads playlist for the channel, it WILL be at least somewhat ordered by most recent
                {
                    //A playlist isn't necessarily in date order (the owner of the playlist could put them in any order).
                    //Unfortunately, that means we have to get every video in the playlist and order them by date. This will be costly for large playlists

                    listRequest.MaxResults = 50; //50 is the maximum
                    response = listRequest.Execute();
                    results.AddRange(response.Items);

                    while (response.NextPageToken != null)
                    {
                        listRequest.PageToken = response.NextPageToken;
                        response = listRequest.Execute();
                        results.AddRange(response.Items);
                    }
                }
                else
                {
                    listRequest.MaxResults = 50;
                    response = listRequest.Execute();
                    results.AddRange(response.Items);

                    //If we still haven't gotten any items older than the "sinceDate", get more
                    if (sinceDate != null)
                    {
                        while (!results.Any(p => p.Snippet.PublishedAt < sinceDate) && response.NextPageToken != null)
                        {
                            listRequest.PageToken = response.NextPageToken;
                            response = listRequest.Execute();
                            results.AddRange(response.Items);
                        }
                    }
                }

                //Check to see if any of the sub's private videos have change to public
                foreach (string videoId in sub.PrivateVideosToWatch)
                {
                    PlaylistItem matchingItem = results.Find(p => p.Snippet.ResourceId.VideoId == videoId);
                    if (matchingItem != null && matchingItem.Status.PrivacyStatus == "public")
                    {
                        privateToPublic.Add(matchingItem);
                    }
                }

                //Stop watching for private video status change if it is now in "privateToPublic"
                sub.PrivateVideosToWatch.RemoveAll(p => privateToPublic.Find(o => o.Snippet.ResourceId.VideoId == p) != null);

                List <PlaylistItem> recentPrivateVideos = results.Where(p => p.Status.PrivacyStatus == "private").ToList();
                foreach (PlaylistItem video in recentPrivateVideos)
                {
                    string videoId = video.Snippet.ResourceId.VideoId;
                    if (!sub.PrivateVideosToWatch.Contains(videoId))
                    {
                        sub.PrivateVideosToWatch.Add(videoId);
                    }

                    results.Remove(video);
                }

                if (sinceDate != null)
                {
                    results = results.Where(p => p.Snippet.PublishedAt > sinceDate).ToList();
                }

                results.AddRange(privateToPublic);

                ////------------------------------------
                ////   There is currently a bug with retrieving uploads playlists where the returned order does not match
                ////   the order shown on YouTube https://issuetracker.google.com/issues/65067744 . To combat this, we
                ////   will get the top 50 results and order them by upload date

                resultsByDate = results.OrderByDescending(p => p.Snippet.PublishedAt).ToList();
                ////------------------------------------
            }

            return(resultsByDate);
        }
Ejemplo n.º 18
0
 public async Task <PlaylistItemListResponse> SearchPlayListTask(string id)
 {
     PlaylistItemsResource.ListRequest request = _youTubeService.PlaylistItems.List("");
     request.PlaylistId = id;
     return(await request.ExecuteAsync());
 }
Ejemplo n.º 19
0
        public YoutubeViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            TokenSource = new CancellationTokenSource();

            RegionManager   = regionManager;
            EventAggregator = eventAggregator;
            NrColumns       = 4;

            MediaState = new MediaState();
            MediaStateCollectionView = new YoutubeCollectionView(MediaState);
            MediaState.clearUIState("Empty", DateTime.Now, MediaStateType.SearchResult);

            MediaStateCollectionView.SelectionChanged += mediaStateCollectionView_SelectionChanged;

            ViewCommand = new Command <SelectableMediaItem>((selectableItem) =>
            {
                if (selectableItem.Item.Metadata == null)
                {
                    return;
                }

                if (selectableItem.Item is YoutubeVideoItem)
                {
                    YoutubeVideoItem item = selectableItem.Item as YoutubeVideoItem;

                    if (item.IsEmbeddedOnly)
                    {
                        Process.Start("https://www.youtube.com/watch?v=" + item.VideoId);
                    }
                    else
                    {
                        YoutubeVideoStreamedItem video, audio;
                        item.getStreams(out video, out audio, (int)Properties.Settings.Default.MaxPlaybackResolution);

                        Shell.ShellViewModel.navigateToVideoView(video, null, audio);
                    }
                }
            });

            ViewChannelCommand = new AsyncCommand <SelectableMediaItem>(async(selectableItem) =>
            {
                if (selectableItem.Item.Metadata == null)
                {
                    return;
                }

                YoutubeItem item = selectableItem.Item as YoutubeItem;

                SearchResource.ListRequest searchListRequest = Youtube.Search.List("snippet");
                searchListRequest.ChannelId  = item.ChannelId;
                searchListRequest.MaxResults = YoutubeSearchViewModel.maxResults;
                searchListRequest.Order      = Google.Apis.YouTube.v3.SearchResource.ListRequest.OrderEnum.Date;

                MediaStateCollectionView.FilterModes.MoveCurrentToFirst();

                await searchAsync(searchListRequest, item.ChannelTitle, false);
            });

            ViewPlaylistCommand = new AsyncCommand <SelectableMediaItem>(async(selectableItem) =>
            {
                if (selectableItem.Item.Metadata == null)
                {
                    return;
                }

                YoutubePlaylistItem item = selectableItem.Item as YoutubePlaylistItem;

                PlaylistItemsResource.ListRequest searchListRequest = Youtube.PlaylistItems.List("snippet");
                searchListRequest.PlaylistId = item.PlaylistId;
                searchListRequest.MaxResults = YoutubeSearchViewModel.maxResults;

                MediaStateCollectionView.FilterModes.MoveCurrentToFirst();

                await searchAsync(searchListRequest, item.Name, false);
            });

            SubscribeCommand = new Command <SelectableMediaItem>((selectableItem) =>
            {
                YoutubeChannelItem item = selectableItem.Item as YoutubeChannelItem;

                EventAggregator.GetEvent <AddFavoriteChannelEvent>().Publish(item);
            });

            DownloadCommand = new AsyncCommand <SelectableMediaItem>(async(selectableItem) => {
                List <MediaItem> items = MediaStateCollectionView.getSelectedItems();
                if (items.Count == 0)
                {
                    items.Add(selectableItem.Item);
                }

                String outputPath = null;

                switch (YoutubePlugin.Properties.Settings.Default.VideoSaveMode)
                {
                case MediaViewer.Infrastructure.Constants.SaveLocation.Current:
                    {
                        outputPath = MediaFileWatcher.Instance.Path;
                        break;
                    }

                case MediaViewer.Infrastructure.Constants.SaveLocation.Ask:
                    {
                        DirectoryPickerView directoryPicker = new DirectoryPickerView();
                        directoryPicker.DirectoryPickerViewModel.InfoString   = "Select Output Directory";
                        directoryPicker.DirectoryPickerViewModel.SelectedPath = MediaFileWatcher.Instance.Path;

                        if (directoryPicker.ShowDialog() == false)
                        {
                            return;
                        }

                        outputPath = directoryPicker.DirectoryPickerViewModel.SelectedPath;

                        break;
                    }

                case MediaViewer.Infrastructure.Constants.SaveLocation.Fixed:
                    {
                        outputPath = YoutubePlugin.Properties.Settings.Default.FixedDownloadPath;
                        break;
                    }

                default:
                    break;
                }

                CancellableOperationProgressView progressView = new CancellableOperationProgressView();
                DownloadProgressViewModel vm = new DownloadProgressViewModel();
                progressView.DataContext     = vm;

                progressView.Show();
                vm.OkCommand.IsExecutable     = false;
                vm.CancelCommand.IsExecutable = true;

                await Task.Factory.StartNew(() =>
                {
                    vm.startDownload(outputPath, items);
                });

                vm.OkCommand.IsExecutable     = true;
                vm.CancelCommand.IsExecutable = false;
            });

            LoadNextPageCommand = new AsyncCommand(async() =>
            {
                await searchAsync(CurrentQuery, "", true);
            });

            SelectAllCommand = new Command(() =>
            {
                MediaStateCollectionView.selectAll();
            }, false);

            DeselectAllCommand = new Command(() =>
            {
                MediaStateCollectionView.deselectAll();
            });

            ShutdownCommand = new Command(() =>
            {
                Properties.Settings.Default.Save();
            });

            MediaState.UIMediaCollection.IsLoadingChanged += UIMediaCollection_IsLoadingChanged;

            MediaViewer.Model.Global.Commands.GlobalCommands.ShutdownCommand.RegisterCommand(ShutdownCommand);

            setupViews();

            EventAggregator.GetEvent <SearchEvent>().Subscribe(searchEvent);

            SearchTask = null;
        }
Ejemplo n.º 20
0
        public async Task QueuePlaylist(CommandContext ctx, string playlistUrl, [Description("Shuffle the playlist when adding to queue. \"true\" to enable.")] bool shuffle = false)
        {
            if (ctx.Client.GetVoiceNext()?.GetConnection(ctx.Guild)?.Channel != null && ctx.Client.GetVoiceNext().GetConnection(ctx.Guild).Channel.Users.All(e => e.Id != ctx.User.Id))
            {
                throw new OutputException("You must join a voice channel to queue songs.");
            }

            Uri playlistUri;

            try
            {
                playlistUri = new Uri(playlistUrl);
            }
            catch
            {
                throw new OutputException("Invalid url.");
            }

            NameValueCollection query = HttpUtility.ParseQueryString(playlistUri.Query);

            if (!query.AllKeys.Contains("list"))
            {
                throw new OutputException("Url must point to a YouTube playlist, specifically with a \"list=\" query.");
            }

            YouTubeService youtubeService = new YouTubeService(new BaseClientService.Initializer
            {
                ApiKey          = Globals.BotSettings.YoutubeApiKey,
                ApplicationName = this.GetType().ToString()
            });

            PlaylistsResource.ListRequest playlistListRequest = youtubeService.Playlists.List("snippet");
            playlistListRequest.Id         = query["list"];
            playlistListRequest.MaxResults = 1;

            PlaylistListResponse playlistListResponse = playlistListRequest.Execute();

            PlaylistItemsResource.ListRequest playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
            playlistItemsListRequest.PlaylistId = query["list"];
            playlistItemsListRequest.MaxResults = 50;

            PlaylistItemListResponse playlistItemsListResponse = playlistItemsListRequest.Execute();

            if (!playlistItemsListResponse.Items.Any())
            {
                throw new OutputException("Unable to retrieve playlist or playlist is empty.");
            }

            if (shuffle)
            {
                playlistItemsListResponse.Items.Shuffle();
            }

            int resultQueueCount = GuildQueues.ContainsKey(ctx.Guild.Id) ? GuildQueues[ctx.Guild.Id].Count + playlistItemsListResponse.Items.Count : playlistItemsListResponse.Items.Count;

            await ctx.RespondAsync($"Queuing {playlistItemsListResponse.Items.Count} songs, please be patient if this is the first items to be added to queue. " +
                                   "(If you try to play music and nothing happens most likely the first song is still pending)");

            if (!GuildMusicStatuses.TryGetValue(ctx.Guild.Id, out MusicStatus musicStatus))
            {
                GuildMusicStatuses.Add(ctx.Guild.Id, new MusicStatus
                {
                    Skip = false
                });
            }

            while (GuildMusicStatuses[ctx.Guild.Id].Queuing)
            {
            }

            GuildMusicStatuses[ctx.Guild.Id].Queuing = true;

            foreach (PlaylistItem playlistItem in playlistItemsListResponse.Items)
            {
                string id = playlistItem.Snippet.ResourceId.VideoId;

                VideosResource.ListRequest idSearch = youtubeService.Videos.List("id,snippet");
                idSearch.Id         = id;
                idSearch.MaxResults = 1;

                VideoListResponse videoListResponse = await idSearch.ExecuteAsync();

                if (videoListResponse.Items.Count == 0)
                {
                    await ctx.RespondAsync("Video link cannot be parsed.");

                    return;
                }

                if (!GuildQueues.ContainsKey(ctx.Guild.Id))
                {
                    GuildQueues.Add(ctx.Guild.Id, new List <JigglySong>());
                }

                Video parsedVideo = videoListResponse.Items.First();

                if (!string.IsNullOrWhiteSpace(parsedVideo.ContentDetails?.Duration) && XmlConvert.ToTimeSpan(parsedVideo.ContentDetails.Duration).Minutes > 15)
                {
                    await ctx.RespondAsync("This video is too long, please try to find something shorter than 15 minutes.");
                }

                Guid guid = Guid.NewGuid();

                AddSong(guid, parsedVideo.Snippet.Title, parsedVideo.Id, parsedVideo.Snippet.ChannelTitle, JigglySong.SongType.Youtube, ctx.Member);

                if (!DownloadHelper.GuildMusicTasks.ContainsKey(ctx.Guild.Id))
                {
                    DownloadHelper.GuildMusicTasks.Add(ctx.Guild.Id, new List <(Guid guid, Func <string> downloadTask)>());
                }

                DownloadHelper.GuildMusicTasks[ctx.Guild.Id].Add((guid, () => DownloadHelper.DownloadFromYouTube(ctx, $"https://www.youtube.com/watch?v={id}")));

                if (!DownloadHelper.IsDownloadLoopRunning)
                {
                    new Thread(() => DownloadHelper.DownloadQueue(ctx.Guild.Id)).Start();
                }
            }

            GuildMusicStatuses[ctx.Guild.Id].Queuing = false;

            DiscordEmbedBuilder confirmationBuilder = new DiscordEmbedBuilder
            {
                Description = $"**✅ Successfully added [{playlistListResponse.Items.First().Snippet.Title}](https://www.youtube.com/playlist?list={query["list"]}) " +
                              $"to queue positions {resultQueueCount + 1 - playlistItemsListResponse.Items.Count}-{resultQueueCount}**"
            };

            await ctx.RespondAsync(null, false, confirmationBuilder.Build());
        }
Ejemplo n.º 21
0
        private async Task AccessPlaylist()
        {
            UserCredential credential;

            using (var stream = new FileStream(@"C:\client_id.json", FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    // This OAuth 2.0 access scope allows for read-only access to the authenticated
                    // user's account, but not other types of account access.
                    new[] { YouTubeService.Scope.YoutubeReadonly },
                    "psangat",
                    CancellationToken.None,
                    new FileDataStore(this.GetType().ToString())
                    );
            }

            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName       = this.GetType().ToString()
            });

            var playlists = youtubeService.Playlists.List("snippet");

            playlists.PageToken  = "";
            playlists.MaxResults = 50;
            playlists.Mine       = true;
            PlaylistListResponse presponse = await playlists.ExecuteAsync();

            foreach (var currentPlayList in presponse.Items)
            {
                if (currentPlayList.Snippet.Title.Equals("Songs"))
                {
                    PlaylistItemsResource.ListRequest listRequest = youtubeService.PlaylistItems.List("contentDetails");
                    listRequest.MaxResults = 50;
                    listRequest.PlaylistId = currentPlayList.Id;
                    listRequest.PageToken  = playlists.PageToken;
                    var response = await listRequest.ExecuteAsync();

                    var index = 1;
                    foreach (var playlistItem in response.Items)
                    {
                        VideosResource.ListRequest videoR = youtubeService.Videos.List("snippet, contentDetails, status");
                        videoR.Id = playlistItem.ContentDetails.VideoId;
                        var responseV = await videoR.ExecuteAsync();

                        if (responseV.Items.Count > 0)
                        {
                            string link = String.Format("https://www.youtube.com/watch?v={0}&list={1}&index={2}", videoR.Id, currentPlayList.Id, index);
                            IEnumerable <VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);

                            try
                            {
                                VideoInfo video = videoInfos.First(info => info.VideoType == VideoType.Mp4 && info.Resolution == 0 && !String.IsNullOrEmpty(info.Title));
                                Console.WriteLine("Downloading {0}", video.Title);
                                if (video.RequiresDecryption)
                                {
                                    DownloadUrlResolver.DecryptDownloadUrl(video);
                                }

                                using (var progress = new ProgressBar())
                                {
                                    for (int i = 0; i <= 100; i++)
                                    {
                                        progress.Report((double)i / 100);
                                        Thread.Sleep(20);
                                    }
                                }
                                var audioDownloader = new VideoDownloader(video, Path.Combine(@"C:\Users\prsangat\Desktop\Songs", video.Title + ".mp3"));
                                using (var progress = new ProgressBar())
                                {
                                    audioDownloader.DownloadProgressChanged += (sender, args) => progress.Report(args.ProgressPercentage);
                                }
                                //audioDownloader.DownloadProgressChanged += (sender, args) => progre//Console.Write( "\r{0}% ", Math.Round(args.ProgressPercentage));
                                audioDownloader.Execute();
                                Console.WriteLine("Download Complete.");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine();
                                Console.WriteLine(ex.ToString());
                                Console.WriteLine();
                                // throw;
                            }

                            index++;
                        }
                    }
                    playlists.PageToken = response.NextPageToken;
                }
            }
        }
Ejemplo n.º 22
0
        public List <YouTubeVideo> LoadURLVideos(SYMMSettings settings, List <YouTubeVideo> videos = null, string nextPageToken = null)
        {
            if (settings.UrlSpecs.IsPlaylist && settings.DownloadMode == Mode.All)
            {
                string playlistID = Regex.Split(settings.DownloadURL, @"list=")[1];

                if (playlistID.Contains("&"))
                {
                    playlistID = playlistID.Split('&')[0];
                }

                // Load Uploaded Playlist
                PlaylistItemsResource.ListRequest playlistVideosReq = YouTubeService.PlaylistItems.List("snippet,id");
                playlistVideosReq.PlaylistId = playlistID;
                playlistVideosReq.PageToken  = nextPageToken;
                playlistVideosReq.MaxResults = 50;
                PlaylistItemListResponse playlistVideosRes = playlistVideosReq.Execute();

                // Finnaly grab the video IDs
                if (videos == null)
                {
                    videos = new List <YouTubeVideo>();
                }

                // Populate video list
                foreach (PlaylistItem videoItem in playlistVideosRes.Items)
                {
                    try
                    {
                        YouTubeVideo loadedVideo = new YouTubeVideo(videoItem.Snippet.Title, videoItem.Snippet.ResourceId.VideoId, videoItem.Snippet.Description, videoItem.Snippet.PublishedAt, videoItem.Snippet.Thumbnails.Default__.Url, videoItem.Snippet.ChannelTitle, videoItem.Snippet.Position);
                        videos.Add(loadedVideo);

                        if (OnVideoInformationLoaded != null)
                        {
                            OnVideoInformationLoaded(this, new VideoInformationLoadedEventArgs(loadedVideo));
                        }
                    }
                    catch (NullReferenceException)
                    {
                        Console.WriteLine("Skipped one deleted video");
                    }
                }

                // Check if we have more to grab
                if (!string.IsNullOrEmpty(playlistVideosRes.NextPageToken))
                {
                    videos = LoadURLVideos(settings, videos, playlistVideosRes.NextPageToken);
                }

                if (OnAllVideoInformationLoaded != null)
                {
                    OnAllVideoInformationLoaded(this, new AllVideoInformationLoadedEventArgs(videos));
                }

                return(videos);
            }
            else if (settings.UrlSpecs.ContainsVideo)
            {
                string watchID = Regex.Split(Regex.Split(settings.DownloadURL, @"v=")[1], "&")[0];

                VideosResource.ListRequest videoListReq = YouTubeService.Videos.List("snippet, id");
                videoListReq.Id = watchID;
                VideoListResponse videoListResp = videoListReq.Execute();

                if (videos == null)
                {
                    videos = new List <YouTubeVideo>();
                }

                Video        videoItem   = videoListResp.Items[0];
                YouTubeVideo loadedVideo = new YouTubeVideo(videoItem.Snippet.Title, videoItem.Id, videoItem.Snippet.Description, videoItem.Snippet.PublishedAt, videoItem.Snippet.Thumbnails.Default__.Url, videoItem.Snippet.ChannelTitle, 0);
                videos.Add(loadedVideo);

                if (OnVideoInformationLoaded != null)
                {
                    OnVideoInformationLoaded(this, new VideoInformationLoadedEventArgs(loadedVideo));
                }

                if (OnAllVideoInformationLoaded != null)
                {
                    OnAllVideoInformationLoaded(this, new AllVideoInformationLoadedEventArgs(videos));
                }

                return(videos);
            }
            else
            {
                throw new ArgumentException("The URL specified is not a valid youtube playlist or watch url");
            }
        }
        private async Task <Chart> GetOrCreatePlaylist(Chart chart)
        {
            int chartNameWithPrefixLen = chart.NameWithPrefix.Length;

            UserCredential credential;

            try
            {
                using (FileStream stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
                {
                    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        // This OAuth 2.0 access scope allows for full read/write access to the
                        // authenticated user's account.
                        new[] { YouTubeService.Scope.Youtube },
                        "user",
                        CancellationToken.None,
                        new FileDataStore(GetType().ToString())
                        );
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
                return(null);
            }

            var youTubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName       = GetType().ToString()
            });

            // Find playlist by chart name
            PlaylistsResource.ListRequest playlistReq = youTubeService.Playlists.List("snippet");
            playlistReq.Mine       = true;
            playlistReq.MaxResults = 10;
            PlaylistListResponse playlistResp = await playlistReq.ExecuteAsync();

            Playlist playlist = null;

            foreach (Playlist playlistCandidate in playlistResp.Items)
            {
                string playlistTitle = playlistCandidate.Snippet.Title;
                if (playlistTitle.Length > chartNameWithPrefixLen && playlistTitle.Substring(0, chartNameWithPrefixLen) == chart.NameWithPrefix)
                {
                    playlist = playlistCandidate;
                    Debug.WriteLine("Playlist for {0} already exists as {1}", chart.Name, playlist.Snippet.Title);
                    break;
                }
            }

            if (playlist == null)
            {
                // Create a new, private playlist in the authorized user's channel
                playlist = new Playlist
                {
                    Snippet = new PlaylistSnippet
                    {
                        Title       = chart.PlaylistName,
                        Description = $"Source: {chart.Url}\n\nPlaylist created with the YouTube Playlist Builder https://github.com/RDultsin/YouTubePlaylistBuilder"
                    },
                    Status = new PlaylistStatus
                    {
                        PrivacyStatus = "public"
                    }
                };
                playlist = await youTubeService.Playlists.Insert(playlist, "snippet,status").ExecuteAsync();

                Debug.WriteLine("Created playlist {0}", (object)playlist.Snippet.Title);
            }
            else
            {
                // Update title of playlist
                playlist.Snippet.Title       = chart.PlaylistName;
                playlist.Snippet.Description = $"Source: {chart.Url}\n\nPlaylist updated with the YouTube Playlist Builder https://github.com/RDultsin/YouTubePlaylistBuilder";
                playlist = await youTubeService.Playlists.Update(playlist, "snippet").ExecuteAsync();

                Debug.WriteLine("Updated playlist {0}", (object)playlist.Snippet.Title);

                // Remove all videos from playlist
                PlaylistItemsResource.ListRequest playlistItemReq = youTubeService.PlaylistItems.List("snippet");
                playlistItemReq.PlaylistId = playlist.Id;
                playlistItemReq.MaxResults = 50;
                PlaylistItemListResponse playlistItemResp = await playlistItemReq.ExecuteAsync();

                foreach (PlaylistItem playlistItem in playlistItemResp.Items)
                {
                    await youTubeService.PlaylistItems.Delete(playlistItem.Id).ExecuteAsync();

                    Debug.WriteLine("Removed playlist item {0} from playlist {1}", playlistItem.Snippet.Title, playlist.Snippet.Title);
                }
            }

            // Add a videos to the playlist
            foreach (Song song in chart.Songs)
            {
                PlaylistItem playlistItem = new PlaylistItem
                {
                    Snippet = new PlaylistItemSnippet
                    {
                        PlaylistId = playlist.Id,
                        ResourceId = new ResourceId
                        {
                            Kind    = "youtube#video",
                            VideoId = song.VideoId
                        }
                    }
                };
                playlistItem = await youTubeService.PlaylistItems.Insert(playlistItem, "snippet").ExecuteAsync();

                Debug.WriteLine("Added playlist item {0} to playlist {1}", playlistItem.Snippet.Title, playlist.Snippet.Title);
            }

            return(chart);
        }
Ejemplo n.º 24
0
        private async Task search(IClientServiceRequest request, String searchInfo, bool isNextPage, CancellationToken token)
        {
            SearchListResponse       searchResponse       = null;
            PlaylistItemListResponse playlistItemResponse = null;
            PlaylistListResponse     playlistResponse     = null;

            SearchResource.ListRequest        searchRequest        = request as SearchResource.ListRequest;
            PlaylistItemsResource.ListRequest playlistItemsRequest = request as PlaylistItemsResource.ListRequest;
            PlaylistsResource.ListRequest     playlistRequest      = request as PlaylistsResource.ListRequest;

            List <YoutubeItem> items = new List <YoutubeItem>();
            int relevance;

            if (isNextPage)
            {
                if (NextPageToken == null)
                {
                    // Final page
                    return;
                }

                if (searchRequest != null)
                {
                    searchRequest.PageToken = NextPageToken;
                }
                else if (playlistItemsRequest != null)
                {
                    playlistItemsRequest.PageToken = NextPageToken;
                }
                else if (playlistRequest != null)
                {
                    playlistRequest.PageToken = NextPageToken;
                }

                relevance = MediaState.UIMediaCollection.Count;
            }
            else
            {
                MediaState.clearUIState(searchInfo, DateTime.Now, MediaStateType.SearchResult);

                CurrentQuery = request;
                relevance    = 0;
            }

            // Call the search.list method to retrieve results matching the specified query term.
            if (searchRequest != null)
            {
                searchResponse = await searchRequest.ExecuteAsync(token);

                NextPageToken = searchResponse.NextPageToken;

                foreach (SearchResult searchResult in searchResponse.Items)
                {
                    YoutubeItem newItem = null;

                    switch (searchResult.Id.Kind)
                    {
                    case "youtube#video":
                        newItem = new YoutubeVideoItem(searchResult, relevance);
                        break;

                    case "youtube#channel":
                        newItem = new YoutubeChannelItem(searchResult, relevance);
                        break;

                    case "youtube#playlist":
                        newItem = new YoutubePlaylistItem(searchResult, relevance);
                        break;

                    default:
                        break;
                    }

                    if (newItem == null || MediaState.UIMediaCollection.Contains(newItem))
                    {
                        continue;
                    }

                    items.Add(newItem);

                    relevance++;
                }
            }

            if (playlistItemsRequest != null)
            {
                playlistItemResponse = await playlistItemsRequest.ExecuteAsync(token);

                NextPageToken = playlistItemResponse.NextPageToken;

                foreach (PlaylistItem playlistItem in playlistItemResponse.Items)
                {
                    YoutubeVideoItem newItem = new YoutubeVideoItem(playlistItem, relevance);

                    items.Add(newItem);

                    relevance++;
                }
            }

            if (playlistRequest != null)
            {
                playlistResponse = await playlistRequest.ExecuteAsync(token);

                NextPageToken = playlistResponse.NextPageToken;

                foreach (Playlist playlist in playlistResponse.Items)
                {
                    YoutubePlaylistItem newItem = new YoutubePlaylistItem(playlist, relevance);

                    if (!items.Contains(newItem))
                    {
                        items.Add(newItem);
                    }

                    relevance++;
                }
            }

            // Add each result to the appropriate list, and then display the lists of
            // matching videos, channels, and playlists.
            MediaState.addUIState(items);
        }