使用 Youtube Api v3 和 oauth2 将视频上传到我的 Youtube 频道,无需用户身份验证

Posted

技术标签:

【中文标题】使用 Youtube Api v3 和 oauth2 将视频上传到我的 Youtube 频道,无需用户身份验证【英文标题】:Upload videos to my Youtube channel without user authentication using YoutubeApi v3 and ouath2 【发布时间】:2013-10-27 06:16:59 【问题描述】:

我的任务目标是创建一个控制台脚本,它将我自己网站上最近上传的视频插入我自己的 Youtube 频道。 我想使用服务器到服务器的身份验证,但 YoutubeApi 现在不支持这种身份验证方式。

所以我的问题是:如何在没有用户帮助的情况下使用 oauth2 身份验证和控制台脚本将视频上传到 youtube 频道?有没有办法在不使用已弃用的 ClientLogin 身份验证协议的情况下做到这一点?

【问题讨论】:

在下面的回答中添加了视频。 【参考方案1】:

如果您想在不登录的情况下上传,则必须先将登录数据保存到 pickle 文件中,然后下次调用该 pickle 文件。它将包含您的频道身份验证数据。 不要让 pickle 文件公开

youtube = googleapiclient.discovery.buil(...)

只需将此 youtube 变量保存到 pickle 文件中即可。您可以在测试时在本地进行。只需将此 pickle 文件保存到服务器并调用其反序列化对象即可。

【讨论】:

【参考方案2】:

我已经能够使用以下 shell 脚本将视频上传到我在 YouTube 上的频道。

#!/bin/sh

# Upload the given video file to your YouTube channel.

cid_base_url="apps.googleusercontent.com"
client_id="<YOUR_CLIENT_ID>.$cid_base_url"
client_secret="<YOUR_CLIENT_SECRET>"
refresh_token="<YOUR_REFRESH_TOKEN>"
token_url="https://accounts.google.com/o/oauth2/token"
api_base_url="https://www.googleapis.com/upload/youtube/v3"
api_url="$api_base_url/videos?uploadType=resumable&part=snippet"

access_token=$(curl -H "Content-Type: application/x-www-form-urlencoded" -d refresh_token="$refresh_token" -d client_id="$client_id" -d client_secret="$client_secret" -d grant_type="refresh_token" $token_url|awk -F '"' '/access/print $4')

auth_header="Authorization: Bearer $access_token"
upload_url=$(curl -I -X POST -H "$auth_header" "$api_url"|awk -F ' |\r'  '/loc/print $2'); curl -v -X POST --data-binary "@$1" -H "$auth_header" "$upload_url"

有关如何获取自定义变量值,请参阅上一个答案。

【讨论】:

【参考方案3】:

这是一个通过 curl 上传视频的脚本

# WARNING, this works only with GNU grep, if you run this on a mac replace grep with ggrep after 'brew install grep'
# Store our credentials in our home directory with a file called .<script name>
my_creds=.`basename $0`
client_id='YOURCLIENTID'
client_secret='YOURCLIENTSECRET' # really a secret
if [ -s $my_creds ]; then
  # if we already have a token stored, use it
  . $my_creds
  time_now=`date +%s`
else
  scope='https://www.googleapis.com/auth/youtube'

  # Form the request URL
  auth_url="https://accounts.google.com/o/oauth2/auth?client_id=$client_id&scope=$scope&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob"

  echo "Please go to:"
  echo
  echo "$auth_url"
  echo
  echo "after accepting, enter the code you are given:"
  read auth_code

  # swap authorization code for access and refresh tokens
  auth_result=$(curl -s https://accounts.google.com/o/oauth2/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d code=$auth_code \
    -d client_id=$client_id \
    -d client_secret=$client_secret \
    -d redirect_uri=urn:ietf:wg:oauth:2.0:oob \
    -d grant_type=authorization_code)

  echo COMPLETE ANSWER WAS:
  echo $auth_result

  access_token=$(echo "$auth_result" | \
                 ggrep -Po '"access_token" *: *.*?[^\\]",' | \
                 awk -F'"' ' print $4 ')
  refresh_token=$(echo "$auth_result" | \
                 ggrep -Po '"refresh_token" *: *.*?[^\\]",*' | \
                 awk -F'"' ' print $4 ')
  expires_in=$(echo "$auth_result" | \
               ggrep -Po '"expires_in" *: *.*' | \
               awk -F' ' ' print $3 ' | awk -F',' ' print $1')
  time_now=`date +%s`
  expires_at=$((time_now + expires_in - 60))
  echo "access_token=$access_token\nrefresh_token=$refresh_token\nexpires_at=$expires_at" > $my_creds
