YoutubeのAPIには動画情報を取得したり、アップロードをしたりと便利なものが色々とありますが、Google API Consoleを弄ったりと多少ハードルが高いです。
更に、Google API Clientのv0.8からv0.9へのアップデートにより大幅な変更が加えられたため、日本語での情報も既に古くなったものが多くあり、これまたハードルをあげています。 (参考:Migrating from version 0.8.x to 0.9)
なので、自分の理解を整理するために今回はアップロードの方法をザザザっと書いていきます。
実装の前準備
必要なGem
実装に入る前に、Gemfileに記述しインストールすべきGemを紹介します。
# Google Library gem 'googleauth' gem 'google-api-client', '0.9'
googleauthはGoogleアカウントを使った認証を行うためのライブラリで、 google-api-clientはGoogleに紐付いた各種サービスのAPIを操作するためのライブラリです。
Youtube APIの有効化
次に、Google API ConsoleからYoutube APIを有効にしておきます。
入力後、 Youtube Data API v3
というAPIが表示されていると思いますのでクリックします。
そして有効化すればOKです。
OAuth 2.0 クライアント IDの作成
また、OAuth認証を行うためのクライアントIDを発行します。
先ほどの Youtube Data API v3
の画面の左部メニューの項目に 認証情報
がありますのでクリックします。
そして、 認証情報の作成
からOAuth Client IDの作成
を選択します。
あとは必要な情報を入力し、保存して下さい。
Youtubeでマイチャンネルの作成
最後に、これは忘れがちになるのですがYoutube上でマイチャンネルを作成しておいてください。 マイチャンネルを作成しておかないと、アップロードの際にエラーとなってしまいます。
やり方についてはそこまで難しくありませんので、説明は省略します。
実装
それでは実装していきます。
実装の流れとしては - googleauthでGoogleアカウントを使ったユーザーの認証を行う - google-api-clientでYoutubeのAPIを操作する という流れになります。
まず、Googleアカウントを使ったユーザーの認証を行いましょう。
ユーザーの認証には大きく2つの手順があります。 - Google側の認証ページへの遷移 - リダイレクト先でアクセストークンの取得
Google側の認証ページへの遷移
基本的にはOAuth 2.0 Flow: Server-side web appsのアクセス トークンを取得するの項に書いてあることをそのまま実装します。
https://accounts.google.com/o/oauth2/auth
をベースに使用目的に合わせたパラメータを付加していく形になると思います。
そして、完成したURLを適当な場所にリンクとして埋め込んでください。
<%= link_to 'OAuth認証', 'https://accounts.google.com/o/oauth2/auth?client_id=[client_id]&redirect_uri=[redirect_uri]&response_type=code&scope=https://www.googleapis.com/auth/youtube.upload' %>
一旦、完成したURLを叩くとGoogleアカウントの選択画面が表示され、選択するとYoutubeの権限付与に関するページが表示されると思います。 次は、この認証が完了した後にリダイレクトされる先の処理を書いていきます。
リダイレクト先でアクセストークンの取得
次にリダイレクト先でアクセストークンの取得を行います。
リダイレクト先には code
というURLパラメータがくっついていますので、この code
を使いアクセストークンを取得します。
取得については本来は googleauth
を使うべきなのですが、面倒なので net/http
で実装しました。
def callback_auth uri = URI.parse 'https://accounts.google.com/o/oauth2/token' post_params = Hash.new post_params.store('code', params[:code]) post_params.store('client_id', [client_id]) post_params.store('client_secret', [client_secret]) post_params.store('redirect_uri', [ここには設定されている適当なredirect_urlを入力してください]) post_params.store('grant_type', 'authorization_code') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.set_debug_output $stderr req = Net::HTTP::Post.new uri.path req.set_form_data(post_params) http.start do |h| response = h.request(req) result = JSON.parse(response.body) # ここにログインしているユーザーへアクセストークンを保存してあげる処理を書く end # 適当なページへ遷移 redirect_to 〜 end
client_id
, client_secret
はOAuth 2.0 クライアント IDを作成した時に割り振られますので、その値を入力してください。
google-api-clientでYoutubeのAPIを操作する
次に、Youtube APIを実際に動かすところを実装してみます。
authorization = Signet::OAuth2::Client.new( access_token: access_token, expires_at: Time.current.since(1.hour) ) file = params[:upload_file]ztempfile.path youtube = Google::Apis::YoutubeV3::YouTubeService.new youtube.authorization = authorization part = { snippet: { title: 'hoge', description: 'fuga', tags: {} } } response = youtube.insert_video('snippet', part, upload_source: file, content_type: 'video/*')
こんな感じになります。
本来だと有効期限が切れている場合のrefresh_tokenの取得処理などが必要ですが、面倒なので書きませんでした。 とりあえずこのコードを元に諸々検索すると捗るかも。
注意点としては、OAuth2認証ではなくサービスアカウントを使った認証を行うとYoutube APIでのアップロードは出来ないという点です。
また、Youtube APIの公式ドキュメントも google-api-client
の扱いについては古いv0.8の情報しかないので注意して下さい。