「へちまたん」にTorrentでダウンロード中の動画を再生する機能を追加することにしました。
動画再生にはJavaFXのMediaPlayerを使用することにしました。しかし、JavaFXのMediaPlayerは、ファイルとアドレスしか指定できません。ダウンロード中のデータをJavaFXのMediaPlauerに渡すにはどうすればよいのでしょうか?
「へちまたん」で回答を紹介します。
[回答]
「へちまたん」は、HtmlServerの機能をもたせることで解決しました。
1. 動画ファイルをダウンロードする。
2. ダウンロード中の動画ファイルをMediaPlayerに渡すサーバーを立ち上げる。
3. 動画再生側(MediaPlayer)は「へちまたん」が立ち上げたサーバーにデータを取得しにいく。
といった感じです。
[必要な実装]
基本、GETリクエストを受けとたらそのデータを返すだけです。しかし、終盤の映像だけ再生したいといったことがある場合、これだけではうまくいきまん。
Rangeリクエストに対応する必要があります。
[Rangeリクエスト]
Rangeリクエストはダウンロードするデータの位置を指定する事ができます。
例えば、200MBの「どかまぎ列伝」というデータがあったとしましょう。20分くらい動画とします。ユーザーはこの動画すでに見たことがあるのです。しかし、終盤のシーンは見逃してしまいましたとします。理由は色々あると思いますが、とりあえず見逃したのです。なので、15分くらいの動画再生を飛ばしたいはずです。もしも、通常通り動画をサーバーからデータを読み込むと、0Bから読み込みを開始します。途中からとかできません。0Bから読み込み始めます。
この場合、1秒間1MB読み取れる、恵まれた環境の人でも、150秒です。2分以上待たされることになります。そんな問題を解決するのが、Rangeリクエストです。
Rangeリクエストは位置を指定してダウンロードできます。15分後のデータからくださいといったことが可能になるわけです。
[位置を指定してダウンロード]
動画を再生する側は簡単です。Getリクエストのヘッダーに欲しいデータの位置を指定するだけです。300MBのデータの10MBから最後までデータが欲しい場合は、「Range: bytes=10000000-」とヘッダーを追加します。これは、JavaFXのMediaPlayerの中で勝手にやってくれます。
サーバー側は、「Accept-Ranges: bytes」「Content-Range: bytes 10000000-300000000/300000001」とヘッダーを追加して、指定された位置のデータを返すだけでよいです。
といった感じで、特別難しい処理が必要ではないです。HttpのGetリクエストに追加するヘッダーが変わる事ぐらいしか特別なことはしていません。
マルチパートでレスポンスを返すといった、ちょっと複雑なケースもあります。しかし、動画の配信で呼ばれることは、ほぼほぼないでしょう。より詳しい情報はrfc2616を参照してください。
[Hetimatanのコード]
つくりかけですが..
「へちまたん」は作成中のP2Pアプリです。まずは、torrentファイルを扱えるようにする事を目標にしています。
返信削除