読者です 読者をやめる 読者になる 読者になる

いものやま。

雑多な知識の寄せ集め

ニコニコ動画のダウンロードツールをRubyで書いてみた。(その1)

技術 Ruby ニコニコ動画

自分がニコニコ動画のダウンロードツールとして使っていたのが、Nicovideo Downloader

便利なツールなんだけど、ちょっと不満が。
具体的には、公式動画でいくつかダウンロード出来ないものがあるということ。
ただ、原因が分からない・・・
ブラウザでは見れているわけだから、ダウンロード出来ないはずはないんだけど。

ということで、ダウンロード出来ない原因を調べてみることにした。

コードリーディング

調べてみると、このNicovideo DownloaderというツールPythonで書かれてる様子。
なので、実際にコードを読んでみるのが早そうかな、と。

読んでいくと、いくつかの定数や関数が定義され、コマンドラインオプションの解析などもされてるけど、実際の処理は363行目以降から*1

処理の概要

363〜398行目:
ユーザのアカウント情報の設定。
Nicovideo Downloaderでは、オプションで-nを指定された場合、.netrcファイルからユーザのアカウント情報を読むようになってる。

400〜402行目:
urllib2にCookieとProxyのハンドラーを登録してるっぽい?
なんか、デコレータ・パターンのような感じがするけど、urllib2について詳しくないので、ここはよく分からない・・・
さすがにライブラリの内部のコードまで読んでいくのは大変だから、ここはパス。。。

404〜408行目:
ユーザ情報を使ってログイン。

410〜538行目:
コマンドライン引数で指定された各動画のURLについて、ダウンロード処理を行ってる感じ。

ログイン処理

ログイン処理では、https://secure.nicovideo.jp/secure/login?site=niconicoにPOSTメソッドを送信。
データとしては、current_form=login&mail=*account*&password=*password*&login_submit=Log+Inを送る。 (*account*はニコニコのアカウント、*password*はパスワード)

けど、リクエストを送るだけで、受け取ったデータを使ってない・・・?
ProxyHandlerやHTTPCookieProcessorが何かやってるのか?

ダウンロード処理

411〜426行目:
まず、正規表現を使って、指定された動画のURLから動画のID( smXXXXとか)を取得。
そして、動画のURLを標準的なフォーマットにしてる。 そのあと、動画のページにアクセス。
このとき、もしリダイレクトされたりしていたら、動画のURLをリダイレクト後のものに置き換えたり(そんなことあるの?)、ファイル名を動画のタイトルを使ったものにする場合、動画のページから動画のタイトルを取得したりしている。

432〜442行目:
http://www.nicovideo.jp/api/getflv?v=*video_id*&as3=1*video_id*は動画のID)にGETメソッドを送信して、データを取得。 このデータがCGIのクエリと同じフォーマットをしているので、そこからキー"url"の値を取得。
これが動画の実際のURLらしい。

444〜468行目:
動画の実際のURLから、動画の形式を判断して適切な拡張子にしたり、コマンドラインで指定されたオプションにしたがって、ファイル名を直したり。

470〜472行目:
コメントをダウンロードする場合、ダウンロードしてる。

474〜538行目:
実際に動画をダウンロードし、ファイルに保存してる。
このとき、データを一度に読み込んでしまうんじゃなくて、適度なサイズを計算しながら読み込んで行ってる感じ。
また、その経過の具合を出力したりしてる。

原因は・・・?

さて、コードを読んだので、処理の大体の流れは分かった。

やってることは、

  1. ログイン。
  2. 動画のURLにアクセス。
    必要なら、タイトル情報を取得。
  3. 動画情報のURLにアクセス。
    動画の実際のURLを取得。
  4. 動画の実際のURLにアクセス。
    データをダウンロードし、ファイルに出力。

これだけ。

このどこかで問題が起こってるはずだけど・・・

今日はここまで!

*1:読んだのはver.20120212