Search code examples
c#multithreadingwinformsyoutube-data-apiuploading

Youtube data API v3, upload progression in progressBar


I am currently developing a software for a school project. in this software, I need to publish a video on YouTube (using YouTube data API v3), and to show the progression while doing so. I got an event that is being called each time the progression changes, and show it in the console. Because my application is a winForm, I need to show it in a progressBar (or something like this). And when I try to do this, it gives me an error: "Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on." I already tried to do this:

progressBar1.BeginInvoke(new MethodInvoker(delegate { progressBar1.Value = prog; }));

It doesn't give me an error, but it only show the progression at the end(when 100%), so I need a way to show during the process.

Here is the code that call the event:

            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 an application to upload files to the
                    // authenticated user's YouTube channel, but doesn't allow other types of access.
                    new[] { YouTubeService.Scope.YoutubeUpload },
                    "user",
                    CancellationToken.None
                );
            }

            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 = title[i];
            video.Snippet.Description = description[i];

            string[] tags = tag[i].Split(',');
            video.Snippet.Tags = tags;

            video.Snippet.CategoryId = category[i]; // See https://gist.github.com/dgp/1b24bf2961521bd75d6c
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = privacy[i]; // or "private" or "public" or "unlisted"
            var filePath = vidpath[i]; // Replace with path to actual movie file.

            current_vid = i;

            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                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();
            }

and here is the event:

        switch (progress.Status)
        {
            case UploadStatus.Uploading:
                progressBar1.BeginInvoke(new MethodInvoker(delegate { progressBar1.Value = Convert.ToInt32(progress.BytesSent * 100 / total_size); }));
                Console.WriteLine(progress.BytesSent * 100 / total_size);
                break;

            case UploadStatus.Failed:
                Console.WriteLine("An error prevented the upload from completing.\n{0}", progress.Exception);
                break;
        }

Solution

  • The only way I was able to correct this problem, was by creating a console app, and showing the console, when I want to give the progression.

    Thanks for your support.