I want to upload video on youtube using client side login. without open web page permission

1.1k views Asked by At

When I upload video to YouTube using client side login. The first time redirect to UI for permissions.

I want upload without redirect to web page. I need to execute this code on server.

Here is my code.

    private async Task<string> Run(string title, string description, string filepath)
        {

            var videoID = string.Empty;
            try
            {
                logger.Info(string.Format("[uploading file on youTube Title: {0}, Description: {1}, filePath: {2}]", title, description, filepath));
                UserCredential credential;
                using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
                {
                    logger.Info("[Load credentials from google start]");
                    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
                    );
                    logger.Info("[Load credentials from google end]");

                }
                logger.Info("YouTubeApiKey {0}", System.Configuration.ConfigurationManager.AppSettings["YoutubeApiKey"]);
                var youtubeService = new YouTubeService(new BaseClientService.Initializer()
                  {
                      HttpClientInitializer = credential,
                      ApiKey = System.Configuration.ConfigurationManager.AppSettings["YoutubeApiKey"],
                      ApplicationName = System.Configuration.ConfigurationManager.AppSettings["ApplicationName"]
                  });

                logger.Info("ApplicationName {0}", System.Configuration.ConfigurationManager.AppSettings["ApplicationName"]);


                var video = new Video();
                video.Snippet = new VideoSnippet();
                video.Snippet.Title = title;
                video.Snippet.Description = 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 = "public"; // or "private" or "public"
                var filePath = filepath; // 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;

                await videosInsertRequest.UploadAsync();

            }
                return videoID;
            }
            catch (Exception e)
            {
                logger.ErrorException("[Error occurred in Run ]", e);
            }
            return videoID;
  }

        void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress)
        {
            switch (progress.Status)
            {
                case UploadStatus.Uploading:
                    Console.WriteLine("{0} bytes sent.", progress.BytesSent);
                    break;

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

        void videosInsertRequest_ResponseReceived(Video video)
        {
            Console.WriteLine("Video id '{0}' was successfully uploaded.", video.Id);
        }
1

There are 1 answers

6
Linda Lawton - DaImTo On BEST ANSWER

Your code is doing is doing everything correctly. The YouTube API doesn't allow for pure server authentication (Service Account). The only option available to you to upload files will be to use Oauth2 and authenticate your code the first time.

I just sugest you make one small change add filedatastore. This will store the authentication for you. Once you have authenticated it via the web browser you wont need to do it again.

/// <summary>
        /// Authenticate to Google Using Oauth2
        /// Documentation https://developers.google.com/accounts/docs/OAuth2
        /// </summary>
        /// <param name="clientId">From Google Developer console https://console.developers.google.com</param>
        /// <param name="clientSecret">From Google Developer console https://console.developers.google.com</param>
        /// <param name="userName">A string used to identify a user.</param>
        /// <returns></returns>
        public static YouTubeService AuthenticateOauth(string clientId, string clientSecret, string userName)
        {

            string[] scopes = new string[] { YouTubeService.Scope.Youtube,  // view and manage your YouTube account
                                             YouTubeService.Scope.YoutubeForceSsl,
                                             YouTubeService.Scope.Youtubepartner,
                                             YouTubeService.Scope.YoutubepartnerChannelAudit,
                                             YouTubeService.Scope.YoutubeReadonly,
                                             YouTubeService.Scope.YoutubeUpload}; 

            try
            {
                // here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
                UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
                                                                                             , scopes
                                                                                             , userName
                                                                                             , CancellationToken.None
                                                                                             , new FileDataStore("Daimto.YouTube.Auth.Store")).Result;

                YouTubeService service = new YouTubeService(new YouTubeService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "YouTube Data API Sample",
                });
                return service;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                return null;

            }
         }

Call the above method like this:

// Authenticate Oauth2
            String CLIENT_ID = "xxxxxx-d0vpdthl4ms0soutcrpe036ckqn7rfpn.apps.googleusercontent.com";
            String CLIENT_SECRET = "NDmluNfTgUk6wgmy7cFo64RV";
            var service = Authentication.AuthenticateOauth(CLIENT_ID, CLIENT_SECRET, "SingleUser");

Your code will need to be authenticated the first time. Once its authenticated filedatastore stores a file in %appData% on your machine. Every time it runs after that it will use the refresh token stored in %appData% to gain access again.

Code ripped from YouTube API Sample project