使用mvc应用程序将视频上传到youtube(所有代码都在后面)

问题描述 投票:0回答:2

这太疯狂了,我花了一周时间试图解决这个问题。我发现的所有内容要么已弃用,要么不起作用。

这就是我正在尝试做的事情。我们让用户上传视频,我们会存储视频直到获得批准。一旦获得批准,我们需要将其上传到我们的 YouTube 频道。

来自谷歌的示例:https://developers.google.com/youtube/v3/code_samples/dotnet#retrieve_my_uploads不会通过GoogleWebAuthorizationBroker.AuthorizeAsync,因为它永远挂起。

这种方法的另一个问题是,我们需要视频上传后的id,并且我们需要知道视频是否上传成功,所有这些都是同步的。通过查看它使用异步方法的代码,您会发现它有一个回调来获取视频的 id。

有人知道如何在 mvc 应用程序后端同步上传视频吗?

c# asp.net-mvc youtube-data-api
2个回答
14
投票

好吧,我遇到的第一个问题是身份验证挂起(从 GoogleWebAuthorizationBroker.AuthorizeAsync 获取凭据)。解决这个问题的方法是使用 GoogleAuthorizationCodeFlow,它不是异步的,并且不会尝试在 appdata 文件夹中保存任何内容。

我需要获取刷新令牌,为此我遵循: 使用 OAuth 的 Youtube API 单用户场景(上传视频)

要获取可多次使用的刷新令牌,您必须获取已安装应用程序的客户端 ID 和密钥。

证书是最困难的部分,之后一切就都好了。但需要注意一件事,因为我花了几个小时试图找出上传视频时的 CategoryId 是什么。我似乎找不到任何关于示例代码在哪里得到“22”的真正解释。我发现 22 是默认值,意思是“人物和博客”。

这是我的代码,供任何需要它的人使用(我还需要能够删除 YouTube 视频,所以我已将其添加到此处):

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[] tags, String categoryId, Boolean isPublic)
    {
        var video = new Video();
        video.Snippet = new VideoSnippet();
        video.Snippet.Title = title;
        video.Snippet.Description = desc;
        video.Snippet.Tags = tags;
        video.Snippet.CategoryId = categoryId; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
        video.Status = new VideoStatus();
        video.Status.PrivacyStatus = isPublic ? "public" : "private"; // "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;
    }

    public void DeleteVideo(String videoId)
    {
        var videoDeleteRequest = youtube.Videos.Delete(videoId);
        videoDeleteRequest.Execute();
    }

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

我还没有尝试过,但据我了解,ApplicatioName 可以是你想要的任何名称。我只是在测试,这是我在 youtube 上的项目名称,用于客户端 ID 和秘密,但我认为你可以输入任何内容?


0
投票

这段代码在 2023 年可以完美运行,唯一改变的是秘密类型。 现在你应该使用 OAuth 2.0 的 Web 客户端类型(如果你想要简单的软件上传视频),这样你就可以通过 Playground/rest 生成刷新令牌

© www.soinside.com 2019 - 2024. All rights reserved.