YouTube Data API V3 での動画のアップロード

API利用の目標は、googleが用意している各種言語のライブラリーを利用せずに、Youtube APIを
利用することだったので、かなりの遠回りをしながら試行錯誤しました。
最終的には、Youtubeに動画をアップロード。
もちろん、事前にPHPライブラリーを利用してアップロードが出来ることを確認しています。

結果として、プログラム完了しましたが、はまりどころとして phpでcurl 関数を使って
楽をしようとして、いろいろあってうまくいきませんでした。
特に、curlでは1024バイト以上のデータを送信する場合の「Expect: 100-continue」ヘッダの
自動付与でこれを回避できずに、最終的には、PHPのソケットを利用してhttp通信を自前で
処理することで落ち着きました。

curl便利だけど、余計なことしないでほしいというか、追加ヘッダの指定ができるなら
絶対に付与しないヘッダを設定できるようにしてほしい。
ちなみに、web検索で見つけたExpect:を空で追加ヘッダとして指定する方法で回避できますが、
この場合、googleから 400 Bad Request が返されました。

1.OAuth 2.0

https://developers.google.com/youtube/v3/guides/authentication?hl=ja#server-side-apps

  ですが、バッチ処理で動画をアップロードする必要がある為、最終的には以下をよく理解する。

https://developers.google.com/youtube/v3/guides/authentication?hl=ja#installed-apps

  にあるマニュアルを読み,各種言語のライブラリーを利用せずに、問題なくアクセストークンを
 取得可能。
 もちろん、アクセストークンの有効時間は1時間程度しかないので、時間を経過した場合は、
 OAtuhで取得したアクセストークンと同時に返却されるリフレッシュトークン(更新トークン)も
 保存しておく必要があります。
 時間切れの場合に、この更新トークンを利用して再度アクセストークンを取得する。
 (これはバッチ処理で可能)

2.アクセストークンを利用して動画をアップロード
  リファレンスガイドの

https://developers.google.com/youtube/v3/docs/videos/insert?hl=ja

  を読んで組込んでいましたが、ここに記載のあるHTTPリクエスト
 POST https://www.googleapis.com/youtube/v3/video
 で、素直にここにPOSTすると、さあ大変400だったか400番台だったか
 とにかく、エラーステータスで返される。
  返却されたヘッダに、Location:があったので、今度はこちらに動画を
  POSTすると、上手くいきました。
 が、しかしsnippet.titleやsnippet.description等をJSONデータで一緒に
 POSTしても無視されます。
 さあ、ここからが堂々巡りと徹底的なデバックの始まり。
  SSLなので、tcpdumpでパケットキャプチャしても無駄。
 もちろん、SSLのところも自前で書けば何とでもなるんでしょうけど、
 php の fsockopen()関数で ssl指定('ssl://')ができるのでノータッチ。

3.マニュアルはこっちだよ!!
  「ガイドとチュートリアル」にある [Youtube Data API - 再開可能アップロード]

https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol?hl=ja

  このマニュアル通り処理すれば万事うまく行きます。
  最初、再開可能アップロード とあるから途中で切断された場合に切断後に再接続して途中から
  アップロードする場合に利用するとばかり勘違いしていました。
   このステップをものすごく単純化すると
   最初にsnipetやstatusを設定して(JSONでPOST)POST後に返却されたLocation:ヘッダにある
   URIに動画をアップロードするという事です。
  また、ガイドにある「ステップ 4.1: アップロード ステータスを確認する」以降は
   実装しませんでした。
 
   本当は、「ステップ 4 - アップロード プロセスを完了する」を実装してアップロードが
   失敗した場合は、中断したアップロードを再開するべきですが。
  失敗した場合は、とりあえずエラーとしてエラーログに保管しています。
  後で実装しようと思います。