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

时间:2017-06-16 16:07:37

标签: c# google-api youtube-data-api google-api-dotnet-client google-data-api

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

我在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
{
  /// <summary>
  /// 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
  /// </summary>
  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#(console / web)的任何工作示例?

帮助感谢。

3 个答案:

答案 0 :(得分:5)

所有归功于@iedoc的code and answer here

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

Default.aspx的

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

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>testing</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p><asp:TextBox runat="server" ID="videoName" placeholder="Video Title" /></p>
        <p><asp:TextBox runat="server" ID="videoDesc" placeholder="Video Description" /></p>
        <p><asp:FileUpload ID="videoUpload" runat="server" /></p>
        <p><asp:Button id="saveDetails" Text="Update Chapel Group" runat="server" OnClick="saveDetails_click" /></p>
    </div>
    </form>
</body>
</html>

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密钥,他们只是没有工作。我想这是一个随机的错误。
  2. 我还有一些我从Youtube上下载的不会上传的MP4,在创作工作室中他们会说&#34;上传失败:无法处理文件&#34;我通过尝试在youTube界面上传它们来确定这一点。 (不是通过API)
  3. 异步与同步导致了许多我不理解的问题。
  4. 我想改进此代码以提供实际的上传状态/反馈,但我认为需要在客户端完成。我不是很擅长C#/。NET

    更新这是我的反馈代码,来自服务器&amp;客户方 - https://stackoverflow.com/a/49516167/3790921

答案 1 :(得分:0)

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

  1. &#34;用户&#34;我已更改为Environment.UserName,这样您的凭据名称将是当前登录用户的名称。
  2. 我已经更改了FileDataStore的位置我并不确定您使用的代码是否正常工作。我将把凭证存储在当前工作目录的新目录中。
  3. 有关用户参数的信息,它仅用于在提交给FileDataStore的目录中创建凭据。

      

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

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

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

    1. 在Google开发者控制台上创建客户端时,请确保它是其他类型。您无法使用具有浏览器凭据的控制台应用程序,并且您无法将YouTube API与服务帐户一起使用。
    2. 请注意,基于YouTube API频道,因此当您登录时选择频道,您只能访问该频道。
    3. 提示:如果要注销当前用户或强制它再次登录。只需将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);
              }
          }
      }
      

      一旦你有了这个工作,这里有几个例子,一个是upload video

答案 2 :(得分:-1)

以下代码示例调用API的playlistItems.list方法,以检索上传到与请求关联的频道的视频列表。该代码还调用channels.list方法,将mine参数设置为true,以检索标识频道上传视频的播放列表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
{
  /// <summary>
  /// 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
  /// </summary>
  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;
        }
      }
    }
  }
}