问题
I'm trying to upload closed captions using oauth2 with the youtube dotnet libraries. The samples don't include .NET and I understand this is new (i.e. lightly used functionality in the API). I'm pulling my hair out on this one and don't know if I'm missing something or if there could be a bug in the API. Please Help!
The error I get is:
BytesSent: 0
Exception: {"Value cannot be null.\r\nParameter name: baseUri"}
Status: Failed
My code WORKS for uploading a VIDEO but gives the error above when uploading a CAPTION.
Here is the code which includes both working VIDEO UPLOAD and broken CAPTION UPLOAD.
// 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;
}
Here is the error output from the code above:
?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
Note, I tried doing this as an async task and get the same error but maybe the output will be more informative for debugging since it includes line numbers in ResumableUpload. Here is the error output when making the async call (code not shown):
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
BTW, I updated my nuget youtube libraries on the evening of Aug 03, 2015 so I'm using the latest code available to me.
Thank you to anyone who can help!!!!
回答1:
Your code helped me solve a separate issue I was having with the same task. As for your error, I think it comes from the
"snippet/status"
parameter in the Insert() method. It seems that the API expects both a snippet and status object (which you are passing with your cmdUploadVideo_Click() method. The following code works for me...
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();
}
Hope this helps. Thanks.
回答2:
In addition to what @mpwhitt mentioned. Be sure your caption file (@"c:\_IM\captions.txt") is correct. Just to be sure will you use an example caption file or this code that creates one:
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
" );
I see you set the scope that you need (YouTubeService.Scope.YoutubeForceSsl) according to the documentation (https://developers.google.com/youtube/v3/docs/captions/insert) In my usage I used the other one (YouTubePartner); but either should work according to documentation.
I set captionInsertRequest.Sync to false. I think with it set to true it'll need to process. But nonetheless it shouldn't error out with it set as true. But with it to false it should both succeed and show up right away in your video.
来源:https://stackoverflow.com/questions/31823160/uploading-captions-using-youtube-api-v3-dotnet-c-null-error-challenging