ようこそゲストさん

mitc - 日記

2007/09/15(土) foobar2000のTrack info panel modでプログレスバー描画のテスト

はてブ 2007/09/15 12:25 雑記miff

はじめに

Title formatやTrack info panel modについてはこの記事へ
プログレスバーは,Wikipediaによると
プログレスバー(英:Progress Bar)とはタスクの進行を運ぶために使われているグラフィカルユーザインタフェースの要素の一つである。プログレスメーター (Progress Meters) とも呼ばれる。
しばしば、ダウンロードやファイル転送のようにパーセント形式で表示される際、表現の一つとして伴われる。
とのことですが,今回取り上げるのは,
特に楽曲を再生している時にどの部分を再生しているかを表示する要素についてです.

簡易描画

まず,プログレスバーを描画するための関数を使ってみます.
Track info panel modでは,そのための関数が2種類あるので両方試してみます*1

詳しい使い方は,こちらのサイトさんを見るのが早そうです.
フィールドについては,
例えば長さが5:00の曲で現在の再生時間が2:34だとすると,
2:34/5:00=%playback_time_seconds%/%length_seconds%となります.

◆プログレスバー1
prg_preset_1.png
// PerSecond
$progress(%playback_time_seconds%,%length_seconds%,15,'■','□')
◆プログレスバー2
prg_preset_2.png
// PerSecond
$progress2(%playback_time_seconds%,%length_seconds%,15,'■','□')
$rgbで色を付けたりもできます.
今回は,これを自力で描画してみます.
この関数で描くのと比べて,自力で描くと見た目の自由度が高いです.
この関数では,文字でしか表現できませんからね.

*1 : 同時には使えないっぽい?

自力で描画

参考にしたサイト:Foobar2000 Blog

四角形の描画

英語wikiからの訳
訳は全体的に怪しいですが,怪と付いている部分は,訳が特に怪しいので注意.
$drawrect(X,Y,W,H,brushColor-R-G-B penColor-R-G-B OPTIONS)
XとY左上頂点の座標.
省略するか0を指定するとウィンドウサイズの最小値になる(怪)
WとH矩形の幅と高さを定義する.
省略するか0を指定するとウィンドウサイズの最大値になる.
brushColorとpenColorブラシとペンの色を-R-G-B形式で指定する.(例:-255-0-0なら赤色)
-nullを指定すると無効になる.(例 brushColor-null)
-SYSCOL-x(xは0から?までの数値)を指定するとウィンドウズのテーマに沿った色になる
OPTIONS透過処理やぼかしのような拡張機能を使う時にはペンの色のみを指定できます*2
もしあなたがブラシの色を指定していれば,ペンの色として扱われます.
枠だけを描画したいならば,brushcolor-nullを指定して下さい.

$drawrect(10,20,100,30,pencolor-0-0-255 brushcolor-null width-2 alpha-100 blur-2)
(10,20)を左上頂点の座標として幅100,高さ30の長方形を描画する.

すごく単純な方法

//********************************
// Global
//********************************

//********************************
// Background
//********************************

//********************************
// PerTrack
//********************************
// 曲の総時間は曲ごとに決まるので,曲毎に再描画すれば良い
// 曲の秒数を横幅として矩形を描画する
$drawrect(10,10, %length_seconds%,10,pencolor-255-0-0 brushcolor-null width-1 alpha-100 blur-1)

//********************************
// PerSecond
//********************************
// 現在の再生時間は1秒ごとに更新する
// 現在の再生秒数を横幅として塗りつぶした矩形を描画する
$drawrect(10,10,%playback_time_seconds%,10,pencolor-255-0-0 brushcolor-0-0-255 width-1 alpha-100 blur-1)
これを実行すると次のようになります.
prg_test_1.png
すごく単純な方法の問題点
  1. 横幅に曲の秒数を指定しているので,曲が切り替わるごとにプログレスバーの長さが変わる
  2. 長い曲では無制限にプログレスバーが伸びる
  3. 再生中で無い時に表示がおかしくなる
1,2は,プログレスバーの幅を固定して現在の再生時間が全体の何パーセントであるかを計算することで解決できます.
3は,1,2の対策で長さを固定し,再生中でない時は内側の矩形を描画しないようにしてしまいましょう.

すごく単純な方法のちょっと改良版

//********************************
// Global
//********************************

//-- 設定
// 左上座標
$puts(PROGRESSBAR_POINT_X, 10)
$puts(PROGRESSBAR_POINT_Y, 50)
// 幅
$puts(PROGRESSBAR_WIDTH_MAX, 100)
// 高さ
$puts(PROGRESSBAR_HEIGHT, 10)

//-- 処理

//- プログレスバーの横幅を取得
// プログレスバーを空にするフラグ
$puts(PROGRESSBAR_BLANK_FLAG, 0)
// 再生中でないならプログレスバーは空
$if(%_isplaying%
	,$puts(PROGRESSBAR_WIDTH,$muldiv(%playback_time_seconds%, $get(PROGRESSBAR_WIDTH_MAX),%length_seconds%))
	,$puts(PROGRESSBAR_BLANK_FLAG,1)
)
// 再生時間が0の時にプログレスバーの長さが0になってしまう
// 矩形の描画で幅を0にするとウィンドウ一杯に描画してしまうので,0の時にはバーの中身を表示しないようにする
$ifequal($get(PROGRESSBAR_WIDTH),0, $puts(PROGRESSBAR_BLANK_FLAG, 1) , $puts(PROGRESSBAR_BLANK_FLAG, 0))

