ニコニコ動画のオレオレ外部プレイヤーの算段がついた
前回までのあらすじ(真面目に読まなくてもよい)
前回「ニコニコ動画が倒せない(ブラウザ上でニコニコの動画にアクセスする)」
製作中のウェブアプリケーションにニコニコ動画のプレビュー機能を追加したいのだけれど、公式の外部プレーヤーではJavaScriptで制御できなかったり設置にscriptタグを使わなければいけなかったりでいやーんな感じ。で、オレオレ外部プレイヤーを作ろうと思ったんだけど、動画ファイルをHTTP GETするのに必要なnicohistoryというクッキーをクロスドメインで取得する方法がなくて困っていたというお話。
今回のダイジェスト(真面目に見なくてよい)
その1
その2
本論
ニコニコ動画の動画を取得する手順は以下であった。
- ニコニコ動画にログイン
- getflv APIで動画URLを取得
- watch ページにアクセスしてnicohistoryクッキーを取得
- getflv APIで得た動画URLにアクセス
手順2, 3, 4すべてでニコニコ動画にログインしていることが前提になる。手順2と手順3, 4ではログインするアカウントは別の物でよい。ただしアカウント種別の不一致の問題があるのでそれについては後述する。
手順3のnicohistory Cookie をどうやって外部サイトから動的に取得するかについて。JavaScriptのXMLHttpRequest、FlashのURLLoaderではクロスドメインの制限があることは前回確認した。
これについてはimgタグのsrcに “http://www.nicovideo.jp/watch/sm9″ などとJavaScriptで設定すれば動的に取得できるということを発見した。コンテンツの中身ではなくCookieだけが欲しいと言うのが味噌。iframe でもいけるかも知れないが確認はしていない(ちなみにヘッダには x-frame-options が設定されている)。取得完了待ちは img タグの onerror イベントを使用すればよい。動画再生のタイミングで img タグによる nicohistory Cookie の取得を行えば動画ファイルにアクセスできる。これで nicohistory Cookie の問題はほぼ解決。
——– ↓ここから仮説まじり↓ ——–
と、思ったんだが getflv API で返ってくる動画ファイルのURLは getflv をコールした時のアカウントの種別(一般会員・プレミアム会員)により異なる。また、 nicohistory Cookie は取得した時のアカウントの種別に対応した動画ファイルのURLにしか有効にならない。
つまり、一般会員なら一般画質向け nicohistory Cookie を取得して一般画質の動画ファイルURLにアクセスしなければいけないし、プレミアム会員も同様に対応する Cookie で対応する URL にアクセスしなければならない。
現在 getflv API は Ajax 的にコールできないので、自分のサーバにプロキシを作成して対応している。自分のサーバでニコニコ動画にリクエストするアカウントは一般会員なので getflv で得られる動画URLも一般画質の URL である。一般画質の URL を受け取ったプレミアムユーザーがプレミアム用の nicohistory Cookie でアクセスしても forbidden になってしまう。困った。
一般向け URL から プレミアム向け URL に、一意に変換する方法はない(と、思う)。サーバをプレミアム会員にすると、今度は一般会員でウェブアプリケーションにアクセスした際に不整合が起きる。
——– ↑ここまで仮説まじり↑ ——–
そこで、nicohistory Cookie 取得のためのURLを “http://www.nicovideo.jp/watch/sm9?lo=1″ とし、プレミアムユーザーも強制的に一般画質の動画にアクセスするようにした。(参考:?lo=1 のニコニコ大百科)
これで、おっけー。
JavaScriptでの動画再生開始までは実験ができているので、再生ナビゲーションの一通りのインターフェースをこれから作る事にする。
課題
ニコニコ動画のコメントやスクリプト、提供を表示したいがブラックボックスなリバースエンジニアリングで再現するにはちょっとしんどいのでどうしたものかというところ。ニコニコマッシュアップなものを作りたいのでせめてコメントくらいは再現したいが・・・。
そもそもウェブアプリケーションをデプロイしないとデモができないんだけど、外部ですでに公開されているらしい getflv プロキシを使ってデモを作ろうかしら。
余談
nicohistory Cookie を Set-Cookie してくれるインターフェースについて。自分がわかっているのは3つ
- http://www.nicovideo.jp/watch/sm9
通常の視聴ページ。ログインしてGETで 取得できる。?eco=1や?lo=1で挙動が変わる。 - http://ext.nicovideo.jp/thumb_watch
外部プレイヤーが使っているインターフェース。POSTを使っている。POSTの内容の一部に何かのハッシュのような文字列があって、イマイチ使い方がわからない。 - http://so.nicovideo.jp/watch/sm9
スマートフォン向けの視聴ページ。通常の視聴ページと同様。画質の扱いがよくわからない。
あと getflv API は http://flapi.nicovideo.jp/api/getflv/sm9 のように GET で使えるんだけど、プレミアムアカウントで ?eco=1 でアクセスするとエコノミー版の URL が得られたりする。エコノミーと一般とプレミアムのファイルの種類などが自分の中で整理がついてなかったりするのでもうちょっと調べたい。あと getflv API にはPOSTでアクセする事もできて、スマートフォン版のページだとリクエストボディに “eco=1&device=android&v=sm9″ なんて入ってたりする。ecoは0/1以外も受けつけるようなのでこれももうちょっと調べたい。
というお話だったのさ。
http://ext.nicovideo.jp/thumb_watch
についてです。
、
1. http://ext.nicovideo.jp/thumb_watch/sm??????? getでにつなぐ
そしたら、
if (typeof Nicovideo == ‘undefined’) {
Nicovideo = new Object();
}
if (typeof Nicovideo.Global == ‘undefined’) {
Nicovideo.Global = {
playerCount: 0,
embedMode: “noflash”
};
……….
と延々と続く巨大ファイルが帰ってくるから、
2.その中から正規表現を使って
thumbplaykeyっていう変数のデータを取り出してください。
そして、http://ext.nicovideo.jp/thumb_watchに、
postで
?as3=1&v=sm???????&k={さっきのthumbplaykey}
って形式のデータを送信すると、nicohistoryが得られると思います。