5

I'm using the .net nuget (Google.Apis.YouTube.v3) from Google for the API calls. Everything works so far (getting playlists, video informations and so on..). But when I try to upload a video it finishes within seconds and nothing happens. upload_ResponseReceived is never called, and upload_ProgressChanged is only called twice with the following output: 1) Bytes sent: 0, Status: Starting, Exception: after a while 2) Bytes sent: 0, Status: Failed, Exception: System.Threading.Tasks.TaskCanceledException: A task was canceled.

Sample Code:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
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 UploadTest
{
    class Program
    {
        static void Main(string[] args)
        {
            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 },
                    "user",
                    CancellationToken.None,
                    new FileDataStore("YouTube.Auth.Store")).Result;
            }
            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });
            var video = new Video();
            video.Snippet = new VideoSnippet();
            video.Snippet.Title = "Default Video Title";
            video.Snippet.Description = "Default Video Description";
            video.Snippet.Tags = new string[] { "tag1", "tag2" };
            video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
            var filePath = @"E:\video.mp4"; // Replace with path to actual movie file.
            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
                videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
                videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;
                videosInsertRequest.Upload();
            }
            Console.ReadLine();
        }

        private static void videosInsertRequest_ResponseReceived(Video obj)
        {
            Debug.WriteLine("Video has been uploaded! ID: {0}",obj.Id);
        }

        private static void videosInsertRequest_ProgressChanged(IUploadProgress obj)
        {
            Debug.WriteLine("Bytes sent: {0}, Status: {1}, Exception: {2}", obj.BytesSent, obj.Status, obj.Exception);
        }
    }
}

Stacktrace:

System.AggregateException was unhandled.
  HResult=-2146233088
  Message=One or more errors occurred.
  Source=mscorlib
  StackTrace:
       at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
       at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
       at System.Threading.Tasks.Task`1.get_Result()
       at Google.Apis.Upload.ResumableUpload`1.Upload() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\output\default\Src\GoogleApis\Apis\[Media]\Upload\ResumableUpload.cs:line 351
       at UploadTest.Program.<>c__DisplayClass2.<Main>b__1() in e:\Development\UploadTest\Program.cs:line 52
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Threading.Tasks.TaskCanceledException
       HResult=-2146233029
       Message=A task was canceled.
       InnerException: 

Any idea what I could be doing wrong?

Science
  • 53
  • 7
  • What the returned object (IUploadProgress) contains? What Exception and Status properties contain? – peleyal Feb 04 '14 at 18:49
  • Bytes sent: 0, Status: Failed, Exception: Object reference not set to an instance of an object. – Science Feb 04 '14 at 19:14
  • Before that I get a Bytes sent:0, Status:Starting – Science Feb 04 '14 at 19:24
  • Can you add the exception's stacktrace? – peleyal Feb 04 '14 at 22:20
  • Added the Stacktrace to the question – Science Feb 05 '14 at 11:08
  • 1. Try to change "using (var fileStream = new FileStream(filePath, FileMode.Open))" to "using (var fileStream = new FileStream(filePath, FileMode.Open, System.IO.FileAccess.Read))" (ADD System.IO.FileAccess.Read).
    2. I also recommend you to use the other "Insert" method (without the stream) and check if it works for you.
    – peleyal Feb 05 '14 at 17:11
  • 1) Still the same error 2) How am I supposed to specify the video file when using the method without the stream? – Science Feb 05 '14 at 17:32
  • 2) It will just create the metadata, without the actual stream. – peleyal Feb 05 '14 at 19:52

1 Answers1

5

OK, I think that you have connection issues, all you have to do is changing the chunk size to a smaller size, so your code should look something like that:

const int KB = 0x400;
var minimumChunkSize = 256 * KB;

var videosInsertRequest = youtubeService.Videos.Insert(video, 
    "snippet,status", fileStream, "video/*");
videosInsertRequest.ProgressChanged +=
    videosInsertRequest_ProgressChanged;
videosInsertRequest.ResponseReceived += 
    videosInsertRequest_ResponseReceived; 
// The default chunk size is 10MB, here will use 1MB.
videosInsertRequest.ChunkSize = minimumChunkSize * 4; 
videosInsertRequest.Upload();
peleyal
  • 3,472
  • 1
  • 14
  • 25