Search code examples
c#.netyoutube-apigoogle-api-dotnet-clientclosed-captions

YouTube v3 API caption download using SDK nuget package


I'm trying to download a caption track using YouTube API v3 (https://developers.google.com/youtube/v3/docs/captions/download) and official .NET SDK nuget package (https://www.nuget.org/packages/Google.Apis.YouTube.v3/, version 1.9.0.1360).

Returned stream contains the following text:

"The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead."

instead of the SRT plain text content which I just uploaded and verified manually through YouTube.com UI.

I found the type of error: lockedDomainCreationFailure

My code:

    ...
        _service = new YTApi.YouTubeService(new BaseClientService.Initializer {
            ApplicationName = config.AppName,
            ApiKey = config.DeveloperKey
        });
    ...

    public Stream CaptionsDownload(
        string accessToken,
        string trackId
        )
    {
        var request = _service.Captions.Download(trackId);
        request.OauthToken = accessToken;
        request.Tfmt = YTApi.CaptionsResource.DownloadRequest.TfmtEnum.Srt;

        var trackStream = new MemoryStream();
        request.Download(trackStream);
        trackStream.Position = 0;

        return trackStream;
    }

I cannot seem to find the way to set any headers on _service.HttpClient, and I guess I shouldn't do it manually. I expect that DownloadRequest (or YouTubeBaseServiceRequest) will put

/// <summary>
/// OAuth 2.0 token for the current user.
/// </summary>
[RequestParameter("oauth_token", RequestParameterType.Query)]
public virtual string OauthToken { get; set; }

into a correct authorization header. I don't see this implemented in the version 1.9.0.1360.

Maybe I'm overlooking something? Any help is greatly appreciated.

Note: I use other caption-related methods with this SDK, and 'download' is the only one I'm having a trouble with.


Solution

  • You initialed the service WITHOUT the user credential (you only used the API key). Take a look in one of the samples in our developers guide, (and pick the right flow... are you using installed application, windows phone, etc.?)

    You will have to change the way you create your service to do something like the following:

            UserCredential credential;
            using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { YoutubeService.Scope.<THE_RIGHT_SCOPE_HERE> },
                    "user", CancellationToken.None);
            }
    
            // Create the service.
            _service = new YouTubeService(new BaseClientService.Initializer {
            ApplicationName = config.AppName,
                    HttpClientInitializer = credential,
                    ApplicationName = "Books API Sample",
                });
    

    Then, for each request to the youtube service, your OAuth access token will be included as an additional header on the HTTP request itself.