2013年6月1日土曜日

P2P探訪 Raider JavaFXでHtmlServerを立ててMediaPlayerを再生する

「へちまたん」に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のコード]

つくりかけですが..

https://github.com/kyorohiro/Hetimatan/blob/master/Hetimatan/src/net/hetimatan/net/http/SimpleHttpServer.java


1 件のコメント:

  1. 「へちまたん」は作成中のP2Pアプリです。まずは、torrentファイルを扱えるようにする事を目標にしています。

    返信削除

mbedtls dart の 開発を始めた web wasm ffi io flutter

C言語 で開発した機能を、Dart をターゲットとして、Web でも サーバーでも、そして Flutter  でも使えるようにしたい。 そこで、mbedtls の 暗号化の部分を Dart 向けのPackageを作りながら、 実現方法を試行錯誤する事にした。 dart...