0
votes

I am creating a Azure Blob triggered function, which contains the code to upload a video to YouTube channel whenever there is a video file in the "video" container. The code I am using is from the YouTube API sample code: https://developers.google.com/youtube/v3/docs/videos/insert . I have taken this code, and I put it inside an Azure function(code below). When I compile and run the function locally, it just says "job has started"(console output below) . Next, I tried to publish this function to the Azure portal and I uploaded a test.mp4 video in my "video" container. When I clicked on 'Run' button of my function in Azure portal, it throws an error such as this, and my video isn't getting uploaded to my YouTube Channel. Text](https://stackoverflow.com/errorinazureportal.jpg) [![enter image description here]1

Here is snapshot of my storage account named, uploadvideotoyoutube, that has a 'video' container. Inside the 'video' Container I had uploaded a test.mp4 file. enter image description here Here is my code and other files:

Function1.cs:

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 YoutubeUploadFunction
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task Run([BlobTrigger("video/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, Microsoft.Azure.WebJobs.ExecutionContext context, ILogger log)
        {
            UserCredential credential;
            using (var stream = new FileStream(System.IO.Path.Combine(context.FunctionDirectory, "client_secrets.json"), FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                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";
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "unlisted";
            var VideoInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", myBlob, "video/*");
            await VideoInsertRequest.UploadAsync();
        }
    }
}

Local.Setting.Json:

    {
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=uploadvideotoyoutube;AccountKey=xxxxxxxxxxxxxxxxxxxxxx==;EndpointSuffix=core.windows.net",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  }
}

client_secrets.json: {

  "installed": {
    "client_id": "147300761218-dl0rhktkoj8arh0ebu5pu56es06hje5p.apps.googleusercontent.com",
    "project_id": "mytestproj",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "xxxxxxxxxxxxxxxxxx",
    "redirect_uris": [ "urn:ietf:wg:oauth:2.0:oob"]
  }
}

When I compile and run the function locally, this is the output I see in console:

                  %%%%%%
                 %%%%%%
            @   %%%%%%    @
          @@   %%%%%%      @@
       @@@    %%%%%%%%%%%    @@@
     @@      %%%%%%%%%%        @@
       @@         %%%%       @@
         @@      %%%       @@
           @@    %%      @@
                %%
                %

Azure Functions Core Tools (3.0.2245 Commit hash: 1d094e2f3ef79b9a478a1621ea7ec3f93ac1910d)
Function Runtime Version: 3.0.13139.0
[3/16/2020 6:02:11 PM] Building host: startup suppressed: 'False', configuration suppressed: 'False', startup operation id: 'a37bba12-9125-4af6-8c10-26daef57ef90'
[3/16/2020 6:02:11 PM] Reading host configuration file 'C:\Users\Sean\Desktop\UploadVideo\YoutubeUploadFunction\YoutubeUploadFunction\bin\Debug\netcoreapp3.0\host.json'
[3/16/2020 6:02:11 PM] Host configuration file read:
[3/16/2020 6:02:11 PM] {
[3/16/2020 6:02:11 PM]   "version": "2.0"
[3/16/2020 6:02:11 PM] }
[3/16/2020 6:02:11 PM] Reading functions metadata
[3/16/2020 6:02:11 PM] 1 functions found
[3/16/2020 6:02:11 PM] Loading startup extension 'AzureStorage'
[3/16/2020 6:02:11 PM] Loaded extension 'AzureStorage' (3.0.4.0)
[3/16/2020 6:02:11 PM] Initializing Warmup Extension.
[3/16/2020 6:02:11 PM] Initializing Host. OperationId: 'a37bba12-9125-4af6-8c10-26daef57ef90'.
[3/16/2020 6:02:11 PM] Host initialization: ConsecutiveErrors=0, StartupCount=1, OperationId=a37bba12-9125-4af6-8c10-26daef57ef90
[3/16/2020 6:02:11 PM] LoggerFilterOptions
[3/16/2020 6:02:11 PM] {
[3/16/2020 6:02:11 PM]   "MinLevel": "None",
[3/16/2020 6:02:11 PM]   "Rules": [
[3/16/2020 6:02:11 PM]     {
[3/16/2020 6:02:11 PM]       "ProviderName": null,
[3/16/2020 6:02:11 PM]       "CategoryName": null,
[3/16/2020 6:02:11 PM]       "LogLevel": null,
[3/16/2020 6:02:11 PM]       "Filter": "<AddFilter>b__0"
[3/16/2020 6:02:11 PM]     },
[3/16/2020 6:02:11 PM]     {
[3/16/2020 6:02:11 PM]       "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[3/16/2020 6:02:11 PM]       "CategoryName": null,
[3/16/2020 6:02:11 PM]       "LogLevel": "None",
[3/16/2020 6:02:11 PM]       "Filter": null
[3/16/2020 6:02:11 PM]     },
[3/16/2020 6:02:11 PM]     {
[3/16/2020 6:02:11 PM]       "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[3/16/2020 6:02:11 PM]       "CategoryName": null,
[3/16/2020 6:02:11 PM]       "LogLevel": null,
[3/16/2020 6:02:11 PM]       "Filter": "<AddFilter>b__0"
[3/16/2020 6:02:11 PM]     }
[3/16/2020 6:02:11 PM]   ]
[3/16/2020 6:02:11 PM] }
[3/16/2020 6:02:11 PM] FunctionResultAggregatorOptions
[3/16/2020 6:02:11 PM] {
[3/16/2020 6:02:11 PM]   "BatchSize": 1000,
[3/16/2020 6:02:11 PM]   "FlushTimeout": "00:00:30",
[3/16/2020 6:02:11 PM]   "IsEnabled": true
[3/16/2020 6:02:11 PM] }
[3/16/2020 6:02:11 PM] SingletonOptions
[3/16/2020 6:02:11 PM] {
[3/16/2020 6:02:11 PM]   "LockPeriod": "00:00:15",
[3/16/2020 6:02:11 PM]   "ListenerLockPeriod": "00:00:15",
[3/16/2020 6:02:11 PM]   "LockAcquisitionTimeout": "10675199.02:48:05.4775807",
[3/16/2020 6:02:12 PM]   "LockAcquisitionPollingInterval": "00:00:05",
[3/16/2020 6:02:12 PM]   "ListenerLockRecoveryPollingInterval": "00:01:00"
[3/16/2020 6:02:12 PM] }
[3/16/2020 6:02:12 PM] QueuesOptions
[3/16/2020 6:02:12 PM] {
[3/16/2020 6:02:12 PM]   "BatchSize": 16,
[3/16/2020 6:02:12 PM]   "NewBatchThreshold": 8,
[3/16/2020 6:02:12 PM]   "MaxPollingInterval": "00:00:02",
[3/16/2020 6:02:12 PM]   "MaxDequeueCount": 5,
[3/16/2020 6:02:12 PM]   "VisibilityTimeout": "00:00:00"
[3/16/2020 6:02:12 PM] }
[3/16/2020 6:02:12 PM] BlobsOptions
[3/16/2020 6:02:12 PM] {
[3/16/2020 6:02:12 PM]   "CentralizedPoisonQueue": false
[3/16/2020 6:02:12 PM] }
[3/16/2020 6:02:12 PM] HttpOptions
[3/16/2020 6:02:12 PM] {
[3/16/2020 6:02:12 PM]   "DynamicThrottlesEnabled": false,
[3/16/2020 6:02:12 PM]   "MaxConcurrentRequests": -1,
[3/16/2020 6:02:12 PM]   "MaxOutstandingRequests": -1,
[3/16/2020 6:02:12 PM]   "RoutePrefix": "api"
[3/16/2020 6:02:12 PM] }
[3/16/2020 6:02:12 PM] Starting JobHost
[3/16/2020 6:02:12 PM] Starting Host (HostId=desktopgq271u4-950774370, InstanceId=16bc66b5-e751-4c00-b383-6f705e303c13, Version=3.0.13139.0, ProcessId=5656, AppDomainId=1, InDebugMode=False, InDiagnosticMode=False, FunctionsExtensionVersion=(null))
[3/16/2020 6:02:12 PM] Loading functions metadata
[3/16/2020 6:02:12 PM] 1 functions loaded
[3/16/2020 6:02:12 PM] Generating 1 job function(s)
[3/16/2020 6:02:12 PM] Found the following functions:
[3/16/2020 6:02:12 PM] YoutubeUploadFunction.Function1.Run
[3/16/2020 6:02:12 PM]
[3/16/2020 6:02:14 PM] Initializing function HTTP routes
[3/16/2020 6:02:14 PM] No HTTP routes mapped
[3/16/2020 6:02:14 PM]
[3/16/2020 6:02:14 PM] Host initialized (2033ms)
[3/16/2020 6:02:14 PM] Host started (2485ms)
[3/16/2020 6:02:14 PM] Job host started
Hosting environment: Production
Content root path: C:\Users\Sean\Desktop\UploadVideo\YoutubeUploadFunction\YoutubeUploadFunction\bin\Debug\netcoreapp3.0
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.
[3/16/2020 6:02:19 PM] Host lock lease acquired by instance ID '000000000000000000000000A74A8599'.

C:\Users\Sean\AppData\Local\AzureFunctionsTools\Releases\3.4.1\cli_x64\func.exe (process 5656) exited with code -1.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

How can I get the function to run so that it can upload video to my YouTube channel? Does my function need to be changed? Thank you.

1
When you run the function locally, did you ever see your function triggered by blob?George Chen
@GeorgeChen I used Azure Storage Explorer, and I uploded a sample video to my container and it seems to trigger because I see this: 2020-03-17T01:48:16.534 [Information] Executing 'Function1' (Reason='New blob detected: video/test.mp4', Id=cf36ef6e-1274-4be4-a5ba-86acc1dc937c) But, how come it is not uploading the test.mp4 to my Youtube channel?user13001132
@GeorgeChen could you also please have a look at my Azure function code and see if something is missing or if it can be improved?user13001132
Suppose your code no problem, even there is something wrong, it should be trigger with exception. So try restart your function then upload a file to blob container, check if your function could be triggered.George Chen
And you don't need to run it manually, if click run I will get your same result, cause no blob is processed.George Chen

1 Answers

0
votes

Which file do you expect the function to upload if you click "run"?

By design, the blob trigger is automatically triggered whenever a new blob is uploaded to the blob account.

You need to upload a file to blob storage while the function is running.

Here is a full example (without Youtube): https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-storage-blob-triggered-function