Not able to successfully run an Azure Function which contains code to Upload Video to YouTube

浪尽此生 提交于 2020-03-23 23:15:22

问题


I am basically creating an HTTP Trigger Azure function, which has the code to upload a video to YouTube using the YouTube API. The code was pretty much provided by the YouTubeAPI docs: https://developers.google.com/youtube/v3/docs/videos/insert. I re-formatted the code a bit to fit it into the Azure function.

However, when I try to run the function locally on my Visual Studio, I get an 500 error saying:

Executed 'Function1' (Failed, Id=84400f0c-b6e4-4c78-bf55-30c4527a8b5f) System.Private.CoreLib: Exception while executing function: Function1. System.Private.CoreLib: Could not find file 'C:\Users\Peter\Desktop\TestDemo\UploadVideo\UploadVideo\bin\Debug\netcoreapp2.1\client_secrets.json'.

I am not sure how to fix this error and to make the function run without any errors. Is there anything that needs to be added/changed in the code (below) to fix this issue?

My goal: my ultimate goal is to trigger this azure function whenever there is a new video added into the Azure Blob Storage.

Code

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Upload;
using Google.Apis.YouTube.v3.Data;
using System.Reflection;
using Google.Apis.YouTube.v3;
using Google.Apis.Services;
using System.Threading;

namespace UploadVideo
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            log.LogInformation("YouTube Data API: Upload Video");
            log.LogInformation("==============================");

            try
            {
                await Run();
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.InnerExceptions)
                {
                    log.LogInformation("Error: " + e.Message);
                }
            }

            return new OkObjectResult($"Video Processed..");

        }

        private static async Task Run()
        {
            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 = "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 = @"C:\Users\Peter\Desktop\audio\test.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;

                await videosInsertRequest.UploadAsync();
            }
        }

        private static 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;
            }
        }

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

回答1:


First, from your requirements:

My goal: my ultimate goal is to trigger this azure function whenever there is a new video added into the Azure Blob Storage.

You need to use Azure blob trigger to achieve your goal.

And from your error:

Executed 'Function1' (Failed, Id=84400f0c-b6e4-4c78-bf55-30c4527a8b5f) System.Private.CoreLib: Exception while executing function: Function1. System.Private.CoreLib: Could not find file 'C:\Users\Peter\Desktop\TestDemo\UploadVideo\UploadVideo\bin\Debug\netcoreapp2.1\client_secrets.json'.

I think you didn't change the properties of the json file to 'Copy if newer' after you create it. If you don't change this property, you will face this error. So it is in the same folder with your code but not in the same folder with your dll file.




回答2:


Could not find file 'C:\Users\Peter\Desktop\TestDemo\UploadVideo\UploadVideo\bin\Debug\netcoreapp2.1\client_secrets.json'.

Its looking for the "client_secrets.json" it need to be in the same directory with your code. as you havent told it to look any where else

using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
        {

Note

GoogleWebAuthorizationBroker.AuthorizeAsync is only designed for use with installed applications its going to open the web browser on the server and prompt a user to authenticate the code.

correct me if im wrong but azure functions dont have a ui endpoint where you can prompt a user for authentication. which would mean that the only thing you could use would be a service account and the YouTube api doesn't support service accounts.



来源:https://stackoverflow.com/questions/60294677/not-able-to-successfully-run-an-azure-function-which-contains-code-to-upload-vid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!