如何将代码 YouTube API 从控制台转换为 WPF [关闭]
Posted
技术标签:
【中文标题】如何将代码 YouTube API 从控制台转换为 WPF [关闭]【英文标题】:How to convert code YouTube API from Console to WPF [closed] 【发布时间】:2021-11-17 20:05:12 【问题描述】:我的代码在控制台中运行良好,但我尝试将其转换为 WPF c#,但没有成功。 我尝试将每个部分移植到 WPF,当我将其转换为 WPF 时,我发现了下面的代码(我在下面引用的第二个代码)它不起作用 请帮我。如何在 WPF c# 中正常工作 这是我的代码:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; using Google.Apis.Services; using Google.Apis.Upload; using Google.Apis.Util.Store; using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; namespace ConsoleApp2 internal class PlaylistUpdates public string PrivacyStatus get; private set; [STAThread] static void Main(string[] args) Console.WriteLine("YouTube Data API: Playlist Updates"); Console.WriteLine("=================================="); try //new PlaylistUpdates().Run().Wait(); //new PlaylistUpdates().RunUpload().Wait(); new PlaylistUpdates().Editvideo().Wait(); catch (AggregateException ex) foreach (var e in ex.InnerExceptions) Console.WriteLine("Error: " + e.Message); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); private async Task Editvideo() UserCredential credential; using (var 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 read-only access to the authenticated // user's account, but not other types of account access. new[] YouTubeService.Scope.YoutubeReadonly , "user", CancellationToken.None, new FileDataStore(this.GetType().ToString()) ); var youtubeService = new YouTubeService(new BaseClientService.Initializer() HttpClientInitializer = credential, ApplicationName = this.GetType().ToString() ); var channelsListRequest = youtubeService.Channels.List("contentDetails"); channelsListRequest.Mine = true; // Retrieve the contentDetails part of the channel resource for the authenticated user's channel. var channelsListResponse = await channelsListRequest.ExecuteAsync(); foreach (var channel in channelsListResponse.Items) // From the API response, extract the playlist ID that identifies the list // of videos uploaded to the authenticated user's channel. var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads; Console.WriteLine("Videos in list 0", uploadsListId); var nextPageToken = ""; while (nextPageToken != null) var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet,status"); playlistItemsListRequest.PlaylistId = uploadsListId; playlistItemsListRequest.MaxResults = 50; playlistItemsListRequest.PageToken = nextPageToken; // Create a new, private playlist in the authorized user's channel. var newVideo = new Video(); newVideo.Snippet = new VideoSnippet(); newVideo.Id = "6obQQde1X3A"; newVideo.Snippet.Title = "My Title"; newVideo.Snippet.Description = "My Description"; newVideo.Snippet.Tags = new string[] "tag 1", "tag 2", "tag 3" ; newVideo.Snippet.CategoryId = "22"; newVideo.Status = new VideoStatus(); newVideo.Status.PrivacyStatus = "public"; newVideo = await youtubeService.Videos.Update(newVideo,"Id,snippet,status").ExecuteAsync(); Console.WriteLine("Change video details OK ...."); // Retrieve the list of videos uploaded to the authenticated user's channel. var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync(); foreach (var playlistItem in playlistItemsListResponse.Items) Console.WriteLine("0 (1)", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId); nextPageToken = playlistItemsListResponse.NextPageToken;
如果我在下面删除此代码。效果很好!
// Create a new, private playlist in the authorized user's channel.
var newVideo = new Video();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
newVideo.Snippet.Title = "My Title";
newVideo.Snippet.Description = "My Description";
newVideo.Snippet.Tags = new string[] "tag 1", "tag 2", "tag 3" ;
newVideo.Snippet.CategoryId = "22";
newVideo.Status = new VideoStatus();
newVideo.Status.PrivacyStatus = "public";
newVideo = await youtubeService.Videos.Update(newVideo,"Id,snippet,status").ExecuteAsync();
Console.WriteLine("Change video details OK ....");
这是我在 WPF 中的代码
private async Task Change_VideoDetails()
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] YouTubeService.Scope.YoutubeReadonly ,
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
);
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Mine = true;
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
// From the API response, extract the playlist ID that identifies the list
// of videos uploaded to the authenticated user's channel.
var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;
//Console.WriteLine("Videos in list 0", uploadsListId);
var nextPageToken = "";
while (nextPageToken != null)
var playlistItemsListRequest = youtubeService.PlaylistItems.List("Id,snippet,status");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
var newVideo = new Video();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
txtLog.AppendText("\nWill change video details....." + newVideo.Id + );
txtLog.ScrollToEnd();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
newVideo.Snippet.Title = "My Title";
newVideo.Snippet.Description = "My Description";
newVideo.Snippet.Tags = new string[] "tag 1", "tag 2", "tag 3" ;
newVideo.Snippet.CategoryId = "22";
newVideo.Status = new VideoStatus();
newVideo.Status.PrivacyStatus = "public";
newVideo = await youtubeService.Videos.Update(newVideo, "Id,snippet,status").ExecuteAsync();
txtLog.AppendText("\nChanged video details ....." + newVideo.Id);
txtLog.ScrollToEnd();
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
int line_count=0;
foreach (var playlistItem in playlistItemsListResponse.Items)
line_count += 1;
if (line_count == int.Parse(txtVideonumber.Text))
break;
//
nextPageToken = playlistItemsListResponse.NextPageToken;
我使用下面的代码来运行上面的代码:
private void BtnChange_Click(object sender, RoutedEventArgs e)
Change_VideoDetails();
我尝试运行调试器,但我的代码在以下代码处停止:
newVideo = await youtubeService.Videos.Update(newVideo, "Id,snippet,status").ExecuteAsync();
我不明白为什么它会停止?请帮我解决一下
【问题讨论】:
请您扩展“不起作用” - 有什么问题?有编译错误吗? 我没有收到编译器错误。我只是没有看到这段代码的执行:var newVideo = new Video(); newVideo.Snippet = new VideoSnippet(); newVideo.Id = "6obQQde1X3A"; newVideo.Snippet.Title = "My Title"; ... Console.WriteLine("Change video details OK ....");
非常感谢。
wpf 代码在哪里?您询问了您的 wpf 代码不起作用但仅发布了控制台应用程序。
您应该运行调试器以查看执行在哪一行停止 - 如果它停止。
我的问题已被编辑。请检查它帮助我。感谢任何想法来解决我的问题
【参考方案1】:
你必须await
一个异步方法,即await
Task
结果:
// Since this is an event handler 'async void' is allowed.
// Otherwise you must use 'async Task' or 'async Task<T>'
private async void BtnChange_Click(object sender, RoutedEventArgs e)
await Change_VideoDetails();
等待Task
对于允许正确的异常处理/行为很重要。如果你不 await
a Task
那么异常将不会正确传播 - 异常将被吞没。这是因为在async
方法中,异常被捕获并放置在Task
对象上。当您 await
Task
时,您允许执行传播到调用者的上下文以最终保存您的应用程序或在 catch
块中处理。
对于无法访问您的环境(包括 Youtube 帐户和身份验证配置)的人来说,您的问题很难解决。
首先确保您的调试器将通过至少启用所有 CLR 异常来中断所有异常:在主菜单中选择 Debug/Windows/Exception Setting 并检查 “Common Language Runtime例外” 复选框。
如果调试器仍然没有抛出异常,则删除ExecuteAsync()
以同步执行操作。这样您就可以测试是否遇到死锁。说到 async/await,您必须知道控制台应用程序、Asp.Net 和 Winforms/Wpf/UWP 在某些方面具有不同的行为。
【讨论】:
我已经解决了我的问题。感谢您对使用 async 和 await 的建议。我查看了 YouTube API 文档,发现问题出在以下代码中:new[] YouTubeService.Scope.YoutubeReadonly ,
。我已将 Scope.
从 YoutubeReadonly
更改为 Youtubepartner
并且效果很好。非常感谢以上是关于如何将代码 YouTube API 从控制台转换为 WPF [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何读取从 Youtube API Kotlin/Java 返回的视频的持续时间
将 jquery .getJSON 转换为 ajax 异步等待 YouTube API