2009年2月18日水曜日

Windows Media Player 10 視覚エフェクトをC#+WPFで作る実験

自力でトライしてみたが、COMについて何も知らないので躓いている。
1.http://msdn.microsoft.com/en-us/windowsmedia/bb190309.aspxからWMP 10のSDKを落とす。
2.SDKのインクルードディレクトリにあるeffects.idlをWmpEffectsLib.idlにコピーして、

[
object,
uuid(D3984C13-C3CB-48e2-8BE5-5168340B4F35),
helpstring("IWMPEffects: Public interface for Windows Media Player SDK."),
pointer_default(unique),
oleautomation
]
interface IWMPEffects : IUnknown
{

から

interface IWMPEffects2 : IWMPEffects
{
HRESULT SetCore( [in] IWMPCore * pPlayer );
HRESULT Create( [in] HWND hwndParent );
HRESULT Destroy();
HRESULT NotifyNewMedia( [in] IWMPMedia * pMedia );
HRESULT OnWindowMessage( [in] UINT msg, [in] WPARAM WParam, [in] LPARAM LParam, [in] LRESULT * plResultParam );
HRESULT RenderWindowed( [in] TimedLevel * pData, [in] BOOL fRequiredRender );
}

までを

[
uuid(d282e51a-5bb9-46c2-aa73-decf29cba6f2),
version(1.0)
]
library WmpEffectsLib{
...中身...
}

で囲む。なお、uuidの生成にはuuidgenまたはguidgenを使う。
2.midl /newtlb WmpEffectsLib.idlしてWmpEffectsLib.tlbを生成
3.tlbimp WmpEffectsLib.tlbしてWmpEffectsLib.dllを生成
4.WmpEffectsLib.idlを見ながらconstやenumの対応する定義をするC#コードを作成。
後有用そうなコメントもコピー。

namespace WmpEffectsLib
{
static class WmpEffectsLibUtils
{
// These flags are to be returned in the GetCapabilities method. They
// indicate to the effects host what the effect supports
public const uint EFFECT_CANGOFULLSCREEN = 0x00000001; // can the effect go full screen?
public const uint EFFECT_HASPROPERTYPAGE = 0x00000002; // does the effect have a property page?
public const uint EFFECT_VARIABLEFREQSTEP = 0x00000004; // should effect return frequency data with variable size steps?
public const uint EFFECT_WINDOWEDONLY = 0x00000008; // can the effect render only in windowed mode?

public const uint EFFECT2_FULLSCREENEXCLUSIVE = 0x00000010;


public const int SA_BUFFER_SIZE = 1024; // number of frequency/waveform samples

enum PlayerState // audio playback states
{
stop_state = 0, // audio is currently stopped
pause_state = 1, // audio is currently paused
play_state = 2 // audio is currently playing
};

// The tagTimedLevel structure is passed to the Render() method of the effect. It holds the frequency,
// waveform and state data need to render the effect.
//
// The first dimension of each array corresponds to the channel: 0-left/mono 1-right(stereo only)
// The second dimension contains the sampled levels. The frequency data ranges
// from 0..255. The wave form data represents -128..127 but is stored as
// 0..255. The state contains the current audio playback state. The time stamp provides
// the relative time of these samples in the audio stream.
}
}

5.MyEffects.csに以下を記述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WmpEffectsLib;
using System.Runtime.InteropServices;

namespace WMPWPFTest
{
[Guid("f6add2d1-c4c0-4e4a-99df-49ac5a90d23b")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyEffect")]
class MyEffect:IWMPEffects
{
#region IWMPEffects メンバ

public void DisplayPropertyPage(ref _RemotableHandle hwndOwner)
{
return;
}

public void GetCapabilities(out uint pdwCapabilities)
{
pdwCapabilities = 0;
}

public void GetCurrentPreset(out int pnPreset)
{
pnPreset = 0;
}

public void GetPresetCount(out int pnPresetCount)
{
pnPresetCount = 1;
}

public void GetPresetTitle(int nPreset, out string bstrPresetTitle)
{
switch (nPreset) {
case 0: bstrPresetTitle = "test";
break;
default:
bstrPresetTitle = "test";
break;
}
}

public void GetTitle(out string bstrTitle)
{
bstrTitle = "WMPEPFTest";
}

public void GoFullscreen(int fFullScreen)
{
return;
}

public void MediaInfo(int lChannelCount, int lSampleRate, string bstrTitle)
{
return;
}

public void Render(ref tagTimedLevel pLevels, ref _RemotableHandle hdc, ref tagRECT prc)
{
return;
}

public void RenderFullScreen(ref tagTimedLevel pLevels)
{
return;
}

public void SetCurrentPreset(int nPreset)
{
return;
}

#endregion
}
}

6.プロジェクトのプロパティのアセンブリ情報で``アセンブリをCOM参照可能にする''をONにする。
7.ビルド
8.regasm /regfile bin/releaseに生成されたdll でHKCR\CLSID\にクラス情報を登録するレジストリファイルを生成

この8.で「登録する型がないため、登録スクリプトは何も作成されません」と非情なお言葉。

もうちょっとCOM参照可能なクラスを作る方法を調べてみよう。

0 件のコメント: