[BlueLeaf1336]> PROGRAM>

TWindowsMediaPlayer - 002

historyTOP

2004/06/21:作成
2004/06/22:更新(*)

overviewTOP

続きです。前の話はTWindowsMediaPlayer - 001で。

参考サイトTOP

前回と同じ。

メディアに関する情報TOP

取り出せる内容は多岐にわたっていますが、幅・高さ以外は、適当に表示するぐらいかなぁ。本家WindowsMediaPlayerが再生中の時に左下に表示しているものも、いくつか見当たります。説明とか、ビットレートとか。

//  ---------------------------------------------------------------------------
//  メディアに関する情報
procedure TForm1.Button12Click(Sender: TObject);
var
    i, w, h: integer;
    s: string;
begin
    //  再生中の奴ある?
    if (player.currentMedia <> nil) then
    begin
        //  区切り線
        ShowMsg(StringOfChar('-', 20));

        //  高さ
        w := player.currentMedia.imageSourceWidth;
        h := player.currentMedia.imageSourceHeight;
        ShowMsg(Format('横幅 = %d; 高さ = %d', [w, h]));

        //  メディアの名前
        ShowMsg(Format('名前 = %s', [player.currentMedia.name]));
        //  URL
        ShowMsg(Format('URL  = %s', [player.currentMedia.sourceURL]));

        //  列挙できる属性
        for i := 0 to player.currentMedia.attributeCount - 1 do
        begin
            s := player.currentMedia.getAttributeName(i);
            ShowMsg(Format('%-20s = %s', [s, player.currentMedia.getItemInfo(s)]));
        end;

        //  区切り線
        ShowMsg(StringOfChar('-', 20));
    end;
end;

どんな操作が可能かTOP

コードを見てもらえるとわかりますが、対応しているメソッドやプロパティを利用できる状態にあるかどうかを調べることができます。つまるところ、操作ボタンのEnable制御に使用するんだと思います。

//  ---------------------------------------------------------------------------
//  指定した情報の種類が利用可能か、または指定した動作が実行可能かどうかを判断
procedure TForm1.Button5Click(Sender: TObject);
var
    b: Boolean;
    s: string;
