¿Cómo subir un video a youtube usando Google.Apis.YouTube.v3 y C #?

He creado la aplicación de console utilizando C# . Que subirá el Video desde el disco local a youtube . He creado una nueva aplicación en google api usando este enlace . También he instalado todos los packages requeridos usando nuget . Cuando ejecuto mi aplicación, aparece un error como ” Acceso denegado ” No puedo encontrar el problema.

Estoy recibiendo un error en Task Run() método de 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); } } } 

¿Debo pasar el parámetro ‘usuario’ al nombre de usuario de gmail?

¿Algún ejemplo de trabajo usando C # (consola / web)?

Ayuda apreciada.

Todos los créditos a @iedoc por su código y respuesta aquí.

Un ejemplo básico de trabajo de proyecto 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; } } } 

Odio .NET y he estado peleando con esto por semanas. Algunos de los problemas que encontré;

  1. un par de claves API defectuosas, simplemente no funcionaron. Supongo que fue un error aleatorio.
  2. También tengo un par de MP4 que descargué de Youtube que no se volverían a cargar, dentro del estudio del creador dirían “Falló la carga: no se puede procesar el archivo”. Determiné esto al intentar cargarlos en la interfaz de youTube. (no a través de API)
  3. Async vs. sincrónico me estaba causando muchos problemas que simplemente no entiendo.

Me gustaría mejorar este código para proporcionar el estado real de la carga / comentarios, pero creo que debería hacerse desde el lado del cliente. No soy muy bueno en C # / .NET

ACTUALIZACIÓN aquí está mi código de comentarios a través del servidor y del lado del cliente – https://stackoverflow.com/a/49516167/3790921

He realizado algunos cambios menores en su código, es mejor hacer que su ejemplo inicial de Oauth2 funcione primero. Es difícil decir por qué está obteniendo un acceso denegado. Esto es lo que he cambiado.

  1. “usuario” cambié a Environment.UserName de esta manera el nombre de sus credenciales será el nombre del usuario registrado actual.
  2. He cambiado la ubicación de su FileDataStore No estoy tan seguro de que el código que estaba usando iba a funcionar. El mío almacenará las credenciales en un nuevo directorio en el directorio de trabajo actual.

La información sobre el parámetro de usuario solo se utiliza para crear la multa de credenciales en el directorio enviado a FileDataStore.

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

Mi nombre de usuario de inicio de sesión es lilaw de esta manera, puede tener archivos de credenciales para cada usuario. Siendo que esta es una aplicación de consola que no importa mucho.

Lo que debe comprobar si esto no funciona fuera de la caja:

  1. Cuando creó su cliente en la consola de desarrolladores de Google, asegúrese de que sea de otro tipo. No puede usar una aplicación de consola con credenciales de navegador y no puede usar la API de YouTube con una cuenta de servicio.
  2. Recuerde que el canal de la API de YouTube se basa en que, al iniciar sesión, elija un canal, solo tendrá acceso a ese canal.

Sugerencia: si desea cerrar sesión en el usuario actual o forzarlo para que vuelva a iniciar sesión. Simplemente cambie Environment.UserName a otra cosa, lo forzará a iniciar sesión nuevamente

He probado este código funciona:

 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); } } } 

Una vez que tienes ese trabajo, hay varios ejemplos aquí, uno para subir un video

El siguiente ejemplo de código llama al método playlistItems.list de la API para recuperar una lista de videos subidos al canal asociado con la solicitud. El código también llama al método channels.list con el parámetro mine establecido en verdadero para recuperar el ID de la lista de reproducción que identifica los videos subidos del canal.

 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; } } } } }