2

我正在尝试使用 oauth2 和 youtube dotnet 库上传隐藏式字幕。这些示例不包括 .NET,我知道这是新的(即 API 中很少使用的功能)。我在这个问题上大发雷霆,不知道我是否遗漏了什么,或者 API 中是否存在错误。请帮忙!

我得到的错误是: BytesSent: 0 Exception: {"Value cannot be null.\r\nParameter name: baseUri"} Status: Failed

我的代码适用于上传视频,但在上传 CAPTION 时出现上述错误。

这是包含有效视频上传和损坏的字幕上传的代码。

// THIS ONE WORKS !!!!
        private void cmdUploadVideo_Click(object sender, EventArgs e)
    {
        YouTubeService youtubeService = getYouTubeService();

        Video newVideo = new Video();
        newVideo.Snippet = new VideoSnippet();
        newVideo.Snippet.Title = "Learning YouTube API 2";
        newVideo.Snippet.Description = "Description of video";
        newVideo.Snippet.Tags = new string[] { "tag1", "tag2" };
        newVideo.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
        newVideo.Status = new VideoStatus();
        newVideo.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
        var filePath = @"c:\\_IM\\TestVideo.mp4"; 

        using (var fileStream = new FileStream(filePath, FileMode.Open))
        {
            VideosResource.InsertMediaUpload videosInsertRequest = youtubeService.Videos.Insert(newVideo, "snippet,status", fileStream, "video/*");
            IUploadProgress results = videosInsertRequest.Upload();
        }
    }

// HELP PLEASE!!! VERY SIMILAR STRUCTURE BUT GETS ERROR
    private void cmdUploadVideoCaption_Click(object sender, EventArgs e)
    {
        YouTubeService youtubeService = getYouTubeService();

        Caption newCaption = new Caption();
        newCaption.Snippet = new CaptionSnippet();
        newCaption.Snippet.Name = "test";
        newCaption.Snippet.Language = "en";
        newCaption.Snippet.VideoId = txtVideoID.Text;
        var filePath = @"c:\\_IM\\captions.txt"; // Replace with path to actual movie file.

        using (var fileStream = new FileStream(filePath, FileMode.Open))
        {
            CaptionsResource.InsertMediaUpload captionInsertRequest = youtubeService.Captions.Insert(newCaption, "snippet,status", fileStream, "*/*");
            captionInsertRequest.Sync = true;
            IUploadProgress result = captionInsertRequest.Upload();
// HELP WITH LINE ABOVE ... THAT IS WHERE THE ERROR OCCURS
        }
    }

// THIS PART WORKS !!!! IT IS USED BY BOTH, OAUTH2
    private YouTubeService getYouTubeService()
    {
        UserCredential credential;
        using (FileStream stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
        {
            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                new[] { YouTubeService.Scope.Youtube, YouTubeService.Scope.YoutubeUpload, YouTubeService.Scope.YoutubeForceSsl },
                "user",
                CancellationToken.None,
                new FileDataStore("YouTube.Auth.Store")).Result;
        }

        YouTubeService youtubeService = new YouTubeService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
        });

        return youtubeService;
    }

这是上面代码的错误输出:

?result
{Google.Apis.Upload.ResumableUpload<Google.Apis.YouTube.v3.Data.Caption>.ResumableUploadProgress}
    [Google.Apis.Upload.ResumableUpload<Google.Apis.YouTube.v3.Data.Caption>.ResumableUploadProgress]: {Google.Apis.Upload.ResumableUpload<Google.Apis.YouTube.v3.Data.Caption>.ResumableUploadProgress}
    BytesSent: 0
    Exception: {"Value cannot be null.\r\nParameter name: baseUri"}
    Status: Failed

