PHP Youtube API v3-直接上传-未经授权的消息 [英] PHP Youtube API v3 - Direct Upload - Unauthorized message

查看:91
本文介绍了PHP Youtube API v3-直接上传-未经授权的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用API​​ v3将视频直接上传到Youtube.

I'm trying to direct upload videos to Youtube with API v3.

我正在使用服务帐户方案( https://developers.google.com/accounts/docs/OAuth2?hl=es&csw=1#scenarios ),我解决了google-api-php-client中的一些问题库(读取p12文件并避免isAccessTokenExpired始终返回false).

I'm using service account scenario (https://developers.google.com/accounts/docs/OAuth2?hl=es&csw=1#scenarios), and I solved some problems in the google-api-php-client library (to read the p12 file and to avoid the isAccessTokenExpired always return false).

<?php
/** Config */ 
$private_key_password = 'notasecret';
$private_key_file = 'xxxxxxxx-privatekey.p12';
$applicationName = 'xxxxx-youtube';
$client_secret = 'CLIENT_SECRET';
$client_id = 'xxxxxxxxxxxxx.apps.googleusercontent.com';
$service_mail = 'xxxxxxxxxxx@developer.gserviceaccount.com';
$public_key = 'xxxxxxxxxxx';

/** Constants */ 
$scope = 'https://www.googleapis.com/auth/youtube';
$url_youtube_token = 'https://accounts.google.com/o/oauth2/token';

/** Create and sign JWT */ 
$jwt = new Google_AssertionCredentials($service_mail, $scope, $private_key_file, $private_key_password, $url_youtube_token);
$jwt_assertion = $jwt->generateAssertion();

/** Use JWT to request token */
$data = array(
    'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
    'assertion' => $jwt_assertion,
);

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data),
    ),
);

$context = stream_context_create($options);
$result = file_get_contents($url_youtube_token, false, $context);

到那时,我已经在json响应中获得了访问令牌,如下所示:

At that point I've got the access token in a json response like this:

{
  "access_token" : "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "token_type" : "Bearer",
  "expires_in" : 3600
}

,不包含创建的","refresh_token"和"id_token"字段.因此,我修复了 Google_OAuth2 类中的 setAccessToken 方法,将创建的"字段设置为time()(如果未设置).否则, isAccessTokenExpired 始终返回false.

without the "created", "refresh_token" and "id_token" fields. So I fixed the setAccessToken Method in Google_OAuth2 class seting the "created" field to time() if it's not set. Otherwise isAccessTokenExpired always return false.

现在,让我们上传文件.

Now, let's go to upload the file.

    try{
        // Client init 
        $client = new Google_Client();
        $client->setClientId($client_id);
        $client->setClientSecret($client_secret);
        $client->setApplicationName($applicationName);

        $client->setAccessToken($result);

        if ($client->getAccessToken()) {

            if($client->isAccessTokenExpired()) {
                // @TODO Log error 
                echo 'Access Token Expired!!<br/>'; // Debug
            }

            $youtube = new Google_YoutubeService($client);

            $videoPath = "./test.mp4";

            // Create a snipet with title, description, tags and category id
            $snippet = new Google_VideoSnippet();
            $snippet->setTitle("fmgonzalez test " . time());
            $snippet->setDescription("fmgonzalez test " . time() );
            $snippet->setTags(array("tag1", "tag2"));

            // Numeric video category. See
            // https://developers.google.com/youtube/v3/docs/videoCategories/list
            $snippet->setCategoryId("22");

            // Create a video status with privacy status. Options are "public", "private" and "unlisted".
            $status = new Google_VideoStatus();
            $status->privacyStatus = "public";

            // Create a YouTube video with snippet and status
            $video = new Google_Video();
            $video->setSnippet($snippet);
            $video->setStatus($status);

            // Size of each chunk of data in bytes. Setting it higher leads faster upload (less chunks,
            // for reliable connections). Setting it lower leads better recovery (fine-grained chunks)
            $chunkSizeBytes = 1 * 1024 * 1024;

            // Create a MediaFileUpload with resumable uploads
            $media = new Google_MediaFileUpload('video/*', null, true, $chunkSizeBytes);
            $media->setFileSize(filesize($videoPath));

            // Create a video insert request
            $insertResponse = $youtube->videos->insert("status,snippet", $video,
                array('mediaUpload' => $media));

            $uploadStatus = false;

            // Read file and upload chunk by chunk
            $handle = fopen($videoPath, "rb");
            $cont = 1;
            while (!$uploadStatus && !feof($handle)) {
                $chunk = fread($handle, $chunkSizeBytes);
                $uploadStatus = $media->nextChunk($insertResponse, $chunk);
                echo 'Chunk ' . $cont . ' uploaded <br/>';
                $cont++;
            }

            fclose($handle);

            echo '<br/>OK<br/>';

        }else{
            // @TODO Log error 
            echo 'Problems creating the client';
        }

    } catch(Google_ServiceException $e) {
        print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage(). " <br>";
        print "Stack trace is ".$e->getTraceAsString();
    }catch (Exception $e) {
        echo $e->getMessage();
    }

但是我收到无法启动可恢复的上传" 消息.

调试, Google_MediaFileUpload 中的方法 getResumeUri 我已经获得了以下响应正文:

Debugging, the method getResumeUri in Google_MediaFileUpload I've got this response body:

"error": {
    "errors": [
    {
        "domain": "youtube.header",
        "reason": "youtubeSignupRequired",
        "message": "Unauthorized",
        "locationType": "header",
        "location": "Authorization"
    }
    ],
    "code": 401,
    "message": "Unauthorized"
}

我找到了有关其他场景的示例,但没有找到关于此场景的示例.

I've found examples about other scenarios but not about this one.

我应该怎么做才能最终上传视频文件?关于这种情况的任何示例吗?

What should I do to finally upload the video file? Any example about this scenario?

先谢谢了.

推荐答案

看似微不足道,但是您是否在要向其上传视频的帐户中创建了至少一个频道.对于acceess_token,我使用了与您几乎相同的解决方法,然后遇到了相同的问题,直到我进入YouTube帐户上传部分,并看到消息在上传视频之前至少创建了一个频道.希望对您有所帮助.

It may looks trivial but did you created at least one channel in the account you want to upload the video to. I used almost the same workaround as you for the acceess_token then encountered the same problem until I went in my Youtube account upload section and saw the message create at least one channel before uploading videos. Hope it helps.

这篇关于PHP Youtube API v3-直接上传-未经授权的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