begin
    //  区切り線
    ShowMsg(StringOfChar('-', 20));

    //  再生できるか
    b := player.controls.isAvailable['Play'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.play();']);
    ShowMsg(s);

    //  一時停止できるか
    b := player.controls.isAvailable['Pause'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.pause();']);
    ShowMsg(s);

    //  停止できるか
    b := player.controls.isAvailable['Stop'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.stop();']);
    ShowMsg(s);

    //  早送り(rate = 5)再生できるか
    b := player.controls.isAvailable['FastForward'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.fastForward();']);
    ShowMsg(s);

    //  早巻き戻し(rate = 5)再生できるか
    b := player.controls.isAvailable['FastReverse'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.fastReverse();']);
    ShowMsg(s);

    //  プレイリストの次のメディアにいけるか
    b := player.controls.isAvailable['Next'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.next();']);
    ShowMsg(s);

    //  プレイリストの前のメディアにいけるか
    b := player.controls.isAvailable['Previous'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.previous();']);
    ShowMsg(s);

    //  現在位置を変更できるか
    b := player.controls.isAvailable['CurrentPosition'];
    s := Format('%s = %s', [OK_NG[b], 'player.controls.currentPosition();']);
    ShowMsg(s);

    //  区切り線
    ShowMsg(StringOfChar('-', 20));
end;

エラー発生時TOP

エラーが発生した時のイベント(OnError)を利用して、エラーの内容を取得しようとしているわけですが、たとえば変なファイルを渡したりすると、例外が送出されてしまうので、このイベントは何時走るんだろうと疑問に思っています。

というわけで、どんな実行結果になるのか不明です。

//  ---------------------------------------------------------------------------
//  エラー発生時
procedure TForm1.playerError(Sender: TObject);
var
    i: integer;
    e: integer;
    s: string;
begin
    //  発生しているエラーを表示
    for i := 0 to player.Error.errorCount - 1 do
    begin
        e := player.Error.Item[i].errorCode;
        s := player.Error.Item[i].errorDescription;
        s := Format('%d = %s', [e, s]);
        ShowMsg(s);
    end;
    //  エラーキュークリア
    player.Error.clearErrorQueue();
end;

プレイヤーやメディアの状態について(2004/06/22)TOP

とりあえず最後は、再生中などに表示するとプレイヤーっぽく見える情報の取得についてです。どれも同じようなものですが、せっかく調べたのでのせておきます。

まずは再生中のメディアが変更された時のイベント(OnMediaChange)です。今なんというメディアを再生しているか、たとえば名前とか、を調べることができます。

//  ---------------------------------------------------------------------------
//  メディアが変更された
procedure TForm1.playerMediaChange(Sender: TObject; const Item: IDispatch);
begin
    //  Item を IWMPMedia でチェック付きの型キャストする
    Label4.Caption := (Item as IWMPMedia).name;
end;

次が、プレイヤーの状態変更イベント(OnStatusChange)です。本家メディアプレイヤーが左下に表示している文字列そのままがやってきます。ただ、本家は再生開始後しばらくすると、タイトルとか作成者とかを表示しているようですが。

//  ---------------------------------------------------------------------------
//  Windows Media Player の状態変更時
procedure TForm1.playerStatusChange(Sender: TObject);
begin
    //  「準備完了」「再生中」などの文字列
    ShowMsg(player.status);
end;

残りは、プレイヤーの状態変更イベント(OnPlayStateChange)とメディアの状態変更イベント(OnOpenStateChange)...だと思います。日本語に直せないんですが、とりあえず説明文字を配列にしてますので、そのようなものが取得できると言うことです。

バージョン 7 用の SDK を参考にしているので、新しい状態がわたってくるかも知れないと思ったので、状態を表す変数の値が配列の上下限に収まっていることを、調べています。

//  ---------------------------------------------------------------------------
//  Windows Media Player の状態変更時
procedure TForm1.playerPlayStateChange(Sender: TObject; NewState: Integer);
const
    //  SDK そのままの説明文
    PLAY_STATE_STR: array[0..10] of string
    = ('Undefined      Windows Media Player の状態が定義されません。',
       'Stopped        現在のメディアクリップの再生が停止されています。',
       'Paused         現在のメディアクリップの再生が一時停止されています。'
                    + 'メディアを一時停止した場合は、再生が同じ位置から再開されます。',
       'Playing        現在のメディアクリップは再生中です。',
       'ScanForward    現在のメディアクリップは早送り中です。',
       'ScanReverse    現在のメディアクリップは巻き戻し中です。',
       'Buffering      現在のメディアクリップはサーバーからの追加情報を取得中です。',
       'Waiting        接続は確立されましたが、サーバーがビットを送信していません。'
                    + 'セッションの開始を待機中です。',
       'MediaEnded     メディアの再生が完了し、最後の位置にあります。',
       'Transitioning  新しいメディアを準備中です。',
       'Ready          再生を開始する準備ができています。');
var
    s: string;
begin
    if (Low(PLAY_STATE_STR) <= NewState) and (NewState <= High(PLAY_STATE_STR)) then
        s := PLAY_STATE_STR[NewState]
        //s := OPEN_STATE_STR[player.playState];
    else
        s := 'バールのようなもの:' + IntToStr(NewState);
    ShowMsg(s);
end;

//  ---------------------------------------------------------------------------
//  コンテンツソースの状態を示す値を取得
procedure TForm1.playerOpenStateChange(Sender: TObject; NewState: Integer);
const
    OPEN_STATE_STR: array[0..21] of string
    = ('Undefined                Windows Media Player の状態が定義されません。',
       'PlaylistChanging         新しい再生リストが読み込まれようとしています。',
       'PlaylistLocating         Windows Media Player が再生リストを探しています。'
                              + '再生リストは、ローカル(データベースまたはテキスト'
                              + 'ファイル)でも、リモートでもかまいません。',
       'PlaylistConnecting       再生リストに接続中です。',
       'PlaylistLoading          再生リストが検出され、現在取り込んでいます。',
       'PlaylistOpening          再生リストは取得済みで、現在解析され、読み込み中です。',
       'PlaylistOpenNoMedia      再生リストは開いています。',
       'PlaylistChanged          新しい再生リストが currentPlaylist に割り当てられました。',
       'MediaChanging            新しいメディアが読み込まれようとしています。',
       'MediaLocating            Windows Media Player がメディアファイルを検索中です。'
                              + 'ファイルは、ローカルでもリモートでもかまいません。',
       'MediaConnecting          メディアを保持しているサーバーに接続中です。',
       'MediaLoading             メディアが検出され、現在取得中です。',
       'MediaOpening             メディアは取得済みで、現在開いているところです。',
       'MediaOpen                メディアは現在開いています。',
       'BeginCodecAcquisition    コーデックの取得を開始しています。',
       'EndCodecAcquisition      コーデックの取得が完了しました。',
       'BeginLicenseAcquisition  DRM保護付きのコンテンツを再生するライセンスを取得中です。',
       'EndLicenseAcquisition    DRM保護付きのコンテンツを再生するライセンスを取得しました。',
       'BeginIndividualization   DRM個別化を開始しました。',
       'EndIndividualization     DRM個別化は完了しました。',
       'MediaWaiting             メディアを待機中です。',
       'OpeningUnknownURL        不明な種類のURLを開いています。');
var
    s: string;
begin
    if (Low(OPEN_STATE_STR) <= NewState) and (NewState <= High(OPEN_STATE_STR)) then
        s := OPEN_STATE_STR[NewState]
        //s := OPEN_STATE_STR[player.openState];
    else
        s := 'バールのようなもの:' + IntToStr(NewState);
    ShowMsg(s);
end;

サンプルプログラムTOP

そんなところです。またいつか自分で続きをやりたくなった時のために、テスト用で作った適当なプログラムを置いておきます。

20040622PoorPlayer.zip(197,927bytes)

ところで、設計時、TWindowsMediaPlayerをダブルクリックすると、よさげな設定画面が表示されます。今日初めて気づきました。

それともうひとつ。

でしかも未解決なんですが、本当にどうやるんでしょうか。フォームサイズの変更に、TWindowsMediaPlayerが全くコレッポッチもそぶりさえ見せずについてきません。嫌過ぎ。

EOFTOP