English 中文(简体)
我如何在WPF中预览Windows Media Encoder会话?
原标题:
  • 时间:2008-11-11 11:00:00
  •  标签:

这段代码在Windows Forms应用程序中可行(它显示预览),但在WPF应用程序中不行。

WMEncoder _encoder;
WMEncDataView _preview;
_encoder = new WMEncoder();

IWMEncSourceGroupCollection SrcGrpColl = _encoder.SourceGroupCollection;
IWMEncSourceGroup2 sourceGroup = (IWMEncSourceGroup2)SrcGrpColl.Add("SG_1");
IWMEncVideoSource2 videoDevice = (IWMEncVideoSource2)sourceGroup.AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
videoDevice.SetInput("Default_Video_Device", "Device", "");
IWMEncAudioSource audioDevice = (IWMEncAudioSource)sourceGroup.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
audioDevice.SetInput("Default_Audio_Device", "Device", "");

IWMEncProfile2 profile = new WMEncProfile2();
profile.LoadFromFile("Recording.prx");
sourceGroup.set_Profile(profile);

_encoder.PrepareToEncode(true);

_preview = new WMEncDataView();
int lpreviewStream = videoDevice.PreviewCollection.Add(_preview);

_encoder.Start();

_preview.SetViewProperties(lpreviewStream, (int)windowsFormsHost1.Handle);
_preview.StartView(lpreviewStream);

我尝试使用WindowsFormsHost控件获取句柄以传递(如示例所示),但仍然没有成功。

最佳回答

我最近做了类似的事情,将现有的DirectShow视频组件与新的WPF UI集成。有许多方法可以做到这一点,但可能最简单的方法是从HwndHost派生一个新类。然后,您只需覆盖一些方法,将窗口句柄提供给预览流,就应该可以正常工作。根据您的要求,您可能需要在WndProc中处理一些Windows消息,以处理显示更改和视频未播放时的重绘。

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace SOQuestion
{
    public class VideoHost : HwndHost
    {
        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            IntPtr hwndHost = IntPtr.Zero;
            int hostHeight = (int) this.ActualHeight;
            int hostWidth = (int) this.ActualWidth;

            hwndHost = CreateWindowEx(0, "static", "",
                WS_CHILD | WS_VISIBLE,
                0, 0,
                hostHeight, hostWidth,
                hwndParent.Handle,
                (IntPtr)HOST_ID,
                IntPtr.Zero,
                0);

            return new HandleRef(this, hwndHost);
        }

        protected override void DestroyWindowCore(HandleRef hwnd)
        {
            DestroyWindow(hwnd.Handle);
        }

        protected override void OnWindowPositionChanged(Rect rcBoundingBox)
        {
            base.OnWindowPositionChanged(rcBoundingBox);

            _preview.SetViewProperties(lpreviewStream, (int)this.Handle);
        }

        protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // Handle a couple of windows messages if required - see MSDN for details

            return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
        }

        [DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Auto)]
        internal static extern IntPtr CreateWindowEx(int dwExStyle,
        string lpszClassName,
        string lpszWindowName,
        int style,
        int x, int y,
        int width, int height,
        IntPtr hwndParent,
        IntPtr hMenu,
        IntPtr hInst,
        [MarshalAs(UnmanagedType.AsAny)] object pvParam);

        [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Auto)]
        internal static extern bool DestroyWindow(IntPtr hwnd); 

        internal const int WS_CHILD = 0x40000000;
        internal const int WS_VISIBLE = 0x10000000;
        internal const int HOST_ID = 0x00000002;
    }
}
问题回答

暂无回答




相关问题
热门标签