//********************************
// Background
//********************************

//********************************
// PerTrack
//********************************
// 曲の総時間は曲ごとに決まるので,曲毎に再描画すれば良い
// 曲の秒数を横幅として矩形を描画する
$drawrect($get(PROGRESSBAR_POINT_X),$get(PROGRESSBAR_POINT_Y),$get(PROGRESSBAR_WIDTH_MAX),$get(PROGRESSBAR_HEIGHT),pencolor-255-0-0 brushcolor-null width-1 alpha-100 blur-1)

//********************************
// PerSecond
//********************************
// プログレスバーの中身を描画しないフラグが1なら描画しない.そうでないなら描画する
$ifequal($get(PROGRESSBAR_BLANK_FLAG), 1
	,
	,$drawrect($get(PROGRESSBAR_POINT_X),$get(PROGRESSBAR_POINT_Y),$get(PROGRESSBAR_WIDTH),$get(PROGRESSBAR_HEIGHT),pencolor-255-0-0 brushcolor-255-0-0 width-1 alpha-100 blur-1)
)
これを実行すると次のようになります.
prg_test_2.png
プログレスバーの幅がおかしくなる問題について
muldivを使った計算方法について,私は最初良く理解できなかったので書き残しておきます.
ただ,普通の人にとっては常識だと思います!ごめんなさい!

直観的な計算でプログレスバーの長さを求める処理は,次のようになります.
// プログレスバーの長さ
float progress_length = プログレスバーの長さ;
// プログレスバーの現在の長さ
float progress_playback = (再生時間 / 曲の長さ) * progress_width
再生時間/曲の長さ で,現在何%再生しているのかを算出し,
プログレスバーの長さにかけることでどれだけの長さでバーを埋めればいいかを計算しているわけです.

ところが,Title Formatでは,小数を扱えないので少し面倒な処理が必要になります.
ここで出てくるのがmuldivという関数です.
これは,((第一引数 * 第二引数) / 第三引数)という計算をする関数で,次のように使います.
// 実際の計算: (再生時間 * プログレスバーの最大幅) / 曲の長さ
$muldiv(再生時間,プログレスバーの最大幅,曲の長さ)
ちょっとややこしいですが,これは実際の計算をイメージするとすぐにわかります.
// 最初に挙げた例での計算(直観的な計算方法)
(再生時間 / 曲の長さ) * プログレスバーの長さ = 必要なプログレスバーの長さ
// muldivを使った計算
(再生時間 * プログレスバーの長さ) / 曲の長さ = 必要なプログレスバーの長さ
除算と乗算だけの式なので順番がどうなろうと関係無いということですね*3
再生中で無い時に表示がおかしくなる問題について
%_isplaying%と%playback_time_seconds%を表示しながら再生中の曲を切り替えたり停止ボタンを押してみるとわかりやすいと思います.
%_isplaying%は,楽曲を再生中かどうかを判別するフラグです.
ここでは,再生中かどうかを判別し,再生中のみプログレスバーの長さを計算しています.
また,再生時間が0の時などにプログレスバーの長さが0になり,
矩形の幅を0にするとウィンドウいっぱいに描画されてしまうという仕様に引っかかってしまうので,
その時にはプログレスバーの中身を描画しないようにしています.

おわりに

描画関係は,まだよくわからない部分が多いです.
特に複数の物体を描画したり描画と文字列の表示を両立させようとするとうまくいかないことがよくあったりで.
この辺は,いろいろ試してみるしかないかな…….
画像を使ってもっと綺麗に描くこともできるのかな?

*2 : ブラシの色は指定できません

*3 : 改めて文章にするとあまりにも当たり前なので恥ずかしくなってきた


1: NonO_ 2007年09月16日(日) 午後9時20分

色々できるツールだな~と再認識
参考にさせていただきます

2: miff 2007年09月27日(木) 午後6時46分

本当に色々なことができますよね.
日本ではあんまりサンプルなどがないので
外国のサイトを見ないといけないのが日本語人間の私にはなかなか辛いところです.

3: NonO_ 2008年06月16日(月) 深夜3時34分

色々参考にしたら、広がりすぎて収集が付かなくなってきた(;´Д`)
まさかASIOやネトラジまで出来るなんて
それが半年以上掛けて出た答えみたいです
似たようなツールでVLCが凄いっすね
これからも色々参考にさせていただきますm(_ _)m

4: miff 2008年07月22日(火) 午後10時45分

遅くなってごめんなさい。
foobar2000は、プラグインが凄い数ありますものね。
カスタマイズして原形がわからなくなるほど変わっているスクリーンショットとか良く見ますし。
VLC今度インストールしてみようと思います。
見て頂いてありがとうございます。


名前:  非公開コメント   

E-Mail(任意/非公開):
URL(任意):
  • TB-URL  http://mitc.s279.xrea.com/diary/064/tb/
  • foobar2000にスムーズなプログレスバーを表示する Web Scrap
    foobar2000のTrack info panel modでプログレスバー描画のテストを参考にしてTrack info panel modでプログレスバーを表示させる。