【问题标题】:How do I preview a Windows Media Encoder session in WPF?如何在 WPF 中预览 Windows Media Encoder 会话?
【发布时间】:2008-11-11 11:00:00
【问题描述】:

此代码适用于 Windows 窗体应用程序(它显示预览),但不适用于 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 控件来获取要传递的句柄(如示例中所示),但仍然没有成功。

【问题讨论】:

    标签: wpf directshow windows-media-encoder


    【解决方案1】:

    我最近做了一些类似的事情,将现有的 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;
        }
    }
    

    【讨论】:

    • 这很好用!无法从控件访问 _preview 变量。您知道在控件更改大小时启用调整预览大小的方法吗?
    • 这正是我的示例在窗口位置或大小更改时重置句柄的原因 - 这会导致 DirectShow 渲染器重置。如果在响应控件大小的时候连续调用 StopView 和 StartView 会发生什么?
    • 在 OnWindowPositionChanged 或单独的按钮中调用 StopView、SetViewProperties 和 StartView 时也不起作用。我必须开始/停止编码(可能是 Windows 媒体编码器的问题)
    • 恐怕不知道。我刚刚查看了 WME 文档——它们并没有完全充满细节,是吗?这可能是不可能的——这取决于预览是如何在内部实现的。
    • 不,他们不是......谢谢你的回答,它确实解决了我的主要问题!
    猜你喜欢
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 2012-09-30
    • 1970-01-01
    • 2020-03-03
    相关资源
    最近更新 更多