現在壁紙ビデオを作製しています
http://cult-drang.com/program/tips/wallvideo/wallvideo.html
上記を参考にしているのですが、TWindowsMediaPlayerで再生してVisibleをfalseにして壁紙の背景をなしにしたらオーバーレイされて表示されるらしいのですがうまくいきません。
サンプルのソフトを動かしても壁紙が変化するだけで動画は表示されません
設定はサイトを見ながらやっているので間違ってはいないと思うのですが……
環境はXP SP3です
>TWindowsMediaPlayerで再生してVisibleをfalseにして壁紙の背景をなしにしたらオーバーレイされて表示されるらしいのですがうまくいきません。
それを書いた本人のDと申します。
えーと、すいません。以下の点を確認いただけますでしょうか。
・背景色の設定はされましたでしょうか。
・改めて確認してみたら動画のフォーマットが無圧縮のAVIだとオーバーレイを使わずに再生するようなのでそれ以外のもので試してください。
・WMPの設定でオーバーレイを使う設定になっていますでしょうか。
http://cult-drang.com/program/tips/wmp/gaplessplay.html
このページの下の方にある説明で、「高画質モードを使う」にチェックが入っているとオーバーレイを使わないので壁紙ビデオにはなりません。
http://cult-drang.com/program/tips/wallvideo/wallvideo_wmp.html
また、ここににTWindowsMediaPlayerを利用したサンプルプログラムがあるのですが、こちらでもだめでしょうか。
>>Dさん
返信ありがとうございます、どうやら無圧縮のAVIファイルを再生していました
別ファイルにしたら表示されました!
無圧縮にファイルの表示はやはり難しいのでしょうか?
とりあえずこれで解決とさせていただきます
>無圧縮にファイルの表示はやはり難しいのでしょうか?
http://www.kero2.org/readme.cgi?0+wallpapr+index
このサイトにある「壁紙ビデオ レンダラ」を利用すればできます。
そのためにはDirectXを理解し(ないまでも)使えるようにならないといけないのでちょっと大変かなと思います。
http://www.geekpage.jp/programming/directshow/
VC++での解説ですがこのサイトを参考にコツコツやっていけばそのうちできるようになるのではないでしょうか(私は道半ばです)。
それとオーバーレイを使ってやる場合、背景色を変えるのではなくスクリーン全体の大きさの画像ファイルを作って壁紙を入れ替えてしまったほうがシステムへの影響が少し小さくなるようです。
背景色をちょこちょこ変えるとDelphiのヘルプを表示させているときにエラーを起こしてしまうことがたまにありますので。
//$100010に塗りつぶしたスクリーンいっぱいの画像を作り壁紙にセットしてしまう
ls_File := ChangeFileExt(ParamStr(0), '.bmp');
l_Bitmap := TBitmap.Create;
try
//スクリーンいっぱいのサイズにする
l_Bitmap.Width := Screen.Width;
l_Bitmap.Height := Screen.Height;
//オーバーレイ色で塗りつぶす
l_Bitmap.Canvas.Brush.Color := $100010;
l_Bitmap.Canvas.FillRect(Rect(0, 0, l_Bitmap.Width, l_Bitmap.Height));
l_Bitmap.SaveToFile(ls_File);
//壁紙にセット
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, PChar(ls_File), 0);
finally
l_Bitmap.Free;
end;
上に書かれている「壁紙ビデオ レンダラ」の作者です。
使ってみようなどという物好きな方がいらっしゃるかどうか判りませんが、一応ご参考までに、Delphi で使う場合の簡単なサンプル コーディングです。
エラー処理等は適宜入れてください。
uses
Windows, ActiveX, …
:
const
CLSID_FilterGraph: TGUID = '{E436EBB3-524F-11CE-9F53-0020AF0BA770}';
CLSID_CaptureGraphBuilder2: TGUID = '{BF87B6E1-8C27-11D0-B3F0-00AA003761C5}';
CLSID_AsyncReader: TGUID = '{E436EBB5-524F-11CE-9F53-0020AF0BA770}';
CLSID_Wallpaper: TGUID = '{9A1585D2-CECD-432D-B8AA-F1F91F217D47}';
IID_IGraphBuilder: TGUID = '{56A868A9-0AD4-11CE-B03A-0020AF0BA770}';
IID_ICaptureGraphBuilder2: TGUID = '{93E5A4E0-2D50-11D2-ABFA-00A0C9C6E38D}';
IID_IBaseFilter: TGUID = '{56A86895-0AD4-11CE-B03A-0020AF0BA770}';
IID_IFileSourceFilter: TGUID = '{56A868A6-0AD4-11CE-B03A-0020AF0BA770}';
IID_IMediaControl: TGUID = '{56A868B1-0AD4-11CE-B03A-0020AF0BA770}';
:
type
PLONGLONG = ^LONGLONG;
IBaseFilter = interface;
TAM_MEDIA_TYPE = record
majortype: TGUID;
subtype: TGUID;
bFixedSizeSamples: BOOL;
bTemporalCompression: BOOL;
lSampleSize: ULONG;
formattype: TGUID;
pUnk: IUnknown;
cbFormat: ULONG;
pbFormat: Pointer;
end;
PAM_MEDIA_TYPE = ^TAM_MEDIA_TYPE;
IFilterGraph = interface(IUnknown)
['{56A8689F-0AD4-11CE-B03A-0020AF0BA770}']
function AddFilter(pFilter: IBaseFilter; const pName: LPCWSTR): HResult; stdcall;
function RemoveFilter(pFilter: IBaseFilter): HResult; stdcall;
function EnumFilters(out ppEnum: IUnknown): HResult; stdcall;
function FindFilterByName(const pName: LPCWSTR; out ppFilter: IBaseFilter): HResult; stdcall;
function ConnectDirect(ppinOut: IUnknown; ppinIn: IUnknown; pmt: PAM_MEDIA_TYPE): HResult; stdcall;
function Reconnect(ppin: IUnknown): HResult; stdcall;
function Disconnect(ppin: IUnknown): HResult; stdcall;
function SetDefaultSyncSource: HResult; stdcall;
end;
IGraphBuilder = interface(IFilterGraph)
['{56A868A9-0AD4-11CE-B03A-0020AF0BA770}']
function Connect(ppinOut: IUnknown; ppinIn: IUnknown): HResult; stdcall;
function Render(ppinOut: IUnknown): HResult; stdcall;
function RenderFile(const lpwstrFile: LPCWSTR; lpwstrPlayList: LPCWSTR): HResult; stdcall;
function AddSourceFilter(const lpwstrFileName: LPCWSTR; const lpwstrFilterName: LPCWSTR; out ppFilter: IBaseFilter): HResult; stdcall;
function SetLogFile(hFile: THandle): HResult; stdcall;
function Abort: HResult; stdcall;
function ShouldOperationContinue: HResult; stdcall;
end;
TPIN_DIRECTION = (
PINDIR_INPUT,
PINDIR_OUTPUT
);
ICaptureGraphBuilder2 = interface(IUnknown)
['{93E5A4E0-2D50-11D2-ABFA-00A0C9C6E38D}']
function SetFiltergraph(pfg: IGraphBuilder): HResult; stdcall;
function GetFiltergraph(out ppfg: IGraphBuilder): HResult; stdcall;
function SetOutputFileName(const pType: TGUID; const lpwstrFile: POLESTR; out ppf: IBaseFilter; pSink: IUnknown): HResult; stdcall;
function FindInterface(pCategory: PGUID; pType: PGUID; pf: IBaseFilter; const riid: TIID; out ppint: Pointer): HResult; stdcall;
function RenderStream(pCategory: PGUID; pType: PGUID; pSource: IUnknown; pfCompressor: IBaseFilter; pfRenderer: IBaseFilter): HResult; stdcall;
function ControlStream(const pCategory: TGUID; pType: PGUID; pFilter: IBaseFilter; pstart: PLONGLONG; pstop: PLONGLONG; wStartCookie: WORD; wStopCookie: WORD): HResult; stdcall;
function AllocCapFile(const lpwstr: POLESTR; dwlSize: Int64{DWORDLONG}): HResult; stdcall;
function CopyCaptureFile(const lpwstrOld: POLESTR; const lpwstrNew: POLESTR; fAllowEscAbort: Integer; pCallback: IUnknown): HResult; stdcall;
function FindPin(pSource: IUnknown; pindir: TPIN_DIRECTION; pCategory: PGUID; pType: PGUID; fUnconnected: BOOL; num: Integer; out ppPin: IUnknown): HResult; stdcall;
end;
TFILTER_STATE = (
State_Stopped,
State_Paused,
State_Running
);
IMediaFilter = interface(IPersist)
['{56A86899-0AD4-11CE-B03A-0020AF0BA770}']
function Stop: HResult; stdcall;
function Pause: HResult; stdcall;
function Run(tStart: LONGLONG): HResult; stdcall;
function GetState(dwMilliSecsTimeout: DWORD; out State: TFILTER_STATE): HResult; stdcall;
function SetSyncSource(pClock: IUnknown): HResult; stdcall;
function GetSyncSource(out pClock: IUnknown): HResult; stdcall;
end;
TFILTER_INFO = record
achName: array[0..127] of WCHAR;
pGraph: IFilterGraph;
end;
IBaseFilter = interface(IMediaFilter)
['{56A86895-0AD4-11CE-B03A-0020AF0BA770}']
function EnumPins(out ppEnum: IUnknown): HResult; stdcall;
function FindPin(const Id: LPCWSTR; out ppPin: IUnknown): HResult; stdcall;
function QueryFilterInfo(out pInfo: TFILTER_INFO): HResult; stdcall;
function JoinFilterGraph(pGraph: IFilterGraph; const pName: LPCWSTR): HResult; stdcall;
function QueryVendorInfo(out pVendorInfo: LPWSTR): HResult; stdcall;
end;
IFileSourceFilter = interface(IUnknown)
['{56A868A6-0AD4-11CE-B03A-0020AF0BA770}']
function Load(const pszFileName: POLESTR; pmt: PAM_MEDIA_TYPE): HResult; stdcall;
function GetCurfile(out ppszFileName: POLESTR; out pmt: TAM_MEDIA_TYPE): HResult; stdcall;
end;
IMediaControl = interface(IDispatch)
['{56A868B1-0AD4-11CE-B03A-0020AF0BA770}']
function Run: HResult; stdcall;
function Pause: HResult; stdcall;
function Stop: HResult; stdcall;
function GetState(msTimeout: Integer; out pfs: Integer): HResult; stdcall;
function RenderFile(const strFilename: TBStr): HResult; stdcall;
function AddSourceFilter(const strFilename: TBStr; out ppUnk: IDispatch): HResult; stdcall;
function get_FilterCollection(out ppUnk: IDispatch): HResult; stdcall;
function get_RegFilterCollection(out ppUnk: IDispatch): HResult; stdcall;
function StopWhenReady: HResult; stdcall;
end;
:
var
gb: IGraphBuilder;
cgb2: ICaptureGraphBuilder2;
src: IBaseFilter;
fsf: IFileSourceFilter;
wall: IBaseFilter;
mc: IMediaControl;
:
CoInitialize(nil);
{グラフ作成}
CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, gb);
CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, cgb2);
cgb2.SetFiltergraph(gb);
{ソース追加}
CoCreateInstance(CLSID_AsyncReader, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, src);
src.QueryInterface(IFileSourceFilter, fsf);
fsf.Load('nantoka.avi', nil);
gb.AddFilter(src, 'Video Source');
{レンダラ追加}
CoCreateInstance(CLSID_Wallpaper, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, wall);
gb.AddFilter(wall, 'Video Renderer');
{フィルタ接続}
cgb2.RenderStream(nil, nil, src, nil, wall);
{実行}
gb.QueryInterface(IID_IMediaControl, mc);
mc.Run();
:
{停止}
mc.Stop();
mc := nil;
cgb2 := nil;
gb := nil;
src := nil;
fsf := nil;
wall := nil;
CoUninitialize();
>使ってみようなどという物好きな方がいらっしゃるかどうか判りませんが
試してみました。
あれこれとやってみた結果「レンダラ追加」だけでいけるようでした。
無圧縮のAVIも壁紙ビデオにできました。
結構CPUパワー(というかグラフィックパワーなのかな)が必要で、ATOMなネットブックだと動画のフレームレートが15fps程度でないとタイリングや全画面は厳しい感じでした。
procedure TForm1.Button1Click(Sender: TObject);
var
gb: IGraphBuilder;
mc: IMediaControl;
wall: IBaseFilter;
wc: IWallpaperConfig;
begin
if (OpenDialog1.Execute) then begin
CoInitialize(nil);
{グラフ作成}
CoCreateInstance(
CLSID_FilterGraph,
nil,
CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,
gb
);
{レンダラ追加}
CoCreateInstance(
CLSID_Wallpaper,
nil,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
wall
);
gb.AddFilter(wall, 'Video Renderer');
{設定}
wall.QueryInterface(IID_IWallpaperConfig, wc);
if (RadioButton2.Checked) then begin
//タイル
wc.SetStyle(WallpaperStyle_Tile);
end else if (RadioButton3.Checked) then begin
//全画面
wc.SetStyle(WallpaperStyle_Stretch);
end else {if RadioButton1.Checked) then} begin
//中央
wc.SetStyle(WallpaperStyle_Center);
end;
{実行}
gb.QueryInterface(IID_IMediaControl, mc);
mc.RenderFile(POLESTR(WideString(OpenDialog1.FileName)));
mc.Run();
//すぐに停止してしまわないように
ShowMessage('待機');
{停止}
mc.Stop();
wall := nil;
wc := nil;
gb := nil;
mc := nil;
CoUninitialize();
end;
end;
追記。
設定を行うために、タイプライブラリを取り込んでできたWallpaperTypeLib_TLB.pasを使用しています。
「プロジェクト」→「タイプライブラリの取り込み」で出てくるダイアログのリストから「Wallpaper Renderer Type Library (Version 1.0)」を選択して「インストール」で。
ツイート | ![]() |