【问题标题】:retrieve the duration of each of my youtube videos using C# .NET and the YouTube Data API v3使用 C# .NET 和 YouTube Data API v3 检索我的每个 youtube 视频的持续时间
【发布时间】:2017-12-01 02:50:57
【问题描述】:

是否可以使用 C# .NET 和 YouTube Data API v3(不是 JavaScript 或任何其他客户端语言)获取我的每个 YouTube 视频的时长?

我已经搜索了好几天,唯一想到的是谷歌在他们的.NET Code Samples page 上的例子,它只显示了如何获取一个 playlistItems.list。但是,这并没有为我提供来自 contentDetails 的视频列表及其相关时长。

请帮我解决这个问题。 谢谢大家。

【问题讨论】:

  • 看起来你可以通过获取videos 并检查contentDetails.duration 属性来做到这一点。
  • 感谢您的快速回复@adrianbanks,但我能够接近抓取视频对象的唯一方法是抓取不包含持续时间属性的 playlist.item 对象。是否有任何代码示例可以告诉我如何使用 C# .Net 获取实际的视频对象?
  • 您是否使用过 Google.Apis.YouTube.v3 客户端库

标签: c# .net video youtube-api youtube-data-api


【解决方案1】:

遇到过类似情况,我需要更新所有上传内容的说明。在这里查看隐藏的宝石:https://github.com/youtube/api-samples/tree/master/dotnet

Google.Apis.YouTube.Samples.UpdateVideos 项目中,您会发现一个循环,您可以稍微修改并使用它来获取每个视频的持续时间。

foreach (var channel in channelsListResponse.Items)
{
    var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;

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

    var nextPageToken = "";
    while (nextPageToken != null)
    {
        var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
        playlistItemsListRequest.PlaylistId = uploadsListId;
        playlistItemsListRequest.MaxResults = 50;
        playlistItemsListRequest.PageToken = nextPageToken;

        // Retrieve the list of videos uploaded to the authenticated user's channel.
        var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();

        foreach (var playlistItem in playlistItemsListResponse.Items)
        {
            var videoRequest = youtubeService.Videos.List("snippet");
            videoRequest.Id = playlistItem.Snippet.ResourceId.VideoId;
            videoRequest.MaxResults = 1;
            var videoItemRequestResponse = await videoRequest.ExecuteAsync();

            // Get the videoID of the first video in the list
            var video = videoItemRequestResponse.Items[0];
            var duration = video.ContentDetails.Duration;
        }

        nextPageToken = playlistItemsListResponse.NextPageToken;
    }
}

