Last updated: 2026年1月
DirectShow.NET 替代方案:VisioForge .Net SDK 迁移指南
从 DirectShow.NET(已停止维护)迁移到 VisioForge .NET SDK 的分步指南,适用于 .NET 6-10 上的视频捕获、播放和处理。
从 DirectShow.NET(directshowlib)迁移到现代 .NET 6-10 视频捕获、播放和处理 SDK 的 C# 开发者
为什么要替换 DirectShow.NET?
DirectShow.NET 自2010年2月以来已被放弃——超过15年没有更新。它为 Microsoft 的 DirectShow API 提供原始 COM 接口定义,而 Microsoft 自身已弃用 DirectShow,转而使用 Media Foundation。
| 风险 | 影响 |
|---|---|
| Microsoft 已弃用 DirectShow | 没有新功能、编解码器或平台支持 |
| 库已停止维护 | .NET Framework 2.0,不支持 .NET 6+ |
| COM 复杂性 | 基本任务需要数百行代码,手动内存管理 |
| 编解码器搜寻 | 必须查找、安装和注册第三方 DirectShow 滤镜 |
| 滤镜图调试 | 不透明的管道故障,无诊断工具 |
| 仅限 Windows | COM/DirectShow 无法在 macOS、Linux 或移动设备上运行 |
| 无现代编解码器 | 没有第三方滤镜就无法使用原生 H.265、AV1、VP9 |
| 注册表问题 | 现代 Windows 上的滤镜注册问题 |
哪个 VisioForge SDK 替换什么?
DirectShow.NET 用途到 VisioForge 替代
| DirectShow.NET 用途 | VisioForge 替代 |
|---|---|
| 通过滤镜图进行 C# 摄像头捕获 | Video Capture SDK .Net — `VideoCaptureCoreX` |
| C# IP 摄像头捕获(RTSP/MJPEG) | Video Capture SDK .Net — `RTSPSourceSettings` |
| C# 屏幕捕获和录制 | Video Capture SDK .Net — `ScreenCaptureSourceSettings` |
| 通过 `IGraphBuilder` 播放文件 | Media Player SDK .Net — `MediaPlayerCoreX` |
| 通过 `IDvdControl2` 播放 DVD | Media Player SDK .Net — DVD 导航 API |
| 通过 `IAMTVTuner` 电视调谐器 | Video Capture SDK .Net — `VideoCaptureCore` |
| 文件转码 | Video Edit SDK .Net — `VideoEditCoreX` |
| 自定义滤镜图 | Media Blocks SDK .Net — 模块化管道(400+ 模块) |
| `ISampleGrabber` 帧访问 | 任何 SDK 上的 `OnVideoFrameBuffer` 事件 |
C# DirectShow 接口映射
C# DirectShow 接口映射
| DirectShow.NET 接口 | VisioForge 等效 |
|---|---|
| `IGraphBuilder` | SDK 自动构建管道 |
| `ICaptureGraphBuilder2` | `VideoCaptureCoreX` 构造函数 |
| `IMediaControl` (Run/Stop/Pause) | `StartAsync()` / `StopAsync()` / `PauseAsync()` |
| `IMediaEvent` | SDK 事件(`OnError`、`OnStop` 等) |
| `IVideoWindow` | `VideoView` 控件(WinForms/WPF/MAUI/Avalonia) |
| `ISampleGrabber` | `OnVideoFrameBuffer` 事件 |
| `IBaseFilter` | 不需要——SDK 内部管理滤镜 |
| `IPin` / 引脚连接 | 不需要——SDK 自动连接管道 |
| `DsDevice.GetDevicesOfCat()` | `DeviceEnumerator.Shared.VideoSourcesAsync()` |
| `FilterCategory.VideoInputDevice` | `DeviceEnumerator.Shared.VideoSourcesAsync()` |
| `FilterCategory.AudioInputDevice` | `DeviceEnumerator.Shared.AudioSourcesAsync()` |
| `IAMTVTuner` | `VideoCaptureCore.TVTuner` 属性 |
| `IDvdControl2` | `MediaPlayerCore.DVD_*` 方法 |
| `Marshal.ReleaseComObject()` | `await sdk.DisposeAsync()` |
C# 摄像头捕获与预览
DirectShow.NET — 摄像头捕获(迁移前)
C#// 80+ lines of COM interop
var graphBuilder = (IGraphBuilder)new FilterGraph();
var captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
int hr = captureGraph.SetFiltergraph(graphBuilder);
DsError.ThrowExceptionForHR(hr);
// Find video device
var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
IBaseFilter sourceFilter;
hr = graphBuilder.AddSourceFilterForMoniker(
devices[0].Mon, null, devices[0].Name, out sourceFilter);
DsError.ThrowExceptionForHR(hr);
// Render preview
hr = captureGraph.RenderStream(
PinCategory.Preview, MediaType.Video, sourceFilter, null, null);
DsError.ThrowExceptionForHR(hr);
// Set video window
var videoWindow = (IVideoWindow)graphBuilder;
videoWindow.put_Owner(panelHandle);
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings);
videoWindow.SetWindowPosition(0, 0, panel.Width, panel.Height);
// Start
var mediaControl = (IMediaControl)graphBuilder;
hr = mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
// Cleanup (must release EVERY COM object)
Marshal.ReleaseComObject(sourceFilter);
Marshal.ReleaseComObject(captureGraph);
Marshal.ReleaseComObject(graphBuilder);VisioForge — C# 摄像头捕获(迁移后)
C#var capture = new VideoCaptureCoreX(videoView);
var devices = await DeviceEnumerator.Shared.VideoSourcesAsync();
capture.Video_Source = new VideoCaptureDeviceSourceSettings(devices[0]);
await capture.StartAsync();
// Cleanup
await capture.StopAsync();
await capture.DisposeAsync();C# 摄像头录制为 MP4
DirectShow.NET — 摄像头转 MP4(迁移前)
C#// Must find H.264 encoder filter, MP4 mux filter, file writer
// Each requires separate COM object management
var graphBuilder = (IGraphBuilder)new FilterGraph();
var captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
captureGraph.SetFiltergraph(graphBuilder);
// Add source
var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
IBaseFilter sourceFilter;
graphBuilder.AddSourceFilterForMoniker(
devices[0].Mon, null, devices[0].Name, out sourceFilter);
// Find and add H.264 encoder (must be installed on system!)
// This varies by system — no guarantee the filter exists
Guid h264Clsid = new Guid("some-encoder-guid");
IBaseFilter encoder = (IBaseFilter)Activator.CreateInstance(
Type.GetTypeFromCLSID(h264Clsid));
graphBuilder.AddFilter(encoder, "H.264 Encoder");
// Find and add MP4 mux
// Find and add file writer
// Connect source → encoder → mux → writer pins manually
// Each pin connection can fail silently or throw cryptic COM errors
// Configure encoder properties via ICodecAPI or IPropertyBag
// Different for every encoder filter...
var mediaControl = (IMediaControl)graphBuilder;
mediaControl.Run();
// Cleanup: release 5+ COM objectsVisioForge — C# 摄像头录制为 MP4(迁移后)
C#var capture = new VideoCaptureCoreX(videoView);
var devices = await DeviceEnumerator.Shared.VideoSourcesAsync();
capture.Video_Source = new VideoCaptureDeviceSourceSettings(devices[0]);
capture.Outputs_Add(new MP4Output("recording.mp4"), true);
await capture.StartAsync();C# 视频文件播放
DirectShow.NET — 视频播放(迁移前)
C#var graphBuilder = (IGraphBuilder)new FilterGraph();
int hr = graphBuilder.RenderFile("video.mp4", null);
DsError.ThrowExceptionForHR(hr);
var videoWindow = (IVideoWindow)graphBuilder;
videoWindow.put_Owner(panelHandle);
videoWindow.put_WindowStyle(WindowStyle.Child);
videoWindow.SetWindowPosition(0, 0, panel.Width, panel.Height);
var mediaControl = (IMediaControl)graphBuilder;
mediaControl.Run();
// Seeking
var mediaSeeking = (IMediaSeeking)graphBuilder;
long position = 50000000; // 5 seconds in 100ns units
mediaSeeking.SetPositions(
ref position, AMSeekingSeekingFlags.AbsolutePositioning,
null, AMSeekingSeekingFlags.NoPositioning);VisioForge — C# 视频播放器(迁移后)
C#var player = new MediaPlayerCoreX(videoView);
await player.OpenAsync(new Uri("video.mp4"));
await player.PlayAsync();
// Seeking
await player.SeekAsync(TimeSpan.FromSeconds(5));C# 视频帧捕获
DirectShow.NET — ISampleGrabber 帧捕获(迁移前)
C#// Must insert ISampleGrabber into filter graph
var sampleGrabber = (ISampleGrabber)new SampleGrabber();
var mediaType = new AMMediaType();
mediaType.majorType = MediaType.Video;
mediaType.subType = MediaSubType.RGB24;
sampleGrabber.SetMediaType(mediaType);
graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "Grabber");
// Connect pins...
sampleGrabber.SetBufferSamples(true);
// In callback: manually read buffer, create Bitmap from raw bytes
sampleGrabber.GetCurrentBuffer(ref bufferSize, buffer);
// Manual pixel format conversion, stride calculation, etc.VisioForge — C# 视频帧捕获(迁移后)
C#capture.OnVideoFrameBuffer += (s, e) =>
{
// Frame data available as managed buffer
// Or convert to SKBitmap/Bitmap directly
var bitmap = e.Frame.ToBitmap();
ProcessFrame(bitmap);
};迁移清单
- 审计 DirectShow.NET 使用情况——查找所有 `using DirectShowLib` 引用
- 识别滤镜图用途——捕获、播放、转码或自定义处理
- 选择 VisioForge SDK——Video Capture、Media Player、Video Edit 或 Media Blocks
- 安装 NuGet 包——将 DirectShowLib NuGet 替换为 VisioForge 包
- 替换滤镜图代码
- 移除 COM 清理代码——VisioForge 使用 `IAsyncDisposable`
- 移除第三方 DirectShow 滤镜依赖——VisioForge 包含编解码器
- 面向现代 .NET——.NET 6-10
- 跨平台测试
- 移除 DirectShow 滤镜注册——不再需要
迁移后的收获
| 方面 | DirectShow.NET | 迁移后 |
|---|---|---|
| 代码行数 | 每个功能100+行 | 每个功能5-10行 |
| 框架 | .NET Framework 2.0 | .NET 6-10 |
| 平台 | 仅限 Windows | Windows、macOS、Linux、iOS、Android |
| API 风格 | 原始 COM,手动引脚连接 | 类型化 async C# API |
| 编解码器 | 查找并安装 DirectShow 滤镜 | 内置(H.264、H.265、AV1、VP9) |
| 内存管理 | 手动 `Marshal.ReleaseComObject` | `IAsyncDisposable` |
| 调试 | 不透明的 COM 错误(HRESULT) | 类型化异常、事件 |
| 视频效果 | 需要查找效果滤镜 | 40+ 内置(GPU + CPU) |
| 音频效果 | 无 | 40+(EQ、混响、合唱、3D) |
| 流媒体 | 不可用 | RTMP、HLS、SRT、NDI |
| 检测 | 不可用 | 运动(MOG2)、人脸(Haar/DNN/DLib)、行人(HOG+SVM)、条形码 |
| 硬件编码 | 需要查找编码器滤镜 | NVENC、QSV、AMF、VideoToolbox |
| IP 摄像头 | 手动滤镜图 | RTSP、RTMP、HLS、ONVIF(自动重连) |
| 维护 | 已放弃(2010) | 活跃开发 |
Frequently Asked Questions
DirectShow.NET 还在维护吗?
不。DirectShow.NET 自2010年2月以来已被放弃。Microsoft 也已弃用底层 DirectShow API,转而使用 Media Foundation。
C# 视频捕获的最佳 DirectShow.NET 替代方案是什么?
VisioForge Video Capture SDK .Net 用类型化 async API 替换 DirectShow 滤镜图。需要80多行 COM 互操作的摄像头捕获变成5行 C# 代码,并提供内置录制、硬件编码和跨平台支持。
VisioForge 能替换自定义 DirectShow 滤镜图吗?
可以。VisioForge Media Blocks SDK 提供了一个包含400多个模块的模块化管道,替代自定义滤镜图构建。
VisioForge 支持 .NET 6、.NET 8、.NET 9 和 .NET 10 吗?
是的。所有 VisioForge .Net SDK 包支持 .NET 6 到 .NET 10,包括跨平台部署。
我还需要在系统上安装 DirectShow 滤镜吗?
不需要。VisioForge 捆绑了自己的编解码器和解码器。H.264、H.265、AV1、VP9、AAC 等编解码器开箱即用。
我可以从 DirectShow.NET 逐步迁移吗?
可以。VisioForge SDK 可以与 DirectShow.NET 在同一项目中共存。一次替换一个滤镜图。
