问题
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