【讨论】:

  • 感谢您的回答@Janis。在研究它时,我确实提出了类似的解决方案。但是,我注意到一个性能问题。我有 22 个视频要访问并使用这种技术,我对 YouTube API 进行了 23 次调用(一个是为了获取 playlistItemsListResponse 对象,另一个是 22 个调用(一个用于最后一个 foreach 循环中的每个视频)。为了解决这个问题,我工作了出两个调用过程。我首先调用 playlistItemsListRequest 以获取播放列表的集合,然后调用 videoRequest 以从播放列表中获取视频列表,我遍历该列表以获取持续时间。
【解决方案2】:

好的,这就是我最终如何解决此问题的说明。

我希望使用 YouTube 数据 API 实现的目标是根据用户名或频道 ID 从任何 YouTube 频道检索视频列表。

理想情况下,我们应该能够向 YouTube 索要来自特定 YouTube 频道的所有视频。但是,它似乎不是那样工作的。 最终,我们需要向 YouTubeService.Videos.List 方法发送视频列表请求。这将允许我们检索视频对象列表的内容详细信息、sn-p 和统计信息。但是,此方法需要几个参数。一个是 VideoListRequest.ID 参数,它是您希望检索的视频集合中的视频 ID 的字符串数组。另一个是 VideoListRequest.MaxResults 参数。这将是您希望拉回的视频的最大数量。

要检索视频 ID 列表,我们需要再次调用 YouTube API 并从 YouTubeService.PlaylistItems.List 方法检索播放列表项列表。但是,此方法需要 UploadsListID,该 ID 必须通过对 YouTube API 的 YouTubeService.Channels.List 方法的另一次调用来获取。

因此,我们需要对 YouTube API 进行 3 次调用,如下图所示。

第一步是根据用户名或频道 ID 获取频道列表。 UploadsListId 将来自 ChannelListResponse:channelListResponse.Items[0].ContentDetails.RelatedPlaylists.Uploads。

第二步是使用上一步中的 UploadsListID 获取播放列表项的列表。这使我们可以检索上传的视频播放列表中每个视频的视频 ID,并将它们放入字符串列表中。

最后,第三步是根据前面的字符串列表中的视频 ID 获取视频列表。通过这个响应,我们可以检索每个视频的时长,并将 YouTube 的 HMS 格式转换为“可用的”Timespan 格式字符串 (h:mm:ss)。

这是我用来完成上述描述的代码:

    public async Task<List<Video>> GetVideoListAsync(ChannelListMethod Method, string MethodValue, int? MaxVideos)
    {
        // Define variables needed for this method
        List<string> videoIdList = new List<string>();
        List<Video> videoList = new List<Video>();
        string uploadsListId = null;

        // Make sure values passed into the method are not null or empty.
        if (MaxVideos == null)
        {
            throw new ArgumentNullException(nameof(MaxVideos));
        }

        if (string.IsNullOrEmpty(MethodValue))
        {
            return videoList;
        }

        // Create the service.
        using (YouTubeService youtubeService = new YouTubeService(new BaseClientService.Initializer
        {
            ApiKey = _apiKey,
            ApplicationName = _appName
        }))
        {
            // Step ONE is to get a list of channels for a specified YouTube user or ChannelID.
            // Create the FIRST Request object to get a list of YouTube Channels and get their contentDetails
            // based on either ForUserName or ChannelID.
            ChannelsResource.ListRequest channelsListRequest = youtubeService.Channels.List("contentDetails");
            if (Method == ChannelListMethod.ForUserName)
            {
                // Build the ChannelListRequest using UserName
                channelsListRequest.ForUsername = MethodValue;
            }
            else
            {
                // Build the ChannelListRequest using ChannelID
                channelsListRequest.Id = MethodValue;
            }

            // This is the FIRST Request to the YouTube API.
            // Retrieve the contentDetails part of the channel resource to get a list of channel IDs.
            // We are only interested in the Uploads playlist of the first channel.
            try
            {
                ChannelListResponse channelsListResponse = await channelsListRequest.ExecuteAsync();
                uploadsListId = channelsListResponse.Items[0].ContentDetails.RelatedPlaylists.Uploads;
            }
            catch (Exception ex)
            {
                ErrorException = ex;
                return videoList;
            }

            // Step TWO is to get a list of playlist items from the Uploads playlist.
            // From the API response, use the Uploads playlist ID (uploadsListId) to be used to get list of videos
            // from the videos uploaded to the user's channel.
            string nextPageToken = "";
            while (nextPageToken != null)
            {
                // Create the SECOND Request object for requestring a list of Playlist items
                // from the channel's Uploads playlist.
                // Limit the list to maxVideos items and continue to iterate through the pages.
                PlaylistItemsResource.ListRequest playlistItemsListRequest = youtubeService.PlaylistItems.List("contentDetails");
                playlistItemsListRequest.PlaylistId = uploadsListId;
                playlistItemsListRequest.MaxResults = MaxVideos;
                playlistItemsListRequest.PageToken = nextPageToken;

                // This is the SECOND Request to YouTube and get a Response object containing
                // the playlist items in the channel's Uploads playlist.
                // Then iterate through the Response items to build a string list of the video IDs
                try
                {
                    PlaylistItemListResponse playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
                    foreach (PlaylistItem playlistItem in playlistItemsListResponse.Items)
                    {
                        videoIdList.Add(playlistItem.ContentDetails.VideoId.ToString());
                    }
                }
                catch (Exception ex)
                {
                    ErrorException = ex;
                    return videoList;
                }

                // Now that we have a collection (string array) of video IDs,
                // Step THREE is to retrieve the snippet, contentDetails, and statistics parts of the 
                // list of videos uploaded to the authenticated user's channel.
                try
                {
                    // Create the THIRD Request object for requestring a list of videos and their associated metadata.
                    var VideoListRequest = youtubeService.Videos.List("snippet, contentDetails, statistics");
                    // The next line converts the list of video Ids to a comma seperated string array of the video IDs
                    VideoListRequest.Id = String.Join(",", videoIdList);
                    VideoListRequest.MaxResults = MaxVideos;

                    var VideoListResponse = await VideoListRequest.ExecuteAsync();

                    // This is the THIRD Request to the YouTube API to get a Response object
                    // containing Collect each Video duration and convert to a usable time format.
                    foreach (var video in VideoListResponse.Items)
                    {
                        video.ContentDetails.Duration = HMSToTimeSpan(video.ContentDetails.Duration).ToString();
                        videoList.Add(video);
                    }

                    // request next page
                    nextPageToken = VideoListResponse.NextPageToken;
                }
                catch (Exception ex)
                {
                    ErrorException = ex;
                    return videoList;
                }
            }
            return videoList;
        }
    }

我知道这不是完美的解决方案,或者也许是“最好的”解决方案,但我希望这可以帮助其他人解决同样的问题。

感谢您的所有帮助@Janis S

【讨论】:

    猜你喜欢
    • 2015-08-24
    • 2014-08-15
    • 2018-06-28
    • 2013-04-20
    • 2020-01-21
    • 2015-07-22
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    相关资源
    最近更新 更多