Swingで文字列をスクロールさせてみる
ITmediaの記事「開発者が明かす「ニコニコ動画」人気の“キモ”」に書かれているニコニコ動画プレイヤの仕様のうち、
- 文字列が1画面を横断する時間が5秒
- 後から見ても、コメントが流れる位置は同じ
だけ実装してみた。
Swingアプリを作成するのには、EclipseよりNetBeansの方が良いかと思い試してみた。まっとうなプログラムを作る場合には、手作業で細かにパラメータを調整する必要があるかもしれないが、今のような適当なプログラムを作成するのにはかなりメリットがある。
文字列のスクロール(アニメーションという呼び方の方が適切か)については、Java2Dを学習する必要があると感じた。今回はこちらのサイトのサンプルコード中のクラス/メソッドを、あまり理解せずに使用している。API仕様等を読んでも専門用語が多くすんなりとは理解できそうも無い。壁は厚いと感じている。
Java Web Startについては、取り敢えず動くことを確認したのみ。仕組みなどは一切理解していない。余裕ができたら学習しようと思う。
« ニコニコ動画やYouTubeはストリーミング配信ではない | トップページ | 動画へのアニメーションオーバレイ »
コメント
この記事へのコメントは終了しました。
« ニコニコ動画やYouTubeはストリーミング配信ではない | トップページ | 動画へのアニメーションオーバレイ »
こんばんは
ブログ拝見させていただいています。
当方、こちらでのブログの内容と同様に、jmfを利用してのニコ動風プレイヤを作成しており、その過程でこちらのブログにたどり着きました。
今現在動画上で流れるコメントを実装しようとしています。
動画の手前のレイヤで流れるコメント自体は作ることが出来たのですが、打ち込んだコメントを再生時間に同期させて流すという事ができないでいます。
こちらの2007/11/11の内容にて時間軸に同期して流れるswingアプリを作っておられますが、技術的にどうやっておられるのでしょうか?よろしければぜひ教えていただけないでしょうか?
投稿: y | 2008/01/25 19:00
こんにちは。
「Swingで文字列をスクロールさせてみる」
の内容はJMFとは関係ない(=動画の再生時間等の考慮は行っていない)ですが、良いでしょうか?
このプログラムは、単純に
・"Time Reset"ボタンを押した時間(開始時刻)を覚えておく。
・コメントが入力されたら「入力時刻 - 開始時刻を『コメント表示開始時刻』としてコメントオブジェクトの情報として覚えておく。
だけです。
あとは、画面描画のタイミングで、
現在の時刻-開始時刻 を求めて、
各コメントが上で求めた時刻における表示位置に、文字を書いているだけです。
...文章で書くとわかりづらいのですが、やってることは単純です。
ソースコードは捨ててしまっているのですが、上のJava Web Startで使っているJarファイル
http://feather.cocolog-nifty.com/weblog/program/scroll01/MyPlayer.jar
をjadなどで逆コンパイルしてもらえれば、ほぼそのまま復元できると思います。
そちらを見ていただければやっていることはすぐわかるかと。
なんとなく訊ねられたい内容と回答ポイントがずれているような気もします...また質問いただければ。
投稿: 雪羽 | 2008/01/26 18:13
こんにちは
yです。
ご返信ありがとうございます。
回答の方向性ですが、まさに聞きたい事そのものです。
わざわざjarまで添付していただきありがとうございます。
実は返信を頂くまでに暫定的な解決策を見つけて無理やり時間軸に合わせた再生は出来るようになっておりました。
秒取得のためにスレッドを起動して、スレッドのタイマーとコメントの時間情報が合致した瞬間だけ描画するという力押しな方法なのですが、なるほど描画のタイミングで時間取得も行うというのは、全然思いつかなかった…。
ところで、このようなレイヤードペインを利用した多重レイヤーで動画レイヤーとコメント用レイヤーを用意してプログラムを組むと、
プログラムでコメント用レイヤーのjava2Dアニメーションを停止させていても、動画を描画するとコメントレイヤーが連動してアニメーションされてしまうのですが、こういった事は仕様として常識なのでしょうか?
これでは時間取得に関わらず常にコメントが流れてしまうので仕方なく見たくない時だけコメント文を不可視状態にして対処しているのですが、負荷の無いように止めておけたらいいのにと思っています。
上記の問題をもろもろ回避した方法として、こちらの2007/11/19の内容のように動画にエフェクトとして直接焼きこむ方法には感動しました。試行錯誤しているもののjavaはもとよりjmfの知識が浅い私にはさっぱりです。あれはどうやってやっているのでしょうか?
以上、質問の連投になってしまい申し訳ありません。
お暇のある時にでも返信いただければ幸いです。
投稿: y | 2008/01/27 17:40
こんばんは。申し訳ないですが時間が無いので乱文です。
> コメント用レイヤーのjava2Dアニメーションを停止させていても
(Timerスレッドを停止しても、と解釈すると)
サンプルコードでは、Timerスレッドで定期的にrepaintを実行して
強制的にpaintComponentが呼ばれるようにしています。
ただ、paintComponent自体は、画面描画が必要になった場合にシステムが自動的に呼び出すこともあります。
ですので、下記のような形で、paintComponentの処理自体も分岐させる必要があります。
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(flag) { // flag:コメントを表示するならtrue
// コメント表示処理
}
}
http://java.sun.com/docs/books/tutorial/uiswing/painting/step2.html
辺りにSunの解説があります。ここは英語ですが、検索すれば日本語で解説されているサイトもたくさんあると思います。
JMFのjavax.media.Codecの使い方については、
http://java.sun.com/products/java-media/jmf/2.1.1/solutions/FrameAccess.html
にあるFrameAccess.javaに、11/19のエントリに参考として記載した
http://forum.java.sun.com/thread.jspa?threadID=402604&forumID=28
に書かれているOverlayCodecクラスを追記して実行してみるのが良いかと思います。
Codec#process(Buffer input, Buffer output)メソッドの第1引数 input から、
表示する画像情報や再生時間等が取得できる...はずです。すみません記憶が曖昧です。
11/19のエントリについて、サンプルのJava Web Startのリンクを追記しました。
(当時はリンクおいていたのですが、あまり良くないサンプルだったので消していました)
Jarファイルの場所も、このリンク先jnlpファイルに記載していますので、必要があれば
そちらを参照して頂ければ(このプログラムもソースコードを残していませんでした...)。
ただ、他のコードをそのままコピペしたりして作っているので、不要な処理が多く
あまり理解の助けにはならないかも、です。
前述のOverlayCodecを理解する方が近道かもしれません。
投稿: 雪羽 | 2008/01/28 01:33