WPF 调用海康SDK回放视频流,不用句柄方式,也不想嵌套winform控件
在 WPF 中直接调用海康 SDK 进行视频回放,而不使用句柄方式或嵌套 WinForms 控件,是一个相对复杂的任务,因为海康 SDK 主要是为 WinForms 设计的。实现这种功能需要使用 Interop 技术来直接在 WPF 中操作低级的 Win32 API 和 DirectShow 接口。
下面是一个大致的步骤说明,如何在 WPF 中直接使用海康 SDK 进行视频回放,而不嵌套 WinForms 控件。
System.Runtime.InteropServices
你需要使用 P/Invoke 来调用海康 SDK 的函数。这是一个示例定义:
using System; using System.Runtime.InteropServices; public class HikvisionSdk { [DllImport("HCNetSDK.dll")] public static extern bool NET_DVR_Init(); [DllImport("HCNetSDK.dll")] public static extern bool NET_DVR_Cleanup(); // 其他需要的 P/Invoke 定义 }
由于 WPF 本身不支持直接操作窗口句柄(Hwnd),我们可以使用 HwndHost 来嵌入一个原生的窗口,以便海康 SDK 使用。
HwndHost
using System; using System.Windows; using System.Windows.Interop; public class VideoHost : HwndHost { private IntPtr _hwndHost; private IntPtr _hParentWnd; public VideoHost(IntPtr hParentWnd) { _hParentWnd = hParentWnd; } protected override HandleRef BuildWindowCore(HandleRef hwndParent) { _hwndHost = CreateWindowEx(0, "static", "", WS_CHILD | WS_VISIBLE, 0, 0, (int)Width, (int)Height, hwndParent.Handle, (IntPtr)HOST_ID, IntPtr.Zero, 0); return new HandleRef(this, _hwndHost); } protected override void DestroyWindowCore(HandleRef hwnd) { DestroyWindow(hwnd.Handle); } [DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Auto)] private 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)] private static extern bool DestroyWindow(IntPtr hwnd); private const int WS_CHILD = 0x40000000; private const int WS_VISIBLE = 0x10000000; private const int HOST_ID = 0x00000002; }
public partial class MainWindow : Window { private VideoHost _videoHost; public MainWindow() { InitializeComponent(); Loaded += MainWindow_Loaded; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { _videoHost = new VideoHost(new WindowInteropHelper(this).Handle); hostContainer.Child = _videoHost; // hostContainer 是一个 WindowsFormsHost InitSdk(); PlayVideo(); } private void InitSdk() { HikvisionSdk.NET_DVR_Init(); } private void PlayVideo() { // 使用海康 SDK 播放视频 // 使用 _videoHost.Handle 作为视频播放的句柄 } protected override void OnClosed(EventArgs e) { HikvisionSdk.NET_DVR_Cleanup(); base.OnClosed(e); } }
在 XAML 中添加一个容器,例如 WindowsFormsHost,来承载 VideoHost:
WindowsFormsHost
VideoHost
<Window x:Class="YourNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="450" Width="800"> <Grid> <WindowsFormsHost x:Name="hostContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> </Grid> </Window>
上述步骤演示了如何在 WPF 中使用 HwndHost 来嵌入一个原生窗口,并使用海康 SDK 播放视频。这个方法不使用句柄方式和 WinForms 控件,而是直接在 WPF 中创建一个可供 SDK 使用的窗口句柄。具体的播放逻辑需要根据海康 SDK 的文档来实现。