【问题标题】:Specify the channel to upload the videos in Youtube API using PHP指定频道以使用 PHP 在 Youtube API 中上传视频
【发布时间】:2020-11-08 10:44:32
【问题描述】:

我的 Google 帐户下有两个频道。我可以使用 PHP 的 Youtube API 将视频上传到我的主频道。我想将视频上传到我的第二个频道(不是主频道)。我已经搜索了很多,但找不到解决方案。我刚刚想到的是,我可能需要使用Google_Service_YouTube_ChannelContentOwnerDetails() 类,但我不知道如何将此详细信息指定给https://github.com/youtube/api-samples/blob/master/php/resumable_upload.php 指定的$youtube->videos->insert("status,snippet", $video) 方法。

我还发现我可能需要使用 onBehalfOfContentOwneronBehalfOfContentOwnerChannel 属性,但我认为这些参数适用于有权访问其他频道以代表他们管理其频道的帐户,我不需要使用它们,因为我在一个 Google 帐户下拥有我的两个频道。 (也许我错了)。

我只想通过我的主频道授权将视频上传到我的第二个帐户。

在这方面的任何帮助将不胜感激。

【问题讨论】:

    标签: php youtube-api youtube-data-api


    【解决方案1】:

    我尝试在 sn-p 对象中设置“--channelId”,但这似乎不起作用。 解决方法是为不同的子通道生成不同的oauth2.json。

    【讨论】:

      【解决方案2】:

      无法为Videos.insert API 端点指定通道 ID。不过还是忍一忍吧……

      第一次发出 the OAuth 2.0 authorization flow 时,他/她的应用接收到以下 JSON 对象:

      {
        "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
        "expires_in": 3920,
        "token_type": "Bearer",
        "scope": "https://www.googleapis.com/auth/youtube.force-ssl",
        "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
      }
      

      访问令牌是短暂的,而刷新令牌是长期存在的(但可以撤销at will)。这种 JSON 对象被缓存在本地文件中,以便以后在应用程序需要新的访问令牌(基于存储的刷新令牌的 is obtained from the API)时使用。访问令牌需要传递到每个需要授权的 API 端点。

      以上两个令牌是相对于一个在授权过程中登录的谷歌帐户而言的。在最常见的情况下,每个 Google 帐户都与某个 YouTube 帐户(即频道)唯一关联。但是可能会有与多个 YouTube 频道相关联的 Google 帐户(请参阅this doc使用由您的 Google 帐户管理的品牌帐户部分)。

      现在我的猜想:我确实认为有可能拥有N 这样的 JSON 对象(相对于同一范围;例如 https://www.googleapis.com/auth/youtube.upload),每个对象都与不同的 Youtube 相关联频道 - 都在一个 Google 帐户的保护伞下 - 所有都存储在本地单独的文件中(甚至都存储在一个文件中),这样,在发出需要针对给定频道的 API 调用时,以编程方式选择整组N 对象中的相关标记对。


      我的答案的第二部分包含说明我上面猜想的源代码。我不打算在这里展示一个完整的和/或包罗万象的解决方案,而只是提出一个应用程序框架,以适应具体 PHP 应用程序可能运行的各种方式(例如,单个桌面应用程序或在远程自动运行的应用程序) 没有安装浏览器的服务器)。

      该应用管理一组 JSON 文件——所有文件都存储在同一目录 ($auth_conf_path) 中。每个文件都包含与某个通道相关的所需凭据,以便能够从中创建一个适当的类Google_Client 的实例。这些 JSON 文件的名称格式为 CHANNEL_ID.json,其中 CHANNEL_ID 是该文件所引用的频道的 ID。

      应用分为两部分:一是在启动 OAuth 授权流程时创建这些凭证 JSON 文件;二是在启动 OAuth 授权流程时创建这些凭证 JSON 文件;另一个相对于给定通道进行 API 调用(凭据 JSON 文件已存在)。

      应用程序的第一部分,通过在通常的 PHP OAuth 流程中使用 initChannelCredentials,生成与授予应用程序访问权限的 YouTube 频道相关的 ID 和凭据 JSON 文件。

      应用程序的第二部分,在从 makeChannelClient 获得 Google_Client 类的实例后,会根据传递给该函数的 ID 标识的通道进行实际的 API 端点调用。

      function initChannelCredentials(
        $auth_conf_path, $scopes, $redirect_uri, $client_code)
      {
        if (!is_dir($auth_conf_path))
          throw new InvalidArgumentException(sprintf(
            'Auth config path "%s" does not exist', $auth_conf_path));
      
        $client = new Google_Client();
        $client->setAuthConfigFile(
          $auth_conf_path . DIRECTORY_SEPARATOR . 'client_secrets.json');
        $client->setRedirectUri($redirect_uri);
        $client->setScopes($scopes);
      
        $cred = $client->fetchAccessTokenWithAuthCode($client_code);
      
        $youtube = new Google_Service_YouTube($client);
        $response = $youtube->channels->listChannels('id', array(
          'mine' => 'true'
        ));
      
        $channel_id = $response[0]['id'];
        $cred_file = $auth_conf_path . DIRECTORY_SEPARATOR . $channel_id . '.json';
        if (file_exists($cred_file))
          throw new InvalidArgumentException(sprintf(
            'Credentials file for channel "%s" already exists', $channel_id));
      
        file_put_contents($cred_file, json_encode($cred));
      
        return $channel_id;
      }
      
      function makeChannelClient($auth_conf_path, $channel_id)
      {
        if (!is_dir($auth_conf_path))
          throw new InvalidArgumentException(sprintf(
            'Auth config path "%s" does not exist', $auth_conf_path));
      
        $cred_file = $auth_conf_path . DIRECTORY_SEPARATOR . $channel_id . '.json';
        if (!file_exists($cred_file))
          throw new InvalidArgumentException(sprintf(
            'Credentials file for channel "%s" does not exist', $channel_id));
      
        if (!$cred = json_decode(file_get_contents($cred_file), true))
          throw new LogicException(sprintf(
            'Invalid content of credentials file for channel "%s"', $channel_id));
      
        $client = new Google_Client();
        $client->setAccessType('offline');
        $client->setScopes($cred['scope']);
        $client->setAccessToken($cred);
      
        if ($client->isAccessTokenExpired()) {
          $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
          file_put_contents($cred_file, json_encode($client->getAccessToken()));
        }
      
        return $client;
      }
      

      请注意,上述应用程序比包含在原始帖子和我上面的猜想中的应用程序更通用。由应用程序管理的凭据 JSON 文件(同样是 YouTube 频道)不需要在单个 Google 帐户的保护下全部工作(正如我的猜想所规定的那样)。这些渠道很可能与不同的 Google 帐户相关,只要此类 PHP 应用程序的具体化身能够正确处理多个 Google 帐户即可。

      【讨论】:

      • 感谢您的详细回复。能否举例说明通过主渠道授权获取N个JSON对象?
      • 是的,这将在我的答案的下一部分中,我将在稍后制定。据我所知,没有公共代码示例可以解决手头的问题——无论实现语言(PHP、Python、Java 等)如何。我还需要您继续关注并在此过程中提供帮助,因为您已经拥有一个与两个 YouTube 频道相关联的 Google 帐户。
      • 请仔细阅读this question。 OP 说,在 OAuth 流程中,他会看到一个屏幕,让他在两个 YouTube 频道之间进行选择(在他选择了他的一个 Google 帐户之后,因此已经针对某个 Google 帐户进行了身份验证)。我需要您确认您还看到了允许您从两个关联的 YouTube 频道中选择一个的那种屏幕 - 这是在您登录 Google 帐户后发生的。
      • 是的,我看到了两个 YouTube 频道,我从列表中选择了主频道。
      • 这是个好消息!现在,我希望您测试以下内容:选择第二个通道(不是主通道)并继续完成流程。然后开始上传(一个小视频),只是为了验证这个新添加的视频是否出现在辅助频道上(当然,不会出现在主频道上)。请注意,我确实玩过 OAuth Playground(假设您现在已经非常熟悉 OAuth 2.0 流程)(您也可以玩得更好),而且看起来很有希望。
      猜你喜欢
      • 1970-01-01
      • 2017-02-12
      • 2013-02-03
      • 2015-11-19
      • 2023-03-10
      • 2016-08-05
      • 2016-08-21
      • 2013-02-10
      • 1970-01-01
      相关资源
      最近更新 更多