?result.Exception
{"Value cannot be null.\r\nParameter name: baseUri"}
    [System.ArgumentNullException]: {"Value cannot be null.\r\nParameter name: baseUri"}
    _className: null
    _data: null
    _dynamicMethods: null
    _exceptionMethod: null
    _exceptionMethodString: null
    _helpURL: null
    _HResult: -2147467261
    _innerException: null
    _ipForWatsonBuckets: 1903238454
    _message: "Value cannot be null."
    _remoteStackIndex: 0
    _remoteStackTraceString: null
    _safeSerializationManager: {System.Runtime.Serialization.SafeSerializationManager}
    _source: null
    _stackTrace: {sbyte[96]}
    _stackTraceString: null
    _watsonBuckets: null
    _xcode: -532462766
    _xptrs: 0
    Data: {System.Collections.ListDictionaryInternal}
    HelpLink: null
    HResult: -2147467261
    InnerException: null
    IPForWatsonBuckets: 1903238454
    IsTransient: false
    Message: "Value cannot be null.\r\nParameter name: baseUri"
    RemoteStackTrace: null
    Source: "Microsoft.Threading.Tasks"
    StackTrace: "   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)\r\n   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()\r\n   at Google.Apis.Upload.ResumableUpload`1.<UploadCoreAsync>d__e.MoveNext() in c:\\code\\github\\google-api-dotnet-client\\Tools\\Google.Apis.Release\\bin\\Release\\1.9.2\\default\\Src\\GoogleApis\\Apis\\[Media]\\Upload\\ResumableUpload.cs:line 460"
    TargetSite: {Void ThrowForNonSuccess(System.Threading.Tasks.Task)}
    WatsonBuckets: null

请注意,我尝试将其作为异步任务执行并得到相同的错误,但输出可能会为调试提供更多信息,因为它包含 ResumableUpload 中的行号。这是进行异步调用时的错误输出(代码未显示):

A first chance exception of type 'System.Net.Http.HttpRequestException' occurred in System.Net.Http.dll
A first chance exception of type 'System.Net.Http.HttpRequestException' occurred in Microsoft.Threading.Tasks.dll
An error prevented the upload from completing.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 403 (Forbidden).
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Google.Apis.Upload.ResumableUpload`1.<UploadAsync>d__0.MoveNext() in c:\code\github\google-api-dotnet-client\Tools\Google.Apis.Release\bin\Release\1.9.2\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 378
A first chance exception of type 'System.ArgumentNullException' occurred in System.dll
A first chance exception of type 'System.ArgumentNullException' occurred in Microsoft.Threading.Tasks.dll
An error prevented the upload from completing.
System.ArgumentNullException: Value cannot be null.
Parameter name: baseUri
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Google.Apis.Upload.ResumableUpload`1.<UploadCoreAsync>d__e.MoveNext() in c:\code\github\google-api-dotnet-client\Tools\Google.Apis.Release\bin\Release\1.9.2\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 460

顺便说一句,我在 2015 年 8 月 3 日晚上更新了我的 nuget youtube 库,所以我使用的是我可用的最新代码。

感谢任何可以提供帮助的人!!!!

4

2 回答 2

1

您的代码帮助我解决了我在执行相同任务时遇到的一个单独问题。至于你的错误,我认为它来自

"snippet/status"

Insert() 方法中的参数。似乎 API 需要一个片段和状态对象(您使用 cmdUploadVideo_Click() 方法传递它。以下代码适用于我......

    YouTubeService youtubeService = GetYouTubeService();

    Caption caption = new Caption();
    caption.Snippet = new CaptionSnippet();
    caption.Snippet.Name = "Test Caption";
    caption.Snippet.Language = "en";
    caption.Snippet.VideoId = "videoId";
    caption.Snippet.IsDraft = false;

    var filePath = "{filepath}";
    using (var fileStream = new FileStream(filePath, FileMode.Open))
    {
        CaptionsResource.InsertMediaUpload captionInsertRequest = youtubeService.Captions.Insert(caption, "snippet", fileStream, "*/*");
        captionInsertRequest.Sync = true;
        captionInsertRequest.ProgressChanged += captionInsertRequest_ProgressChanged;
        captionInsertRequest.ResponseReceived += captionInsertRequest_ResponseReceived;
        IUploadProgress result = captionInsertRequest.Upload();
    }

希望这可以帮助。谢谢。

于 2015-10-26T13:57:25.140 回答
0

除了@mpwhitt 提到的内容。确保您的字幕文件 (@"c:\_IM\captions.txt") 正确。只是为了确保您将使用示例标题文件或创建一个示例标题文件的代码:

File.WriteAllText( "example.srt",
@"1
00:00:00.00 --> 00:00:03.00
This is just an example

2
00:00:03.00 --> 00:00:07.00
and we'll see if it works
" );

我看到您根据文档(https://developers.google.com/youtube/v3/docs/captions/insert)设置了您需要的范围(YouTubeService.Scope.YoutubeForceSsl)在我的使用中,我使用了另一个( YouTube 合作伙伴);但两者都应该根据文档工作。

我将 captionInsertRequest.Sync 设置为 false。我认为将其设置为 true 将需要处理。但尽管如此,它不应该在设置为 true 时出错。但是如果它是假的,它应该会成功并立即出现在您的视频中。

于 2015-11-10T20:21:32.000 回答