如何使用Google.Apis.YouTube.v3和C#将video上传到youtube?

我用C#创建了console应用程序。 这将把Video从本地驱动器uploadyoutube 。 我使用此链接在google api中创建了新应用。 我还使用nuget安装了所有必需的packages 。 当我运行我的应用程序时,我收到错误“ 访问被拒绝 ”我无法找到问题。

我在Task Run()方法中遇到错误。

 using System; using System.IO; 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 Google.Apis.YouTube.Samples { ///  /// YouTube Data API v3 sample: create a playlist. /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher. /// See https://developers.google.com/api-client-library/dotnet/get_started ///  internal class PlaylistUpdates { [STAThread] static void Main(string[] args) { Console.WriteLine("YouTube Data API: Playlist Updates"); Console.WriteLine("=================================="); try { new PlaylistUpdates().Run().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 Run() { 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 full read/write access to the // authenticated user's account. new[] { YouTubeService.Scope.Youtube }, "user", CancellationToken.None, new FileDataStore(this.GetType().ToString()) ); } var youtubeService = new YouTubeService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = this.GetType().ToString() }); // Create a new, private playlist in the authorized user's channel. var newPlaylist = new Playlist(); newPlaylist.Snippet = new PlaylistSnippet(); newPlaylist.Snippet.Title = "Test Playlist"; newPlaylist.Snippet.Description = "A playlist created with the YouTube API v3"; newPlaylist.Status = new PlaylistStatus(); newPlaylist.Status.PrivacyStatus = "public"; newPlaylist = await youtubeService.Playlists.Insert(newPlaylist, "snippet,status").ExecuteAsync(); // Add a video to the newly created playlist. var newPlaylistItem = new PlaylistItem(); newPlaylistItem.Snippet = new PlaylistItemSnippet(); newPlaylistItem.Snippet.PlaylistId = newPlaylist.Id; newPlaylistItem.Snippet.ResourceId = new ResourceId(); newPlaylistItem.Snippet.ResourceId.Kind = "youtube#video"; newPlaylistItem.Snippet.ResourceId.VideoId = "GNRMeaz6QRI"; newPlaylistItem = await youtubeService.PlaylistItems.Insert(newPlaylistItem, "snippet").ExecuteAsync(); Console.WriteLine("Playlist item id {0} was added to playlist id {1}.", newPlaylistItem.Id, newPlaylist.Id); } } } 

我是否需要将’user’参数传递给gmail用户名?

任何使用C#(控制台/网络)的工作示例?

帮助感谢。

所有归功于@iedoc的代码和答案

一个基本的工作Web项目示例

Default.aspx的

 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>    testing   

Default.aspx.cs

 using System; using System.IO; 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; using Google.Apis.Auth.OAuth2.Flows; using Google.Apis.Auth.OAuth2.Responses; public partial class _Default : System.Web.UI.Page { string vID = "none"; public void Page_Load(object sender, EventArgs e) { } protected void saveDetails_click(object sender, EventArgs e) { if (Path.GetFileName(videoUpload.PostedFile.FileName) != "") { YouTubeUtilities ytU = new YouTubeUtilities("REFRESH", "SECRET", "CLIENT_ID"); // pass in your API codes here using (var fileStream = videoUpload.PostedFile.InputStream) // the selected post file { vID = ytU.UploadVideo(fileStream,videoName.Text,videoDesc.Text,"22",false); } Response.Write(vID); } } } public class YouTubeUtilities { /* Instructions to get refresh token: * https://stackoverflow.com/questions/5850287/youtube-api-single-user-scenario-with-oauth-uploading-videos/8876027#8876027 * * When getting client_id and client_secret, use installed application, other (this will make the token a long term token) */ private String CLIENT_ID { get; set; } private String CLIENT_SECRET { get; set; } private String REFRESH_TOKEN { get; set; } private String UploadedVideoId { get; set; } private YouTubeService youtube; public YouTubeUtilities(String refresh_token, String client_secret, String client_id) { CLIENT_ID = client_id; CLIENT_SECRET = client_secret; REFRESH_TOKEN = refresh_token; youtube = BuildService(); } private YouTubeService BuildService() { ClientSecrets secrets = new ClientSecrets() { ClientId = CLIENT_ID, ClientSecret = CLIENT_SECRET }; var token = new TokenResponse { RefreshToken = REFRESH_TOKEN }; var credentials = new UserCredential(new GoogleAuthorizationCodeFlow( new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = secrets }), "user", token); var service = new YouTubeService(new BaseClientService.Initializer() { HttpClientInitializer = credentials, ApplicationName = "TestProject" }); //service.HttpClient.Timeout = TimeSpan.FromSeconds(360); // Choose a timeout to your liking return service; } public String UploadVideo(Stream stream, String title, String desc, String categoryId, Boolean isPublic) { var video = new Video(); video.Snippet = new VideoSnippet(); video.Snippet.Title = title; video.Snippet.Description = desc; video.Snippet.CategoryId = categoryId; // See https://developers.google.com/youtube/v3/docs/videoCategories/list video.Status = new VideoStatus(); video.Status.PrivacyStatus = isPublic ? "public" : "unlisted"; // "private" or "public" or unlisted //var videosInsertRequest = youtube.Videos.Insert(video, "snippet,status", stream, "video/*"); var videosInsertRequest = youtube.Videos.Insert(video, "snippet,status", stream, "video/*"); videosInsertRequest.ProgressChanged += insertRequest_ProgressChanged; videosInsertRequest.ResponseReceived += insertRequest_ResponseReceived; videosInsertRequest.Upload(); return UploadedVideoId; } void insertRequest_ResponseReceived(Video video) { UploadedVideoId = video.Id; // video.ID gives you the ID of the Youtube video. // you can access the video from // http://www.youtube.com/watch?v={video.ID} } void insertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress) { // You can handle several status messages here. switch (progress.Status) { case UploadStatus.Failed: UploadedVideoId = "FAILED"; break; case UploadStatus.Completed: break; default: break; } } } 

我讨厌.NET而且我已经和它斗争了好几个星期。 我遇到的一些问题;

  1. 一对错误的API密钥,它们只是不起作用。 我猜这是一个随机的bug。
  2. 我还有一些我从Youtube下载的MP4,它不会上传,在创作工作室中他们会说“上传失败:无法处理文件”我通过尝试在youTube界面上传它们来确定这一点。 (不是通过API)
  3. 异步与同步导致我很多问题,我只是不明白。

我想改进此代码以提供实际的上传状态/反馈,但我认为需要在客户端完成。 我不是很擅长C#/ .NET

这里更新是我通过服务器和客户端的反馈代码 – https://stackoverflow.com/a/49516167/3790921

我对您的代码进行了一些小的更改,最好先让Oauth2的初始示例工作。 很难说你为何拒绝接入。 这是我改变了。

  1. “user”我已经更改为Environment.UserName,这样您的凭据名称将是当前登录用户的名称。
  2. 我已经更改了FileDataStore的位置我并不确定您使用的代码是否正常工作。 我将把凭证存储在当前工作目录的新目录中。

有关用户参数的信息,它仅用于在提交给FileDataStore的目录中创建凭据。

Google.Apis.Auth.OAuth2.Responses.TokenResponse-lilaw

我的登录用户名是lilaw ,您可以通过这种方式为每个用户提供凭据文件。 因为这是一个无关紧要的控制台应用程序。

你应该检查一下,如果这不是开箱即用的:

  1. 在Google开发者控制台上创建客户端时,请确保它是其他类型。 您无法使用具有浏览器凭据的控制台应用程序,并且您无法将YouTube API与服务帐户一起使用。
  2. 请记住,基于YouTube API频道,因此当您登录时选择一个频道,您将只能访问该频道。

提示:如果要注销当前用户或强制它再次登录。 只需将Environment.UserName更改为其他内容,它将强制它再次登录

我测试了它的代码:

 using Google.Apis.Auth.OAuth2; using Google.Apis.Services; using Google.Apis.Util.Store; using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace TestYoutube { class Program { [STAThread] static void Main(string[] args) { Console.WriteLine("YouTube Data API: Playlist Updates"); Console.WriteLine("=================================="); try { new Program().Run().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 Run() { 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.Youtube }, Environment.UserName, CancellationToken.None, new FileDataStore($"{Directory.GetCurrentDirectory()}/credentials") ); } var youtubeService = new YouTubeService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = this.GetType().ToString() }); // Create a new, private playlist in the authorized user's channel. var newPlaylist = new Playlist { Snippet = new PlaylistSnippet { Title = "Test Playlist", Description = "A playlist created with the YouTube API v3" }, Status = new PlaylistStatus {PrivacyStatus = "public"} }; newPlaylist = await youtubeService.Playlists.Insert(newPlaylist, "snippet,status").ExecuteAsync(); // Add a video to the newly created playlist. var newPlaylistItem = new PlaylistItem { Snippet = new PlaylistItemSnippet { PlaylistId = newPlaylist.Id, ResourceId = new ResourceId { Kind = "youtube#video", VideoId = "GNRMeaz6QRI" } } }; newPlaylistItem = await youtubeService.PlaylistItems.Insert(newPlaylistItem, "snippet").ExecuteAsync(); Console.WriteLine("Playlist item id {0} was added to playlist id {1}.", newPlaylistItem.Id, newPlaylist.Id); } } } 

一旦你有了这个工作,这里有几个例子,一个用于上传video

以下代码示例调用API的playlistItems.list方法以检索上载到与请求关联的通道的video列表。 该代码还调用channels.list方法,将mine参数设置为true,以检索标识频道上传video的播放列表ID。

 using System; using System.IO; 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 Google.Apis.YouTube.Samples { ///  /// YouTube Data API v3 sample: retrieve my uploads. /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher. /// See https://developers.google.com/api-client-library/dotnet/get_started ///  internal class MyUploads { [STAThread] static void Main(string[] args) { Console.WriteLine("YouTube Data API: My Uploads"); Console.WriteLine("============================"); try { new MyUploads().Run().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 Run() { 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"); 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) { // Print information about each video. Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId); } nextPageToken = playlistItemsListResponse.NextPageToken; } } } } }