Youtube Data API v3で動画アップロード

2019-05-07

ruby, youtube, google api

YouTube Data APIを使用して、再生数上位のリスト作ったり動画をまとめて投稿したり。
実装中に何度も迷子になったので忘れないようにパンくず置いとく。

2019年5月7日時点

事前準備

Gmailのアカウントを作って YouTube でログインするだけ
「マイチャンネル」にいって自分のチャンネルIDがわかるようになる

Gmailのアカウントを作って GCP でログインするだけ

GCPアカウントがあれば、以下の手順でAPIを使えるようになります

  1. 「プロジェクトの選択」->「新しいプロジェクト」でプロジェクトを作る
  2. ナビゲーションの「APIとサービス->ダッシュボード」から「APIとサービスを有効化」
    遷移先で「YouTube Data API v3」を探して有効化する
  3. ナビゲーションの「APIとサービス->認証情報」から「認証情報を作成 -> OAuthクライアントID」
    今回はRailsアプリですが、バッチスクリプトから操作するので「その他」を選択。適当な名前を設定しました
  4. 作成したクライアントIDの編集画面で「JSONをダウンロード」してどっかに保存しとく

ひとまずこれで多分準備完了

ちなみに「認証情報-> APIキー」でもそこそこ色々できますが、認証が必要な、例えば今回の「動画の投稿」なんかはできなさそうです。
公開されている動画を再生数順でほしいとか、サムネイルのURLがほしいとかだけならAPIキーだけでもいいかも

OAuth

1
gem 'google-api-client', '~> 0.11'

credential作らないと更新系の操作はできないので作る

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
require 'google/apis/youtube_v3'
require 'googleauth'
require 'googleauth/stores/file_token_store'

module Ggl
  class Auth
    # なんかよくわからんけどこういうものなのだろう
    REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
    # tokenとかclient_secret置き場
    CREDENTIALS_PATH = '/path/to/credentials'
    # credential
    CREDENTIAL    = File.join(CREDENTIALS_PATH, "tokens.yml")
    # client_secret
    CLIENT_SECRET = File.join(CREDENTIALS_PATH, 'client_secret.json')
    # アカウントへのアクセスと、動画をアップロードする権限を申請
    SCOPES = %w[https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload]

    attr_reader :user_id

    def initialize(user_id)
      @user_id = user_id
    end

    # Google::Apis::YoutubeV3::YouTubeService の authorization に食わせて認可されたことを証明する
    def credential
      authorizer.get_credentials(user_id)
    end

    # 
    def authorize
      FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))

      url = authorizer.get_authorization_url(base_url: REDIRECT_URI)
      puts '以下のURLにアクセスしてトークンを取得'
      puts 'トークン取得できら貼り付けてenter'
      puts url

      code = gets

      authorizer.get_and_store_credentials_from_code(user_id: user_id, code: code, base_url: REDIRECT_URI)
      puts CREDENTIAL + 'を作成しました'
    end

    def client_secret
      @client_secret ||= Google::Auth::ClientId.from_file(CLIENT_SECRET)
    end

    def token
      @token ||= Google::Auth::Stores::FileTokenStore.new(file: CREDENTIAL)
    end

    def authorizer
      @authorizer ||= Google::Auth::UserAuthorizer.new(client_secret, SCOPES, token)
    end

  end
end
  1. Ggl::Auth.new('user1').authorize
    吐き出したURLで承認
    コンソールにtoken貼り付けてenter
    貼り付けたtokenが正しければ {project_root}/credentials/tokens.yml が作成される
  2. Ggl::Auth.new('user1').credential
    Google::Apis::YoutubeV3::YouTubeService インスタンスに渡す
1
2
---
app-Name: '{"client_id":"xxx-yyyy.apps.googleusercontent.com","access_token":"zzzzz.XXXXXXX-YYYYYY","refresh_token":"ZZZZZ","scope":["https://www.googleapis.com/auth/youtube","https://www.googleapis.com/auth/youtube.upload"],"expiration_time_millis":1623859211000}'

操作

よく使う操作をまとめて

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
require 'google/apis/youtube_v3'
class Ggl::Cli

  def youtube
    @youtube ||= ::Google::Apis::YoutubeV3::YouTubeService.new.tap do |y|
      y.authorization = Ggl::Auth.new.authorize.tap{|auth| auth.refresh! }
    end
  end

  # チャンネル内の動画リスト
  def list
    youtube.list_searches('id,snippet', type: "video", channel_id: 'xxxxxxxx', max_results: 50)
  end

  # ビデオ
  def videos(video_ids)
    youtube.list_videos('snippet, statistics', id: video_ids)
  end

  # 再生回数順
  def view_order_list
    youtube.list_searches('id,snippet', type: "video", order: "viewCount", channel_id: 'xxxxxxxx', max_results: 10)
  end

  # 評価順
  def rate_order_list
    youtube.list_searches('id,snippet', type: "video", order: "rating", channel_id: 'xxxxxxxx', max_results: 10)
  end

  # アップロード
  def insert_video(path, title, description)
    snippet = { snippet: { title: title, description: description } }
    youtube.insert_video('snippet', snippet, upload_source: path, content_type: 'video/*')
  end
end

こんな感じにして使いました
Ggl::Cli.new.insert_video('path_to_video', '動画のタイトル', '動画の説明')

ほぼ毎月、50個ぐらいの動画を投稿してますが、だいぶ楽ちんになりましたよ。

コメント

投稿する

投稿したコメントはご自身で削除できません

不適切なコメントと判断した場合は管理側で削除することがあります

Nicoさん

Hello,

Can you share in this page the content of your tokens.yml? Because I am about to use your code here to automate the process of uploading video into YouTube.


こんにちは、

このページでtokens.ymlのコンテンツを共有できますか?ここであなたのコードを使用して、YouTubeに動画をアップロードするプロセスを自動化しようとしているからです。

adminさん

> Nicoさん

Hello!
I added a sample of tokens.yml.

こんにちは

大変遅くなりましたが、tokens.ymlのサンプルを追記しました。
ご参考になれば幸いです