fi

# if our access token is expired, use the refresh token to get a new one
if [ $time_now -gt $expires_at ]; then
  refresh_result=$(curl -s https://accounts.google.com/o/oauth2/token \
   -H "Content-Type: application/x-www-form-urlencoded" \
   -d refresh_token=$refresh_token \
   -d client_id=$client_id \
   -d client_secret=$client_secret \
   -d grant_type=refresh_token)
  access_token=$(echo "$refresh_result" | \
                 ggrep -Po '"access_token" *: *.*?[^\\]",' | \
                 awk -F'"' ' print $4 ')
  expires_in=$(echo "$refresh_result" | \
               ggrep -Po '"expires_in" *: *.*' | \
               awk -F' ' ' print $3 ' | awk -F',' ' print $1 ')
  time_now=`date +%s`
  expires_at=$(($time_now + $expires_in - 60))
  echo "access_token=$access_token\nrefresh_token=$refresh_token\nexpires_at=$expires_at" > $my_creds
fi


# finally this is the call to upload the video (but I haven't managed to set title and description, you might want to make another call for that)
curl https://www.googleapis.com/upload/youtube/v3/videos?part=snippet \
    -d part='snippet' \
    -d snippet.title='test of a title' \
    -d snippet.description='test of video description' \
    --data-binary "@./small.mp4" \
    -H "Content-Type: application/octet-stream" \
    -H "Authorization: Bearer $access_token"

要完成这项工作,您需要

转到https://console.developers.google.com/projectselector/apis/library 并单击“凭据”和“创建凭据”以获取您的 client_id 和 client_secret 确保它是本机应用程序的“oauth 客户端 ID”(选择“其他”作为类型) 启用“YouTube 数据 API v3”

这个脚本是基于另一个question

此外还有this github project 解决了python的问题...

【讨论】:

【参考方案4】:

在与 YoutubeAPI 开发者光盘后,我们得到了这样的解决方案: 如果不使用已弃用的 ** **ClientLogin Auth 协议,就不可能进行自己的服务器到服务器应用程序 它将在 2014 年 4 月完全弃用(但在 4 月之前您可以使用它)。

因此,如果您希望您的用户从您的网站将视频上传到您的 YT 频道,您应该采用以下方案: - 您的用户将视频上传到您的网站 - 您(或拥有您的 YT 帐户凭据的其他人)将视频导入您的 YT 频道 要解决此问题,您可以轻松使用 OAuth2 协议。

【讨论】:

虽然被接受为正确答案。这是错误的! @pinoyyid 你能用链接证明吗?【参考方案5】:

是的,此部分解释了如何:https://developers.google.com/youtube/v3/guides/moving_to_oauth#standalone

基本上,您只需检查一次并从那里保存令牌。

如果您甚至想跳过那一次,您可以在OAuth2 Playground 中获得一个具有尊重范围的刷新令牌,并将其直接插入您的代码中,并带有客户端密码和 ID。这样你的脚本就不需要网络浏览器了。

Here's the video explaining this workflow step-by-step.

【讨论】:

感谢您的回答,我会尝试使用 OAuth2 Playground,希望对您有所帮助。我告诉你,你的解决方案对我有没有帮助。 感谢您的解决方案。 在我的回答中添加了视频。

以上是关于使用 Youtube Api v3 和 oauth2 将视频上传到我的 Youtube 频道,无需用户身份验证的主要内容,如果未能解决你的问题,请参考以下文章

YouTube api v3 调试 oauth2 访问令牌

带有 OAuth2 的 YouTube API v3:更新和删除失败并出现“权限不足”错误

突然在 YouTube V3 API 上获得 Oauth 2.0 同意的 403(禁止)

没有用户 OAuth 过程的 YouTube API

Java 示例代码示例 youtube 数据 api v3 和授权方法作为 api 密钥

YouTube Data API V3:获取多个 videoCategoryId 视频