CaptureManager SDK - 从网络摄像头捕获、录制和流式传输视频和音频






4.91/5 (213投票s)
本文介绍了我的项目,该项目通过 Microsoft Media Foundation 在 Windows 操作系统上捕获视频和音频源。
- 下载源代码 CaptureManagerSDK - 1.3 MB
- 下载 CaptureManagerSDK-1.24.0-免费版 - 1.5 MB
- 下载 CaptureManagerSDK.chm - 46 KB
- 下载 CaptureManagerToCSharpProxy - 128.7 KB
- 下载 CaptureManagerToJavaProxy - 1.6 MB
- 下载 CaptureManagerToPythonProxy - 24.9 KB
- 下载 CaptureManagerSDK-CPPDemos - 5.3 MB
- 下载 CaptureManagerSDK-QtMinGWDemos - 779.2 KB
- 下载 CaptureManagerSDK-CSharpDemos - 8.5 MB
- 下载 CaptureManagerSDK-JavaDemos - 5.3 MB
- 下载 CaptureManagerSDK-PythonDemos - 54.1 KB
- 下载 CaptureManagerSDK-UnityDemos - 8.9 MB
在
我很高兴收到您对其有用性的反馈,以及您关于改进 SDK 功能的意见和通过以下链接向其他开发人员提出的建议
最有趣的演示程序如下所示
- WPFVirtualCamera - 用于将
CaptureManager SDK 集成到第三方网络摄像头应用程序(如 Skype 或 Zoom)中的DirectShow 过滤器 - WPFStreamer(在 Facebook(SSL 加密连接:Facebook 要求所有实时视频流都通过 RTMPS,或在 TLS/SSL 连接上的实时消息协议 (RTMP) - 这将有助于通过加密保护流媒体内容,从而确保更高的数据完整性)和 YouTube 网站上进行实时视频和音频流式传输)- 免费版。
- WPFRTSPClient - 免费版
- WPFRtspServer - 免费版
CaptureManager SDK 版本
CaptureManager 帮助文件
引言
本文介绍了我的项目,该项目通过 Microsoft Media Foundation 在 Windows 操作系统上捕获视频和音频源。
我花了很多时间解决视频和音频数据处理的不同任务,并研究了在 Windows 系列操作系统上捕获视频和音频的技术。DirectShow 长期以来一直是 Windows 系列操作系统上捕获实时视频的主要技术。然而,自 Vista 操作系统以来,微软引入了一个新的框架来处理视频和音频 - Microsoft Media Foundation,自 Windows7 操作系统以来,它具有通过 USB 视频类驱动程序和线路音频输入处理网络摄像头的特性。我将这项技术纳入了许多项目,并撰写了两篇关于它的文章
这些文章介绍了用于捕获网络摄像头和抓取图像帧的简单库,但 Microsoft Media Foundation 是一个功能更强大的框架。经过一番思考,我决定编写一个处理实时视频和音频的新解决方案,该解决方案比我之前的解决方案更灵活,并且可以发挥 Microsoft Media Foundation 更大的能力(或力量 :))。该解决方案可以与 Microsoft 解决方案竞争。该解决方案,可以被称为任何开发人员以前见过的最好的解决方案。
背景
当我遇到一个不寻常的任务时,我产生了基于 Microsoft Media Foundation 编写一个处理网络摄像头的新解决方案的想法。所以,这个任务没有解决,但我写了一些代码,并决定继续开发这个解决方案。
一开始,该解决方案只包含少数几个类,只允许执行少数几个功能,但在增加了一些对该解决方案的要求后,我决定编写一个简单的 SDK,允许轻松地为新任务进行捕获配置,并通过实现 Microsoft Media Foundation 和
因此,我获得了这个仅通过 Microsoft Media Foundation 从网络摄像头捕获、录制和流式传输实时视频和音频的 SDK。
Using the Code
CaptureManager SDK 演示程序
- WPFHardwareButtonTrigger
- WPFWebViewerEVRLog4net
- WPFVirtualCamera
- WPFStreamingAudioRenderer
- AudioCaptureProcessor
- WPFGIFtoVideo
- WPFMixer
- WPFStreamer (在 Facebook 和 YouTube 网站上进行实时视频和音频流式传输)
- WPFRTSPClient
- WPFRtspServer
- WPFDirectShowPlayer
- DShowPlayer
- WPFWebViewerEVRHandler
- WPFDeviceInfoViewer
- InterProcessRenderer
- WPFAreaScreenRecorder
- WPFHotRecording
- WPFPauseResumeRecording
- WPFViewerTrigger
- UnityVideoAndAudioRecorder
- UnityScreenRecorder
- WPFWindowScreenRecorder
- WPFScreenRecorder
- WPFScreenViewer
- WPFMultiSourceRecorder
- UnityWebCamViewer
- WPFMediaFoundationPlayer
- NativeMediaFoundationPlayer
- WPFVideoAndAudioRecorder
- EVRVieweingAndRecording
- WPFIPCameraMJPEGMultiSourceViewer
- WPFMultiSourceViewer
- WPFViewerEVRDisplay
- WPFIPCameraMJPEGViewer
- WPFImageViewer
- TextInjectorDemo
- WaterMarkInjectorDemo
- WindowsFormsDemo
- CaptureManagerSDKJavaxDemo
- CaptureManagerToJavaProxy
- WPFWebCamSerialShots
- WPFWebCamShot
- CaptureManagerSDKPythonDemo
- QtMinGWDemo
- WPFRecorder
- WPFWebViewerEVR
- WPFWebViewerCallback
- WPFWebViewerCall
- WPFSourceInfoViewer
- CaptureManagerToCSharpProxy
- EVRWebCapViewerViaCOMServer
- OpenGLWebCamViewerViaCOMServer
OpenGLWebCamViewerViaCOMServer
此演示程序仅展示了通过 OpenGL 渲染捕获和查看网络摄像头的简单配置。
要使用
// get COM log interface
CComPtrCustom<iclassfactory> lCoLogPrintOut;
HRESULT lhresult = CoGetClassObject
(CLSID_CoLogPrintOut, CLSCTX_INPROC_SERVER, nullptr, IID_PPV_ARGS(&lCoLogPrintOut));
if (FAILED(lhresult))
return lhresult;
CComPtrCustom<ilogprintoutcontrol> lLogPrintOutControl;
lCoLogPrintOut->LockServer(true);
lhresult = lCoLogPrintOut->CreateInstance(
nullptr,
IID_PPV_ARGS(&lLogPrintOutControl));
if (FAILED(lhresult))
return lhresult;
// set log file for info
lhresult = lLogPrintOutControl->addPrintOutDestination(
(DWORD)INFO_LEVEL,
L"Log.txt");
if (FAILED(lhresult))
return lhresult;
为了获取
CComPtrCustom<IClassFactory> lCoCaptureManager;
lhresult = CoGetClassObject
(CLSID_CoCaptureManager, CLSCTX_INPROC_SERVER, nullptr,
IID_PPV_ARGS(&lCoCaptureManager));
if (FAILED(lhresult))
return lhresult;
lCoCaptureManager->LockServer(true);
// get ICaptureManagerControl interfrace
CComPtrCustom<ICaptureManagerControl> lCaptureManagerControl;
lhresult = lCoCaptureManager->CreateInstance(
nullptr,
IID_PPV_ARGS(&lCaptureManagerControl));
if (FAILED(lhresult))
return lhresult;
此演示程序的拓扑结构如下所示
您可以通过以下链接获取此演示程序
EVRWebCapViewerViaCOMServer
此演示程序展示了通过
此代码允许将此
您可以通过以下链接获取此演示程序
CaptureManagerToCSharpProxy
此演示程序展示了将 CaptureManager.dll 与 C# 项目链接的方式。在此项目中,
您可以从以下链接获取此演示程序
WPFSourceInfoViewer
此演示程序展示了从源收集信息并以可读形式呈现信息的方式。源信息以 XML 文档的形式呈现。使用 XML 格式从 COM 服务器传输信息有一些原因
- 简单结构 - Microsoft Media Foundation 使用大量的 GUID 常量和类型,您需要了解它们才能理解信息,但在此解决方案中,所有这些都以友好的形式呈现。
- 易于从 COM 服务器传输
- 易于解析 - XPath 表达式允许获取几乎所有需要的信息并呈现它,这比使用
static 定义的类和信息列表更容易。 - 在大多数情况下,用户需要读取源支持哪些功能并选择其中之一。
- XML 文档可轻松将源集成到不同演示模型(例如 MVVM)的代码中
此演示程序可从以下链接获取
WPFWebViewerCall
此演示程序展示了通过 C# - WPF 上的 COM 服务器,通过从 WPF 线程调用视频帧来查看网络摄像头实时视频的方式。此代码从
您可以通过以下链接获取此演示程序
WPFWebViewerCallback
此演示程序展示了通过 C# - WPF 上的 COM 服务器,通过从
此演示程序可从以下链接获取
WPFWebViewerEVR
此演示程序展示了通过 C# - WPF 上的 COM 服务器,使用
此演示程序可从以下链接获取
WPFRecorder
此演示程序展示了如何使用
此演示程序的代码展示了通过 COM 服务器接口使用
MFAsyncCallbackQueue
MFASync
MFByteStreamSeekingFlags
MFByteStreamSeekOrigin
MFByteStreamCapabilities
UnmanagedNameAttribute
这些接口的实现可以在文件 NetworkStreamSink.cs 中找到,但我想提请您注意以下几点
- 在
IMFByteStream 接口中,有四个已实现的方法GetCapabilities
Write
BeginWrite
EndWrite
在第一个中,代码设置
IMFByteStream 接口的实现类型 - 可写但不可寻。方法Write 用于同步将数据写入流,而方法BeginWrite 、EndWrite 用于异步写入。但是,有一些重要的时刻:方法Write 在开始时调用一次 - 它写入元数据流的头部:编码器类型、流的数量、流的名称和其他元数据。异步写入需要按以下顺序执行方法:BeginWrite 、参数IMFAsyncCallback pCallback.Invoke 、EndWrite ,但方法BeginWrite 、EndWrite 的调用可以被同一个互斥锁锁定。这意味着参数IMFAsyncCallback pCallback.Invoke 必须在单独的线程中执行 - 例如,通过ThreadPool.QueueUserWorkItem 。 - 在 TCP 服务器的实现中,我使用了
async 调用BeginAcceptTcpClient ,并在每次连接开始时写入头部数据 - 这允许将任意数量的客户端连接到媒体流服务器。public void Start() { try { tcpListener = new TcpListener(Configuration.IPAddress, Configuration.Port); tcpListener.Start(); tcpListener.BeginAcceptTcpClient( new AsyncCallback(callBack), tcpListener); } catch (Exception e) { } } /// <summary> /// Stops the WebServer thread /// </summary> public void Stop() { try { tcpListener.Stop(); foreach (var item in mClientBag) { item.Value.Client.Close(); item.Value.Client.Dispose(); item.Value.Close(); } tcpListener.Server.Dispose(); } catch (Exception e) { } } private void callBack(IAsyncResult aIAsyncResult) { TcpListener ltcpListener = (TcpListener)aIAsyncResult.AsyncState; if (ltcpListener == null) return; TcpClient lclient = null; try { lclient = ltcpListener.EndAcceptTcpClient(aIAsyncResult); } catch (Exception exc) { return; } if (lclient != null && lclient.Client.Connected) { StreamReader streamReader = new StreamReader(lclient.GetStream()); // Read full request with client header StringBuilder receivedData = new StringBuilder(); while (streamReader.Peek() > -1) receivedData.Append(streamReader.ReadLine()); string request = GetRequest(receivedData.ToString()); if (!SuportedMethod(request)) { SendError(StatusCode.BadRequest, "Only GET is supported.", lclient); lclient.Client.Close(); lclient.Close(); } else { Socket socket = lclient.Client; if (socket.Connected) { SendHeader(StatusCode.OK, lclient); lock (this) { if (mHeaderMemory != null) { int sentBytes = socket.Send(mHeaderMemory); } mClientBag[lclient] = lclient; } } } } ltcpListener.BeginAcceptTcpClient( new AsyncCallback(callBack), ltcpListener); }
- 头部包含字节流的 MIME 类型,这允许在未来的版本中将相同的解决方案用于任何类型的媒体容器 - ASF、MP4、MKV。
private void SendHeader(string mimeType, long totalBytes, StatusCode statusCode, TcpClient aTcpClient) { StringBuilder header = new StringBuilder(); header.Append(string.Format("HTTP/1.1 {0}\r\n", GetStatusCode(statusCode))); header.Append(string.Format("Content-Type: {0}\r\n", mimeType)); header.Append(string.Format("Accept-Ranges: bytes\r\n")); header.Append(string.Format("Server: {0}\r\n", Configuration.ServerName)); header.Append(string.Format("Connection: close\r\n")); header.Append(string.Format("Content-Length: {0}\r\n", totalBytes)); header.Append("\r\n"); SendToClient(header.ToString(), aTcpClient); }
此演示程序可从以下链接获取
QtMinGWDemo
此演示程序展示了如何使用 Qt 框架通过 COM 服务器在 C# - WPF 上使用
此演示中的另一个示例展示了将源、编码器和接收器连接到同一个处理管道中的方式。此演示展示了将视频和音频录制到文件中的方式,以及通过 Qt 框架的
您可以从以下链接获取此演示程序
CaptureManagerSDKPythonDemo
此演示程序展示了在 Windows OS 上的 Python 应用程序中,使用
此演示程序可从以下链接下载
WPFWebCamShot
此演示程序展示了使用
此模式与
这种类型对于呈现视频很有用,但捕获单个帧的任务面临下一个困难 - 99% 的帧被捕获、解码并传递到接收器,但客户代码不从接收器中获取它。此任务在现实中可能存在 - 例如,当相机每秒产生 30 帧时,每秒捕获一个帧 - 在这种情况下,CPU 浪费时间和精力在 29 帧上,这些帧将被丢弃。对于此类任务,新模式 -
它允许更有效地利用 CPU 资源仅用于一个任务。新模式也可用于许多图像识别项目 - 此类项目通常以低于相机可产生的帧速率处理帧,但视频管道将花费大量 CPU 资源在不会被处理的帧上。
此演示程序可从以下链接下载
WPFWebCamSerialShots
此演示程序展示了如何使用
它包含两个样本累加器节点,分别存储 5 个和 10 个最后样本。其思想是,在现实世界中,拍照并不是在事件发生的那一刻执行的。人类对事件的反应、按下拍照按钮的过程、将事件从硬件层发送到客户代码层以及请求单个帧需要一些时间——从 500 毫秒到 1 秒。这导致丢失了作为拍照原因的重要时刻。样本累加器节点可以通过累积视频流中的最后样本来补偿这种时间延迟。这些样本可以通过
并接收最后样本
这对于解决某些问题可能很有用,但是样本的累积需要可以快速扩展的内存缓冲区——例如,为了保持 10 个最后 1080p 格式的 RGB32 图像样本,大约需要 60 MB——在这种视频中累积一秒钟可能需要大约 200 MB 或更多。当然,可以创建具有不同方案的样本累加器——例如,每三分之一——这意味着只保留视频流中每三分之一的样本。
您可以通过以下链接获取此演示程序
CaptureManagerToJavaProxy
此演示程序展示了将 CaptureManager.dll 与 Java VM 链接的方式。此项目通过调用 JNI 函数演示了 COM
此代理程序可从以下链接获取
CaptureManagerSDKJavaxDemo
此演示程序展示了通过 Java VM 在 Windows 操作系统上使用网络摄像头的方式。此演示程序允许通过
此外,此演示程序还包括将网络摄像头视频录制到 ASF 视频文件的功能
您可以通过编译可运行 JAR 文件或下载包含 CaptureManagerSDKJavaxDemo.jar 的 CaptureManagerSDKJavaxDemo.jar.zip 来测试此演示程序。VM 的架构 - x86 和 x86-64 - 可能是一个重要的关注点。在大多数情况下,Java 编译的代码可以在两种架构上执行。但是,
我认为你会觉得它非常适合 - 当然,它只在 Windows 7 及更高版本的 Windows 操作系统上可用。
此演示程序可从以下链接下载
WindowsFormsDemo
此演示程序展示了在
此演示程序允许通过
此演示展示了如何选择不同类型的源。目前,
网络摄像头
屏幕 DirectShow
Crossbar
这些源是不同的,并且可能同时连接了其中一些源类型设备。这导致需要一个灵活选择合适源类型组的解决方案。以下生成 XPath 查询的代码在此演示中实现了此功能
string lXPath = "//*[";
if(toolStripMenuItem1.Checked)
{
lXPath += "Source.Attributes/Attribute
[@Name='MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY']
/SingleValue[@Value='CLSID_WebcamInterfaceDeviceCategory']";
}
if (toolStripMenuItem2.Checked)
{
if (toolStripMenuItem1.Checked)
lXPath += "or ";
lXPath += "Source.Attributes/Attribute
[@Name='MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE']
/SingleValue[@Value='Software device']";
}
if (dSCrossbarToolStripMenuItem.Checked)
{
if (toolStripMenuItem1.Checked || toolStripMenuItem2.Checked)
lXPath += "or ";
lXPath += "Source.Attributes/Attribute
[@Name='MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY']
/SingleValue[@Value='CLSID_VideoInputDeviceCategory']";
}
lXPath += "]";
此外,此演示还包括从媒体源录制视频和音频的代码
此演示程序可从以下链接获取
WaterMarkInjectorDemo
此演示程序展示了自定义 Microsoft Media Foundation Transform 与
您可以通过以下链接获取此演示程序
TextInjectorDemo
此演示程序展示了自定义 Microsoft Media Foundation Transform 与
文本字符串内容可以在应用程序端以连续模式更改,并立即显示结果。在此演示程序中,它是通过以下代码完成的
wchar_t ltext[MAXBYTE];
/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
_itow_s(++lFrameCount, ltext, 10);
lITextWriter->writeText(ltext);
Sleep(200);
}
您可以从以下链接获取此演示程序
WPFImageViewer
此演示程序展示了使用
void initilaize(IInitilaizeCaptureSource IInitilaizeCaptureSource)
void pause()
void setCurrentMediaType(ICurrentMediaType aICurrentMediaType)
void shutdown()
void sourceRequest(ISourceRequestResult aISourceRequestResult)
void start(long aStartPositionInHundredNanosecondUnits, ref Guid aGUIDTimeFormat)
void stop()
方法
<!--?xml version='1.0' encoding='UTF-8'?-->
<presentationdescriptor streamcount="1">
<presentationdescriptor.attributes title="Attributes of Presentation">
<attribute description="Contains the unique symbolic link for a
video capture driver." guid="{58F0AAD8-22BF-4F8A-BB3D-D2C4978C6E2F}"
name="MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK"
title="The symbolic link for a video capture driver.">
<singlevalue value="ImageCaptureProcessor">
</singlevalue></attribute>
<attribute description="The display name is a human-readable string,
suitable for display in a user interface."
guid="{60D0E559-52F8-4FA2-BBCE-ACDB34A8EC01}"
name="MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME"
title="The display name for a device.">
<singlevalue value="Image Capture Processor">
</singlevalue></attribute>
</presentationdescriptor.attributes>
<streamdescriptor index="0" majortype="MFMediaType_Video"
majortypeguid="{73646976-0000-0010-8000-00AA00389B71}">
<mediatypes typecount="1">
<mediatype index="0">
<mediatypeitem description="Width and height of a video frame,
in pixels." guid="{1652C33D-D6B2-4012-B834-72030849A37D}"
name="MF_MT_FRAME_SIZE" title="Width and height of the video frame.">
<value.valueparts>
<valuepart title="Width" value="Temp_Width">
<valuepart title="Height" value="Temp_Height">
</valuepart></valuepart></value.valueparts>
</mediatypeitem>
<mediatypeitem description="Approximate data rate of the
video stream, in bits per second, for a video media type."
guid="{20332624-FB0D-4D9E-BD0D-CBF6786C102E}"
name="MF_MT_AVG_BITRATE"
title="Approximate data rate of the video stream.">
<singlevalue value="33570816">
</singlevalue></mediatypeitem>
<mediatypeitem description="The major type defines the
overall category of the media data."
guid="{48EBA18E-F8C9-4687-BF11-0A74C9F96A8F}"
name="MF_MT_MAJOR_TYPE" title="Major type GUID for a media type.">
<singlevalue guid="{73646976-0000-0010-8000-00AA00389B71}"
value="MFMediaType_Video">
</singlevalue></mediatypeitem>
<mediatypeitem description="Default surface stride,
for an uncompressed video media type.
Stride is the number of bytes needed to go from one row of pixels
to the next." guid="{644B4E48-1E02-4516-B0EB-C01CA9D49AC6}"
name="MF_MT_DEFAULT_STRIDE" title="Default surface stride.">
<singlevalue value="Temp_Stride">
</singlevalue></mediatypeitem>
<mediatypeitem description="Specifies for a media type
whether the samples have a fixed size."
guid="{B8EBEFAF-B718-4E04-B0A9-116775E3321B}"
name="MF_MT_FIXED_SIZE_SAMPLES"
title="The fixed size of samples in stream.">
<singlevalue value="True">
</singlevalue></mediatypeitem>
<mediatypeitem description="Frame rate of a video media type,
in frames per second."
guid="{C459A2E8-3D2C-4E44-B132-FEE5156C7BB0}"
name="MF_MT_FRAME_RATE" title="Frame rate.">
<ratiovalue value="10.0">
<value.valueparts>
<valuepart title="Numerator" value="10">
<valuepart title="Denominator" value="1">
</valuepart></valuepart></value.valueparts>
</ratiovalue>
</mediatypeitem>
<mediatypeitem description="Pixel aspect ratio for a
video media type." guid="{C6376A1E-8D0A-4027-BE45-6D9A0AD39BB6}"
name="MF_MT_PIXEL_ASPECT_RATIO" title="Pixel aspect ratio.">
<ratiovalue value="1">
<value.valueparts>
<valuepart title="Numerator" value="1">
<valuepart title="Denominator" value="1">
</valuepart></valuepart></value.valueparts>
</ratiovalue>
</mediatypeitem>
<mediatypeitem description="Specifies for a media type
whether each sample is independent of the other samples
in the stream." guid="{C9173739-5E56-461C-B713-46FB995CB95F}"
name="MF_MT_ALL_SAMPLES_INDEPENDENT" title="Independent of samples.">
<singlevalue value="True">
</singlevalue></mediatypeitem>
<mediatypeitem description="Specifies the size of each sample,
in bytes, in a media type."
guid="{DAD3AB78-1990-408B-BCE2-EBA673DACC10}"
name="MF_MT_SAMPLE_SIZE"
title="The fixed size of each sample in stream.">
<singlevalue value="Temp_SampleSize">
</singlevalue></mediatypeitem>
<mediatypeitem description="Describes how the frames in a
video media type are interlaced."
guid="{E2724BB8-E676-4806-B4B2-A8D6EFB44CCD}"
name="MF_MT_INTERLACE_MODE"
title="Describes how the frames are interlaced.">
<singlevalue value="MFVideoInterlace_Progressive">
</singlevalue></mediatypeitem>
<mediatypeitem description="The subtype GUID defines a
specific media format type within a major type."
guid="{F7E34C9A-42E8-4714-B74B-CB29D72C35E5}"
name="MF_MT_SUBTYPE"
title="Subtype GUID for a media type.">
<singlevalue guid="{Temp_SubTypeGUID}">
</singlevalue></mediatypeitem>
</mediatype>
</mediatypes>
</streamdescriptor>
</presentationdescriptor>
您可以从以下链接下载此演示程序
WPFIPCameraMJPEGViewer
此演示程序展示了使用
void initilaize(IInitilaizeCaptureSource IInitilaizeCaptureSource)
void pause()
void setCurrentMediaType(ICurrentMediaType aICurrentMediaType)
void shutdown()
void sourceRequest(ISourceRequestResult aISourceRequestResult)
void start(long aStartPositionInHundredNanosecondUnits, ref Guid aGUIDTimeFormat)
void stop()
方法
此演示程序可从以下链接获取
WPFViewerEVRDisplay
此演示程序展示了如何使用
此演示程序展示了如何使用
此演示程序可从以下链接获取
WPFMultiSourceViewer
此演示程序展示了如何使用
此演示展示了如何将它们连接到不同的捕获会话并控制目标:大小、位置、比例、刷新。此演示使用屏幕捕获源,以便在没有可访问的 USB 摄像头的情况下也能正常工作。
您可以从以下链接获取此演示程序
WPFIPCameraMJPEGMultiSourceViewer
此演示程序展示了如何使用
您可以从以下链接获取此演示程序
EVRVieweingAndRecording
此演示程序展示了使用
演示程序有控制台界面
此演示程序可从以下链接获取
WPFVideoAndAudioRecorder
此演示程序展示了使用
演示程序具有 WPF GUI,并允许更精确地控制
此演示程序可从以下链接获取
NativeMediaFoundationPlayer
此演示程序展示了如何使用
- 多接收器视频渲染 - 这意味着可以在一个视频上下文中渲染多个视频流。每个视频渲染接收器都具有独立的控制。
- 它可以选择三种视频上下文之一
- 作为渲染目标的窗口句柄
- DirectX9 纹理 - 渲染目标纹理,可用于网格纹理化以进行最终渲染
- DirectX9 SwapChain - DirectX9 渲染器交换链中的渲染目标纹理
- 作为渲染目标的窗口句柄
- 它允许控制渲染的位置、大小和背景颜色。
此演示程序可从以下链接获取
WPFMediaFoundationPlayer
此演示程序展示了如何使用
此演示程序具有 WPF 界面,并展示了如何正确创建具有
此演示程序可从以下链接获取
UnityWebCamViewer
此演示程序展示了在 Windows 操作系统上 Unity 游戏开发 SDK 中使用
此演示程序可从以下链接获取
- 插件 - CaptureManagerWebCamViewerPlugin.zip
- Unity 项目 - UnityWebCamViewer.zip
WPFMultiSourceRecorder
此演示程序展示了将来自多个源的视频和音频数据录制到一个文件中的方法。
源连接的模式如下所示
此演示程序可从以下链接获取
WPFScreenViewer
此演示程序展示了通过添加“normalize”模式来修改“屏幕捕获”源的方式。
“
“
“
“
这样做是为了保持视频编码的最大质量。
“
if ((bool)mNormalizeChkBtn.IsChecked)
lextendSymbolicLink += " --normalize=Landscape";
启用此模式将导致以下结果
“
“
“
“
您可以从以下链接获取此演示程序
WPFScreenRecorder
此演示程序展示了“屏幕捕获”源选项的设置方式。
“
- “
Rectangle ” - 填充形状为矩形 - “
Ellipse ” - 填充形状为椭圆形
它允许设置背景图像的矩形形状
或背景图像的椭圆形形状
“
新选项的 XML 形式为
<Option Type='Clip' >
<Option.Extensions>
<Extension Left='0' Top='0' Height='100' Width='100' />
</Option.Extensions>
</Option>
此演示程序可从以下链接获取
WPFWindowScreenRecorder
此演示程序展示了“屏幕捕获”源选项的设置方式,用于捕获所选应用程序窗口的屏幕视图。
通过单击“按单击选择”按钮开始选择源应用程序窗口 - 它初始化 Windows OS API 以获取鼠标指针下的窗口的
通过按下键盘“L”键来捕获窗口的
选择窗口后,可以应用“屏幕捕获”源的选项,以设置光标背景蒙版和裁剪感兴趣区域
通过向“屏幕捕获”符号链接添加参数“
lextendSymbolicLink += " --HWND=" + m_CurrentHWND.ToInt32().ToString();
此演示程序可从以下链接下载
UnityScreenRecorder
此演示程序展示了在 Windows 操作系统上 Unity 游戏开发 SDK 中使用
此演示程序支持两种工作模式
第一种模式 - 捕获并渲染图像以检查捕获处理器功能的正确性
第二种模式 - 录制,并选择编码器和输出格式文件
此演示程序可从以下链接获取
- 插件 - CaptureManagerUnityScreenRecorderPlugin.zip
- Unity 项目 - UnityScreenRecorder.zip
UnityVideoAndAudioRecorder
此演示程序展示了在 Windows 操作系统上 Unity 游戏开发 SDK 中查看和录制来自外部源的视频和音频的方式。
此演示程序可从以下链接获取
WPFViewerTrigger
此演示程序展示了如何使用切换器节点。此代码使用两个输出节点从源获取图像:EVR 和 Sample Grabber。Sample Grabber 以 1 秒的间隔获取样本并检查样本中的平均亮度 - 如果该值大于或等于阈值,则切换器节点被设置为开启,EVR 以 30 fps 获取样本。如果该值小于阈值,则切换器节点被设置为关闭,EVR 不获取任何东西。此模式如下所示
结果演示如下所示
此演示程序可从以下链接下载
WPFPauseResumeRecording
此演示程序展示了切换器节点的使用方式。切换器设置在录制流中,允许暂停/恢复此视频流,而 EVR 预览流仍以独立连续模式工作。
此演示程序可从以下链接下载
WPFHotRecording
此演示程序展示了如何在不停止源的情况下,在运行时使用切换器节点将录制流附加和分离到源。
此类解决方案对于固定大小的媒体文件录制任务可能很有用——当当前录制媒体文件的大小达到阈值时,当前文件将被分离,新文件将被附加到录制流中。
在此演示程序中,切换器节点(用于视频和音频流)是在没有录制媒体文件的情况下创建的——这是可能的。通过点击“开始录制”按钮来附加新的录制媒体文件。旧文件(如果存在)将被分离。
此演示程序可从以下链接下载
WPFAreaScreenRecorder
此演示程序展示了屏幕捕获源的使用方式。前段时间,我需要一个屏幕录像机应用程序,并尝试开发一个简单的应用程序,它可以覆盖几乎 99% 的其他类似应用程序的功能,但只使用
它通过“橡皮筋矩形”进行剪裁
它按当前日期生成文件名
它具有显示和隐藏光标图标和背景图像蒙版的配置
它具有带设置压缩质量的视频编码器配置
它具有配置选择输出文件格式和选择目录以存储录制的视频文件
当前配置可以保存并重置为默认值。
您可以从以下链接获取此演示程序
InterProcessRenderer
这些演示程序展示了如何使用 DirectX9 纹理共享句柄在两个进程之间共享渲染上下文。它们包括
private Direct3DSurface9 GetSharedSurface(Direct3DDevice9Ex device)
{
return device.CreateRenderTarget(
m_width,
m_height,
Format, // D3DFMT_A8R8G8B8
0,
0,
0 // UNLOCKABLE
);
}
每个
此解决方案允许分离用户界面进程和捕获渲染进程
mOffScreenCaptureProcess = new Process();
mOffScreenCaptureProcess.StartInfo.FileName = "InterProcessRenderer.exe";
mOffScreenCaptureProcess.EnableRaisingEvents = true;
mOffScreenCaptureProcess.Exited += mOffScreenCaptureProcess_Exited;
mPipeProcessor = new PipeProcessor(
"Server",
"Client");
mPipeProcessor.MessageDelegateEvent += lPipeProcessor_MessageDelegateEvent;
mOffScreenCaptureProcess.StartInfo.Arguments =
"SymbolicLink=" + aSymbolicLink + " " +
"StreamIndex=" + aStreamIndex + " " +
"MediaTypeIndex=" + aMediaTypeIndex + " " +
"WindowHandler=" + mVideoPanel.Handle.ToInt64();
mOffScreenCaptureProcess.StartInfo.UseShellExecute = false;
try
{
mIsStarted = mOffScreenCaptureProcess.Start();
HeartBeatTimer.Start();
}
catch (Exception)
{
mIsStarted = false;
}
这些演示程序可从以下链接获取
WPFDeviceInfoViewer
此演示程序展示了按唯一设备 ID 分组视频和音频源的方式。Windows 操作系统中的每个设备都有一个唯一的设备 ID 来标识每个设备。此演示程序显示此 ID 并根据此 ID 对设备进行分组。
此解决方案对于来自同一供应商的许多视频和音频 USB 源的任务可能很有用 - 此代码允许根据所属的真实 USB 设备对视频和音频源进行分组。
您可以从以下链接获取此演示程序
WPFWebViewerEVRHandler
此演示程序展示了如何使用 DirectX9 纹理共享句柄进行渲染。当前一代的 Windows 操作系统具有在不同版本的 DirectX 之间共享渲染纹理的功能。
您可以通过以下链接获取此演示程序
DShowPlayer
此演示程序展示了如何在 C++ Window 应用程序项目中使用
HRESULT hr = S_OK;
IBaseFilter *pEVR = NULL;
//hr = AddFilterByCLSID(pGraph, CLSID_EnhancedVideoRenderer, &pEVR, L"EVR");
unsigned long lPtrOutputNodeAmount = 0;
CaptureManagerLoader::getInstance().getMaxVideoRenderStreamCount
(&lPtrOutputNodeAmount);
std::vector<CComPtrCustom<IUnknown>> lOutputNodes;
CaptureManagerLoader::getInstance().createRendererOutputNodes(
hwnd,
nullptr,
1,
lOutputNodes);
if (!lOutputNodes.empty())
{
lOutputNodes[0]->QueryInterface(IID_PPV_ARGS(&pEVR));
}
CHECK_HR(hr = pGraph->AddFilter(pEVR, L"EVR"));
您可以从以下链接获取此演示程序
WPFDirectShowPlayer
此演示程序展示了如何在 WPF 应用程序中使用
List<object> lOutputNodesList = new List<object>();
lCaptureManagerEVRMultiSinkFactory.createOutputNodes(
IntPtr.Zero,
mEVRDisplay.Surface.texture,
1,// lMaxVideoRenderStreamCount,
out lOutputNodesList);
if (lOutputNodesList.Count == 0)
return;
IBaseFilter lVideoMixingRenderer9 = (IBaseFilter)lOutputNodesList[0];
var h = m_pGraph.AddFilter(lVideoMixingRenderer9, "lVideoMixingRenderer9");
此演示程序可从以下链接获取
WPFRtspServer
此演示程序展示了在 RTSP 流媒体服务中使用
ISampleGrabberCallback lH264SampleGrabberCallback;
aISampleGrabberCallbackSinkFactory.createOutputNode(
MFMediaType_Video,
MFVideoFormat_H264,
out lH264SampleGrabberCallback);
object lOutputNode = lEVROutputNode;
if (lH264SampleGrabberCallback != null)
{
uint ltimestamp = 0;
lH264SampleGrabberCallback.mUpdateEvent += delegate
(byte[] aData, uint aLength)
{
if (s != null)
{
ThreadPool.QueueUserWorkItem((object state) =>
{
s.sendData(aIndexCount, ltimestamp, aData);
ltimestamp += 33;
});
}
};
以及音频流
ISampleGrabberCallback lAACSampleGrabberCallback;
aISampleGrabberCallbackSinkFactory.createOutputNode(
MFMediaType_Audio,
MFAudioFormat_AAC,
out lAACSampleGrabberCallback);
if (lAACSampleGrabberCallback != null)
{
lAACSampleGrabberCallback.mUpdateFullEvent += delegate
(uint aSampleFlags, long aSampleTime,
long aSampleDuration, byte[] aData, uint aLength)
{
if (s != null)
{
ThreadPool.QueueUserWorkItem((object state) =>
{
s.sendData(aIndexCount,
(uint)aSampleTime / 100000, aData);
});
}
};
此 SDK 与 SharpRTSP 代码的结合允许创建可工作的 RTSP 视频和音频流媒体服务器版本
为了支持广泛的解码器,
您可以从以下链接获取演示程序
WPFRTSPClient
此演示程序展示了在 RTSP 流媒体服务中使用
您可以从以下链接获取演示程序
WPFStreamer
此演示程序展示了在 RTMP(实时消息协议 (RTMP) 最初是 Macromedia 开发的一种专有协议,用于在 Flash 播放器和服务器之间通过互联网流式传输音频、视频和数据。Macromedia 现已归 Adobe 所有,Adobe 发布了该协议规范的不完整版本供公众使用)流媒体服务(Facebook (RTMPS)、YouTube 等)中使用
您可以从以下链接获取演示程序
WPFMixer
此演示程序展示了如何使用
IMixerNodeFactory
IVideoMixerControl
IAudioMixerControl
允许将多个视频流合并为一个视频流,并将多个音频流合并为一个音频流。
setPosition - 设置输入视频流在背景参考视频流上的位置setSrcPosition - 设置输入视频流中的区域setZOrder - 设置混音器的 Z 顺序setOpacity - 设置输入视频流的不透明度flush - 清空视频输入流缓冲区
public interface IVideoMixerControl
{
bool setPosition(object aPtrVideoMixerNode,
/* [in] */ float aLeft,
/* [in] */ float aRight,
/* [in] */ float aTop,
/* [in] */ float aBottom);
bool setSrcPosition(object aPtrVideoMixerNode,
/* [in] */ float aLeft,
/* [in] */ float aRight,
/* [in] */ float aTop,
/* [in] */ float aBottom);
bool setZOrder(object aPtrVideoMixerNode,
/* [in] */ UInt32 aZOrder);
bool setOpacity(object aPtrVideoMixerNode,
/* [in] */ float aOpacity);
bool flush(object aPtrVideoMixerNode);
}
接口
public interface IAudioMixerControl
{
bool setRelativeVolume(object aPtrAudioMixerNode, float aRelativeVolume);
}
您可以从以下链接获取演示程序
WPFGIFtoVideo
此演示程序展示了如何使用
此演示程序可从以下链接下载
AudioCaptureProcessor
此演示程序展示了如何使用
您可以从以下链接获取此演示程序
WPFStreamingAudioRenderer
此演示程序展示了如何通过
此演示程序可从以下链接下载
WPFVirtualCamera
此演示程序展示了如何创建“虚拟摄像头”的
然而,此演示程序展示了一个更复杂的产品 - 此演示分为两个项目:C# DirectShow 过滤器和 WPF/C# 进程外 COM 服务器。这种魔力是通过使用 DirectX 11 的 Windows 操作系统跨进程渲染技术实现的。
编译此演示后,Bin 文件夹中有两个基本文件
- WPFVirtualCameraServer.exe - 进程外 COM 服务器
- VirtualCameraDShowFilter.dll - 进程内
DirectShow 过滤器
要将此演示安装到目标 Windows 操作系统中,需要执行 install.bat 脚本文件。
要从 Windows 操作系统中卸载此演示,需要执行 uninstall.bat 脚本文件。
因此,由于
此生成和注册在脚本 install.bat 中执行。执行 install.bat 后,此视频摄像头的软件仿真将显示为“
同时,Windows 操作系统启动后台进程
它是如何工作的?!当网络摄像头应用程序将 VirtualCameraDShowFilter.dll 识别为真实的视频源时,此 DLL 会调用 Windows OS 通过
VirtualCameraDShowFilter.dll 将通过
[ComVisible(false)]
[Guid("EEE2F595-722F-4279-B919-313189A72C36")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IVirtualCameraServer
{
IntPtr get_DirectX11TextureHandler(out int retVal);
}
方法
。鼠标指针双击此图标的左键可显示 WPF UI,用于控制跨进程渲染 - 渲染的位置和大小
鼠标指针在
此解决方案允许将一个真实视频源复制到多个网络摄像头应用程序
进程交互时间线图展示了
此演示程序可从此处获取 。
WPFWebViewerEVRLog4net
此演示程序展示了将 log4net 框架集成到使用
[
object,
uuid(251E71F6-8C02-475F-B300-216D560426B2),
oleautomation,
helpstring("Interface for processing callback of log.")
]
interface ILogPrintOutCallback : IUnknown
{
[
helpstring("Method for callback invoking.")
]
HRESULT invoke(
[in] DWORD aLevelType,
[in] BSTR aPtrLogString);
};
在项目中,此新接口以以下方式实现
LogManager.getInstance().WriteLogDelegateEvent += (aLogLevel, aPtrLogString)=>
{
switch (aLogLevel)
{
case CaptureManagerToCSharpProxy.WrapClasses.LogLevel.INFO_LEVEL:
log.Info(aPtrLogString);
break;
case CaptureManagerToCSharpProxy.WrapClasses.LogLevel.ERROR_LEVEL:
log.Error(aPtrLogString);
break;
default:
break;
}
};
您可以从以下链接获取此演示程序
WPFHardwareButtonTrigger
此演示程序展示了如何将网络摄像头硬件按钮按下事件处理添加到使用
void UpdateStateDelegate(uint aCallbackEventCode, uint aSessionDescriptor) { SessionCallbackEventCode k = (SessionCallbackEventCode)aCallbackEventCode; switch (k) { case SessionCallbackEventCode.Unknown: break; case SessionCallbackEventCode.Error: break; case SessionCallbackEventCode.Status_Error: break; case SessionCallbackEventCode.Execution_Error: break; case SessionCallbackEventCode.ItIsReadyToStart: break; case SessionCallbackEventCode.ItIsStarted: break; case SessionCallbackEventCode.ItIsPaused: break; case SessionCallbackEventCode.ItIsStopped: break; case SessionCallbackEventCode.ItIsEnded: break; case SessionCallbackEventCode.ItIsClosed: break; case SessionCallbackEventCode.VideoCaptureDeviceRemoved: { Dispatcher.Invoke( DispatcherPriority.Normal, new Action(() => mLaunchButton_Click(null, null))); } break; case SessionCallbackEventCode.SnapTrigger: MessageBox.Show("Hardware button is pressed!!!"); break; default: break; } }
您可以从以下链接获取此演示程序
CaptureManager SDK 版本
版本 1.0.0
Capture Manager SDK v1.0.0 – 公开版本。我包含了具有稳定定义的接口
通过类
通过类
方法
ISourceControl
,ISinkColtrol
,IEncoderControl
,ISessionControl
,IStreamControl
;
方法
IMediaTypeParser
IStrideForBitmap
IVersionControl
通过具有接口
IWebCamControl
通过具有接口
IFileSinkFactory
ISampleGrabberCallSinkFactory
IEVRSinkFactory
ISampleGrabberCallbackSinkFactory
IByteStreamSinkFactory
通过具有接口
ISessionCallback
通过具有接口
ISampleGrabberCall
通过具有接口
ISampleGrabberCallback
这些接口执行以下工作
ILogPrintOut – 它管理日志信息的写入ICaptureManagerControl – 它管理所有捕获控件和杂项对象的创建ISourceControl – 它管理和创建视频和音频信号源ISinkColtrol – 它管理和创建视频和音频流的接收器IEncoderControl – 它管理和创建视频和音频编码器ISessionControl – 它创建用于管理录制会话的对象IStreamControl – 它创建用于控制媒体流的对象IMediaTypeParser – 它创建 XML 格式的媒体类型的文本表示IStrideForBitmap – 它计算特定位图格式的内存步幅IVersionControl – 它管理有关CaptureManager 当前版本的信息IWebCamControl – 它管理网络摄像头的选项IFileSinkFactory – 它创建与媒体文件链接的媒体接收器节点ISampleGrabberCallSinkFactory – 它通过直接调用具有接口ISessionCallback 的对象来创建用于抓取单个样本的媒体接收器ISampleGrabberCall – 它管理单个样本的抓取ISampleGrabberCallbackSinkFactory – 它通过从CaptureManager 内部线程调用具有接口ISampleGrabberCallback 的对象来创建用于抓取单个样本的媒体接收器ISampleGrabberCallback – 它管理从CaptureManager 内部线程抓取单个样本IEVRSinkFactory – 它创建用于渲染视频流的媒体接收器IByteStreamSinkFactory – 它创建与自定义字节流对象(具有接口IMFByteStream )链接的媒体接收器节点ISession – 它管理录制会话ISessionCallback – 它管理从CaptureManager 内部线程获取的当前录制会话的结果状态
这些接口的定义在 SDK 文件和
<!--?xml version="1.0" ?-->
<!--XML Document of sources-->
这些文档包含有关源、编码器、接收器、流控制的信息。大多数类型和 GUID 取自 Microsoft Media Foundation MSDN:Microsoft Media Foundation,但这些 XML 文档中节点定义有一些规则
SingleValue - 仅用于呈现一个值的节点 - 名称、整数、类型RatioValue - 以分子和分母表示浮点格式值的节点Value.ValueParts - 用于存储具有相同类型的ValuePart 节点集合的节点。这些 XML 文档的解析示例可以在 WPF 示例代码中找到。
版本 1.1.0,带 HEVC(H265) 编码器
- 添加支持
CaptureManager 作为 COM 服务器自动注册类型库 - 添加对动态语言 Python 2.7 的支持
- 在 Windows 10 中添加对 HEVC(H265) 编码器的支持:下载 HEVCEncoder_Windows10
版本 1.2.0 Beta
- 删除了通过库链接使用
CaptureManager 的旧功能。旧的演示程序已移至旧的演示。 - Microsoft Media Foundation 函数的延迟绑定。
- 将网络摄像头属性功能从 DirectShow 替换为
DeviceIoControl 。 - EVR 中添加了调整大小功能。
函数延迟绑定是通过在运行时加载 Microsoft Media Foundation 库实现的。在 Microsoft Media Foundation 库中找不到的函数将替换为存根函数。这可以防止由于使用不支持的 Microsoft Media Foundation 库函数而导致应用程序崩溃。
使用
EVR 中的调整大小解决了渲染视频图像大小不变的问题。新实现控制渲染器 GUI 的当前图像大小,并更改图像大小和位置以保持视频比例。
版本 1.2.0
- 删除了通过库链接使用
CaptureManager 的旧功能。旧的演示程序已移至旧的演示。 - Microsoft Media Foundation 函数的延迟绑定。
- 将网络摄像头属性功能从
DirectShow 替换为DeviceIoControl 。 - EVR 中添加了调整大小功能。
- 在
SampleGrabberCallSinkFactory 中添加了PULL 模式 - 允许获取单个样本的新模式。 - 添加了样本累加器节点,用于在媒体流中存储最后 5 或 10 个样本。
函数延迟绑定是通过在运行时加载 Microsoft Media Foundation 库实现的。在 Microsoft Media Foundation 库中找不到的函数将替换为存根函数。这可以防止由于使用不支持的 Microsoft Media Foundation 库函数而导致应用程序崩溃。
使用
EVR 中的调整大小解决了渲染视频图像大小不变的问题。新实现控制渲染器 GUI 的当前图像大小,并更改图像大小和位置以保持视频比例。
版本 1.3.0 Beta,带 DirectShow Crossbar 捕获
- 添加支持通过 DirectShow Crossbar 技术捕获以下输入的视频
- 复合
- SVideo
- USB
- 1394 (火线)
在 MSDN 上 - Media Foundation 中的音频/视频捕获,您可以发现“视频捕获设备通过 UVC 类驱动程序支持,并且必须与 UVC 1.1 兼容”。这意味着 Microsoft Media Foundation 只能从支持 UVC 驱动程序的设备捕获视频 - USB 视频类驱动程序。它通常是 USB 网络摄像头 - 其他类型的视频捕获设备不受支持。根据我的经验,我可以说明 Microsoft Media Foundation 的目标平台是 WindowsStore 应用程序。WindowsStore 应用程序最初面向“平板” - “Surface”等便携式设备 - 此类设备没有用于连接捕获卡的外部端口。它们只能使用通过内部 USB 端口连接的嵌入式网络摄像头。我认为这是一个正确的想法,但我收到了许多关于将
<MediaTypeItem Name="DirectShowPhysicalType"
GUID="{09FCAE6B-8F00-4C0A-BBCA-C6820B576C99}"
Title="Physical type of input pin of Crossbar."
Description="Physical type of input pin of Crossbar.">
<SingleValue Value="PhysConn_Video_Composite" />
</MediaTypeItem>
版本 1.3.0,带 DirectShow Crossbar 捕获
- 添加支持通过
DirectShow Crossbar 技术捕获以下输入的视频- 复合
- SVideo
- USB
- 1394 (火线)
- COM
ThreadingModel 已从Apartment 更改为Both 。
版本 1.4.0 Beta
- 添加支持更改屏幕捕获源中光标的呈现方式:使光标不可见,并为当前光标图像添加绘制附加图像
此功能通过在符号链接中添加
<!--?xml version='1.0' encoding='UTF-8'?-->
<Options>
<Option Type="Cursor" Visiblity="True">
<Option.Extensions>
<Extension Fill="0x7055ff55" Height="100" Type="BackImage" Width="100"/>
</Option.Extensions>
</Option>
</Options>
通过
"<Extension Type='BackImage' Height='100' Width='100' Fill='0x7055ff55' />"
属性
“
string lextendSymbolicLink = lSymbolicLink + " --options=" +
"<?xml version='1.0' encoding='UTF-8'?>" +
"<Options>" +
"<Option Type='Cursor' Visiblity='True'>" +
"<Option.Extensions>" +
"<Extension Fill='0x7055ff55' Height='100'
Type='BackImage' Width='100'>" +
"</Extension> +
</Option.Extensions>" +
"</Option>" +
"</Options>";
版本 1.4.0
- 添加支持更改屏幕捕获源中光标的呈现方式:使光标不可见,并为当前光标图像添加绘制附加图像。
- 添加支持使用自定义 Microsoft Media Foundation Transform 来实现自定义效果(例如 - WaterMarkInjectorDemo,TextInjectorDemo)。
版本 1.5.0
- 添加支持多显示器输出
- 添加对
DirectShow 软件过滤器的支持。
版本 1.6.0
Capture Manager SDK v1.6.0。此版本包括以下更改
- 添加
IEVRMultiSinkFactory 、IEVRStreamControl 接口:IEVRMultiSinkFactory 允许为单个渲染上下文(窗口的HWND 、Direct3DSurface9 或IDXGISwapChain )创建两个分离的拓扑节点。IEVRStreamControl 允许控制渲染结果 - 渲染位置、Z 顺序渲染、流缓冲区刷新、过滤器和功能。 IInitilaizeCaptureSource 、ICurrentMediaType 、ISourceRequestResult 、ICaptureProcessor 接口:IInitilaizeCaptureSource 接收捕获处理器的配置。ICurrentMediaType 包含所选媒体类型的信息。ISourceRequestResult 接收以IInitialazeCaptureSource 中定义的格式的原始数据。ICaptureProcessor 控制捕获过程。
从文件播放视频可能没问题,但在处理具有不同延迟的源(例如一个来自本地网络摄像头,另一个通过HTTP来自IP摄像头)时,该怎么办?另一个问题是,如果我们只想停止一个源,代码会停止会话中的所有源。解决这些问题的方法是为每个源使用不同的独立会话,但Microsoft Media Foundation的常见实现不允许通过多个会话共享视频渲染接收器。CaptureManager
通过增加一个抽象层来解决这些问题——虽然Microsoft Media Foundation的常见实现从一个视频上下文创建一个视频渲染媒体接收器,但CaptureManager
从控制器创建多个视频渲染媒体接收器,这些接收器共享同一个视频上下文。
额外的层允许更灵活地管理渲染。用于测试此功能的演示程序可以在WPFMultiSourceViewer中找到。CaptureManager
免费版支持从一个渲染上下文最多渲染两个接收器。`Sink Factories` 中的`MultiRendering` 由新的`Sink Factory` 节点表示。
<sinkfactory guid="{10E52132-A73F-4A9E-A91B-FE18C91D6837}"
name="EVRMultiSinkFactory" title="Enhanced Video Renderer multi sink factory">
<value.valueparts>
<valuepart description="Default EVR implementation"
guid="{E926E7A7-7DD0-4B15-88D7-413704AF865F}"
maxportcount="2" mime="" title="Container format" value="Default">
</valuepart>
</value.valueparts>
</sinkfactory>
渲染可以通过IEVRStreamControl
接口控制。
setPosition
方法允许在共享渲染上下文中以0.0f到1.0f的相对值定位渲染。getPosition
方法允许在共享渲染上下文中以0.0f到1.0f的相对值获取渲染位置。setZOrder
方法允许设置流的渲染顺序,从0到最大渲染接收器。getZOrder
方法允许获取流的渲染顺序,从0到最大渲染接收器。flush
方法允许清除渲染接收器的渲染缓冲区。setSrcPosition
方法允许在输入流中设置矩形以选择感兴趣区域。getSrcPosition
方法允许在输入流中获取矩形以选择感兴趣区域。getCollectionOfFilters
方法允许获取包含当前渲染接收器过滤器列表的XML字符串。<!--?xml version="1.0" ?--> <!-- XML Document of render stream filters --> <filters> <filter currentvalue="" max="" min="" step="" title=""> </filter></filters>
setFilterParametr
方法允许为当前渲染接收器设置过滤器。getCollectionOfOutputFeatures
方法允许获取包含渲染上下文输出功能列表的XMLstring
。<!--?xml version="1.0" ?--> <!-- XML Document of render stream output features --> <features> <feature title="Background Color"> <color> <channel currentvalue="0" index="1" max="255" min="0" step="1" title="Red"> <channel currentvalue="0" index="2" max="255" min="0" step="1" title="Green"> <channel currentvalue="0" index="3" max="255" min="0" step="1" title="Blue"> </channel></channel></channel></color> </feature> </features>
setOutputFeatureParametr
方法允许为渲染上下文设置输出功能;CaptureManager
具有从自定义捕获处理器捕获数据的功能。它包括用于实现自定义CaptureProcessor
类的ICaptureProcessor
接口。所需的配置在initialize
方法的参数中通过IInitilaizeCaptureSource
接口设置。所选配置在setCurrentMediaType
方法的参数中通过ICurrentMediaType
接口设置。所需数据在sourceRequest
方法中通过ISourceRequestResult
接口的参数请求。它允许开发捕获原始数据的解决方案,例如WPFImageViewer或WPFIPCameraMJPEGViewer。
版本 1.7.0
CaptureManager
SDK v1.7.0。此版本包含以下更改:
- 添加了与
MediaFoundation
播放器兼容的CaptureManager
视频渲染器工厂。它通过额外的接收器工厂支持IEVRMultiSinkFactory
和IEVRStreamControl
接口。
<SinkFactory Name="CaptureManagerVRMultiSinkFactory"
GUID="{A2224D8D-C3C1-4593-8AC9-C0FCF318FF05}"
Title="CaptureManager Video Renderer multi sink factory">
<Value.ValueParts>
<ValuePart Title="Container format" Value="Default"
MIME="" Description="Default EVR implementation"
MaxPortCount="2" GUID="{E926E7A7-7DD0-4B15-88D7-413704AF865F}" />
</Value.ValueParts>
</SinkFactory>
添加了以下新的演示程序:
- WPFMediaFoundationPlayer
- NativeMediaFoundationPlayer
- WPFVideoAndAudioRecorder
- EVRVieweingAndRecording
CaptureManager
视频渲染器工厂可用于在许多解决方案中实现用于从媒体文件渲染视频的视频接收器。
版本 1.8.0
CaptureManager
SDK v1.8.0。此版本包含以下更改:
- 为“屏幕捕获”源添加了“normalize”模式
- 添加了
IRenderingControl
接口,用于控制目标进程上的渲染 - 为“屏幕捕获”源的“光标”选项添加了“形状”属性
- 为“屏幕捕获”源添加了“剪辑”类型选项
添加了以下新的演示程序:
“屏幕捕获”源支持按原样捕获屏幕——这意味着旋转的图像按计算机创建时旋转的方式获取。然而,在某些情况下,可能需要以特定的图像方向获取图像,例如,以“横向”形式获取“纵向”屏幕。为此,“屏幕捕获
”源支持“normalize
”模式,用于将当前图像后处理到所需方向:“--normalize=Landscape
”。
“屏幕捕获”源支持背部图像的额外形状——“椭圆”,以及新选项“剪辑”。
新的IRenderingControl
接口是从ICaptureManagerControl::createMisc
方法创建的,并扩展了渲染过程的控制。IRenderingControl
接口具有以下签名:
MIDL_INTERFACE("1CBCAF1C-1809-41DE-A728-23DBF86A6170")
IRenderingControl : public IDispatch
{
public:
virtual /* [id][helpstring] */ HRESULT STDMETHODCALLTYPE enableInnerRendering(
/* [in] */ IUnknown *aPtrEVROutputNode,
/* [in] */ BOOL aIsInnerRendering) = 0;
virtual /* [id][helpstring] */ HRESULT STDMETHODCALLTYPE renderToTarget(
/* [in] */ IUnknown *aPtrEVROutputNode,
/* [in] */ IUnknown *aPtrRenderTarget,
/* [in] */ BOOL aCopyMode) = 0;
};
方法enableInnerRendering
允许在CaptureManager
中切换渲染模型。方法renderToTarget
允许从用户渲染线程执行到目标纹理的渲染。
引入新接口来控制渲染的原因是DirectX的线程安全。在CaptureManager
的早期版本中,渲染是在CaptureManager
内部线程的上下文中执行的。在大多数情况下,这种渲染方式不会导致问题——在演示程序中,DirectX9设备是支持多线程创建的,DirectX11设备默认是线程安全的。然而,在修改UnityWebCamViewer演示项目以包含DirectX11渲染时,我遇到了渲染问题。经过一些代码搜索,我发现ID3D11Device::CreateDeferredContext
返回错误DXGI_ERROR_INVALID_CALL
——根据此链接——“如果设备是使用D3D11_CREATE_DEVICE_SINGLETHREADED值创建的,CreateDeferredContext
返回DXGI_ERROR_INVALID_CALL
。”这意味着Unity引擎不支持从非渲染线程更新纹理。IRenderingControl
接口允许从多线程渲染切换到单线程渲染模式。默认情况下,CaptureManager
具有多线程渲染,可以通过方法enableInnerRendering
将aIsInnerRendering
设置为FALSE
来切换到单线程渲染。方法renderToTarget
允许在单个渲染线程的上下文中渲染到目标——对于目标,可以使用DirectX9
的接口IDirect3DTexture9
或DirectX11
的接口ID3D11Texture2D
渲染纹理。对于DirectX9
,参数aCopyMode
必须设置为FALSE
。对于DirectX11
,参数aCopyMode
可以是TRUE
或FALSE
——这取决于渲染纹理的类型。DirectX11
允许创建TYPELESS
纹理格式以实现类型的灵活转换。但是,DirectX11
视频处理器仅支持UNORM
类型的渲染纹理。Unity引擎使用TYPELESS
纹理格式创建渲染纹理——这会导致错误。将参数aCopyMode
设置为TRUE
允许创建额外的UNORM
类型纹理,并将此纹理用作渲染目标,然后从该纹理复制到原始的TYPELESS
纹理格式渲染纹理。此操作在GPU上下文中执行得非常快。
您可以从此处下载CaptureManager
帮助文件。
版本 1.9.0
CaptureManager
SDK v1.9.0。此版本包含以下更改:
- 为“屏幕捕获”源添加了“
HWND
”模式。
添加了新的演示程序。
- 添加了WPFWindowScreenRecorder演示程序。
- 添加了UnityScreenRecorder演示程序。
版本 1.10.0
CaptureManager
SDK v1.10.0。此版本包含以下更改:
- 添加了
ISwitcherNodeFactory
接口用于媒体流的暂停/恢复 - 添加了
ISwitcherControl
接口用于控制(暂停、恢复、分离、连接)媒体流
添加了新的演示程序。
版本 1.11.0
CaptureManager
SDK v1.11.0。此版本包含以下更改:
- 添加了DirectX11纹理捕获
- 屏幕捕获输出格式从RGB32更改为NV12
版本 1.12.0
CaptureManager
SDK v1.12.0。此版本包含以下更改:
- 添加了带有唯一设备ID的
CM_DEVICE_LINK
属性 - 支持
DirectX9Ex
纹理共享处理器
添加了以下新的演示程序:
版本 1.13.0
CaptureManager
SDK v1.13.0。此版本包含以下更改:
- 添加了对
DirectShow
视频渲染器的支持
添加了以下新的演示程序:
版本 1.14.0
CaptureManager
SDK v1.14.0。此版本包含以下更改:
- 添加了H.264/MPEG-4 AVC视频流编码器(从256 kbit/c到64 kbit/c)
- 添加了H.265/MPEG-4 HEVC视频流编码器(64 kbit/c)
- 添加了AAC音频流编码器(96 kbit/c)
- 添加了视频流解码器
添加了以下新的演示程序:
版本 1.15.0
CaptureManager
SDK v1.15.0。此版本包含以下更改:
- 添加了快速SSE2/SSSE3/SSE4.2复制功能
版本 1.16.0
CaptureManager
SDK v1.16.0。此版本包含以下更改:
- 添加了用于混合视频和音频流的接口
IMixerNodeFactory
IVideoMixerControl
IAudioMixerControl
添加了以下新的演示程序:
版本 1.17.0
CaptureManager
SDK v1.17.0。此版本包含以下更改:
- H264和H265视频编码器比特率扩展至2^25 (33,554,432)
版本 1.18.0
Capture Manager SDK v1.18.0。此版本包含以下更改:
- 添加了音频渲染器
添加了新的演示程序
版本 1.19.0
Capture Manager SDK v1.19.0。此版本包含以下更改:
- 添加了H264网络摄像头的支持
版本 1.19.1
CaptureManager
SDK v1.19.1。此版本包含以下更改:
- 修复了拉取模式的bug
- 修复了摄像机已被占用时无法打开的bug
版本 1.20.0
CaptureManager
SDK v1.20.0。此版本包含以下更改:
- 添加了async/await调用模型
版本 1.21.0
CaptureManager
SDK v1.21.0。此版本包含以下更改:
- 将
DirectX9
渲染替换为DirectX11
渲染。
添加了新的演示程序。
版本 1.22.0
CaptureManager
SDK v1.22.0。此版本包含以下更改:
- 添加了新接口
ILogPrintOutCallback
。
添加了新的演示程序
版本 1.23.0
CaptureManager
SDK v1.23.0。此版本包含以下更改:
- 改进了对VMware虚拟机的支持。
版本 1.24.0
CaptureManager
SDK v1.24.0。此版本包含以下更改:
- 增加硬件按钮触发事件支持。
添加了新的演示程序
关注点
此前,我曾写道,有一个不寻常的任务,这就是开始开发CaptureManager
的原因。该任务包括从两个来源录制工业过程的实时视频以及从两个传感器录制数据。我开始为Microsoft Media Foundation编写一个新解决方案,并考虑使用Microsoft ASF格式,因为存在MFMediaType_Binary
主要类型。然而,一段时间后,我发现Microsoft Media Foundation中用于录制的Microsoft ASF格式实现仅支持MFMediaType_Video
、MFMediaType_Audio
和MFMediaType_Script
。这是停止解决该任务的主要原因。
更新
首次更新于2015年8月21日
- 改进了
AudioLoopback
捕获的质量; - 解决了屏幕捕获源(
GDIScreenCapture
和AudioLoopback
)的同步问题; - 为屏幕捕获源(
GDIScreenCapture
)添加了新的媒体类型,帧率如下:20 fps、25 fps和30 fps; - 在屏幕捕获源(
GDIScreenCapture
)中添加了对捕获光标并将其绘制到捕获视频中的支持。
第二次更新于2015年8月31日
- 修复了
AudioLoopback
捕获中样本丢失的问题; - 为屏幕捕获源(
GDIScreenCapture
)添加了新的媒体类型,帧率如下:1 fps、5 fps和10 fps; - 添加了对WM Speech Encoder DMO的支持;
- 添加了对WMVideo9 Screen Encoder MFT的支持——FOURCC "MSS2";
- 添加了适用于x64 Windows操作系统的
CaptureManager
SDK版本。
第三次更新于2015年9月14日
- 添加了新的屏幕捕获源 -
DirectX9ScreenCapture
,具有以下帧率:1 fps、5 fps、10 fps、15 fps、20 fps、25 fps、30 fps; - 添加了库CaptureManagerProxy.dll,用于以“C”样式调用
CaptureManagerSDK
描述符; - 添加了对第三方媒体接收器解决方案的支持 - RecordInto3rdPartyMediaSink;
- 添加了用于捕获DirectX9视频游戏屏幕的演示程序 - ScreenCaptureWithDirect3D9APIHooks;
第四次更新于2015年9月30日
- 添加了增强视频渲染器(Enhanced Video Renderer)支持——演示程序:EnhancedVideoRendererWebCapViewer
第五次更新于2015年11月13日
- 添加了对COM服务器的有限支持;
- 添加了CaptureManager.tlb;
- 添加了演示程序,用于通过C#-WPF上的COM展示
CaptureManagerSDK
的使用。
第六次更新于2016年3月7日
- 第一个稳定版本1.0.0;
- 在COM服务器中实现了对所有SDK功能的支持;
- 编写了新的COM服务器接口;
- 停止了C接口的开发;
- 将
GDIScreenCapture
和DirectX9ScreenCapture
替换为屏幕捕获; - 包含了对播放、暂停、停止和关闭功能的完全支持;
- 更新了演示程序代码,用于展示通过C#-WPF上的COM使用
CaptureManagerSDK
; - 添加了新的演示程序,用于演示录制和网络流媒体内容的功能。
第七次更新于2016年3月21日
- 添加了在MinGW编译器上的Qt框架程序中使用
CaptureManager
SDK的演示程序:QtMinGWDemo
第八次更新于2016年4月12日
- 添加了在Windows Store应用程序中使用
CaptureManager
SDK的演示程序。
第九次更新于2016年6月13日
稳定版本 1.1.0
- 添加了对通过类型库自动注册
CaptureManager
为COM服务器的支持; - 添加了对动态语言Python 2.7的支持;
- 添加了对Windows 10中HEVC(H265)编码器的支持:下载HEVCEncoder_Windows10;
第十次更新于2016年8月1日
测试版 1.2.0
- 删除了通过库链接使用
CaptureManager
的旧功能。旧的演示程序已移至旧演示。 - 实现了Microsoft Media Foundation函数的延迟绑定;
- 将网络摄像头属性功能从DirectShow替换为
DeviceIoControl
; - 在EVR中添加了调整大小功能。
第十一次更新于2016年9月5日
版本 1.2.0
- 删除了通过库链接使用
CaptureManager
的旧功能。旧的演示程序已移至旧演示。 - 实现了Microsoft Media Foundation函数的延迟绑定;
- 将网络摄像头属性功能从
DirectShow
替换为DeviceIoControl
; - 在EVR中添加了调整大小功能。
- 在
SampleGrabberCallSinkFactory
中添加了PULL
模式——一种允许获取单个样本的新模式; - 添加了样本累加器节点,用于在媒体流中存储最后5个或10个样本;
- 添加了四个新的演示程序
第十二次更新于2016年10月3日
测试版 1.3.0
- 添加了通过DirectShow Crossbar技术进行视频捕获的功能,支持以下输入:
- 复合
- SVideo
- USB
- 1394 (火线)
第十三次更新于2016年12月19日
为Java编程语言添加了两个新的演示程序
第十四次更新于2017年1月2日
- 添加了NuGet CaptureManager SDK包——适用于NET 4.0项目的包。它基于
CaptureManagerToCSharpProxy
,但有一个区别——该包包含CaptureManager.dll作为嵌入资源。它允许在运行时将CaptureManager.dll解压到Temp文件夹中,并将其上传到应用程序进程中。这比在系统中注册CaptureManager.dll作为COM服务器模块更简单——它不需要管理员权限。此包支持x86和x64 CPU架构的CaptureManager.dll,并在运行时选择合适的。
第十五次更新于2017年1月9日
版本 1.3.0。此版本包含以下更改:
- 添加了通过
DirectShow
Crossbar技术进行视频捕获的支持,用于以下输入:- 复合
- SVideo
- USB
- 1394 (火线)
- COM
ThreadingModel 已从Apartment 更改为Both 。
第十六次更新于2017年1月16日
添加了支持源类型选择的WindowsForms
GDI的新演示程序
测试版 1.4.0 - 版本 1.4.0 测试版
- 添加支持更改屏幕捕获源中光标的呈现方式:使光标不可见,并为当前光标图像添加绘制附加图像。
第十七次更新于2017年2月6日
添加了新的演示程序
版本 1.4.0 - 版本 1.4.0。此版本包含以下更改:
- 添加了对屏幕捕获源中光标显示更改的支持:使光标不可见,并为当前光标图像添加了额外的图像绘制。
- 添加了对使用自定义Microsoft Media Foundation Transform实现自定义效果的支持。
第十八次更新于2017年3月13日
版本 1.5.0 - 版本 1.5.0。此版本包含以下更改:
- 添加了对多显示器输出的支持;
- 添加了对DirectShow软件过滤器的支持。
第十九次更新于2017年5月1日
添加了新的演示程序
- WPFIPCameraMJPEGMultiSourceViewer
- WPFMultiSourceViewer
- WPFViewerEVRDisplay
- WPFIPCameraMJPEGViewer
- WPFImageViewer
版本 1.6.0 - 版本 1.6.0。此版本包含以下更改:
- 添加了
IEVRMultiSinkFactory
、IEVRStreamControl
接口:IEVRMultiSinkFactory
允许为同一个渲染上下文(窗口句柄HWND
、Direct3DSurface9
或IDXGISwapChain
)创建两个独立的拓扑节点。IEVRStreamControl
允许控制渲染——渲染位置、Z轴渲染顺序、流缓冲区的刷新、过滤器和功能。 IInitilaizeCaptureSource
、ICurrentMediaType
、ISourceRequestResult
、ICaptureProcessor
接口:IInitilaizeCaptureSource
接收捕获处理器的配置。ICurrentMediaType
包含所选媒体类型的信息。ISourceRequestResult
接收IInitilaizeCaptureSource
中定义的格式的原始数据。ICaptureProcessor
控制捕获过程。
第二十次更新于2017年7月10日
添加了以下新的演示程序:
- WPFMediaFoundationPlayer
- NativeMediaFoundationPlayer
- WPFVideoAndAudioRecorder
- EVRVieweingAndRecording
版本 1.7.0 - 版本 1.7.0。此版本包含以下更改:
- 添加了与
MediaFoundation
播放器兼容的CaptureManager
视频渲染器工厂。
第二十一次更新于2017年7月31日
添加了新的演示程序
- 添加了UnityWebCamViewer演示程序
第二十二次更新于2017年8月21日
添加了新的演示程序
- 添加了WPFMultiSourceRecorder演示程序
第二十三次更新于2017年10月23日
发布 1.8.0 - 版本 1.8.0。此版本包含以下更改:
- 为“屏幕捕获”源添加了“normalize”模式;
- 添加了
IRenderingControl
接口,用于控制目标进程上的渲染; - 为“屏幕捕获”源的“光标”选项添加了“形状”属性;
- 为“屏幕捕获”源添加了“剪辑”类型选项。
添加了新的演示程序
- 添加了WPFScreenViewer演示程序
- 添加了WPFScreenRecorder演示程序
第二十四次更新于2018年1月15日
版本 1.9.0 - 版本 1.9.0。此版本包含以下更改:
- 为“屏幕捕获”源添加了“
HWND
”模式
添加了新的演示程序
第二十五次更新于2018年3月5日
添加了新的演示程序
- 添加了UnityVideoAndAudioRecorder演示程序
第二十六次更新于2018年4月9日
发布 1.10.0 - 版本 1.10.0。此版本包含以下更改:
- 添加了
ISwitcherNodeFactory
接口用于媒体流的暂停/恢复; - 添加了
ISwitcherControl
接口用于控制(暂停、恢复、分离、连接)媒体流。
添加了新的演示程序
第二十七次更新于2018年8月13日
发布 1.11.0 - 版本 1.11.0。此版本包含以下更改:
- 添加了DirectX11纹理捕获
- 屏幕捕获输出格式从RGB32更改为NV12
第二十八次更新于2018年10月1日
发布 1.12.0 - 版本 1.12.0。此版本包含以下更改:
- 添加了带有唯一设备ID的
CM_DEVICE_LINK
属性; - 支持
DirectX9Ex
纹理共享句柄。
添加了新的演示程序
第二十九次更新于2018年11月19日
发布 1.13.0 - 版本 1.13.0。此版本包含以下更改:
- 添加了对
DirectShow
视频渲染器的支持。
添加了新的演示程序。
第三十次更新于2019年2月11日
发布 1.14.0 - 版本 1.14.0。此版本包含以下更改:
- 添加了H.264/MPEG-4 AVC视频流编码器(从256 kbit/c到64 kbit/c)
- 添加了H.265/MPEG-4 HEVC视频流编码器(64 kbit/c)
- 添加了AAC音频流编码器(96 kbit/c)
- 添加了视频流解码器
添加了新的演示程序
第三十一次更新于2019年4月15日
发布 1.15.0 - 版本 1.15.0。此版本包含以下更改:
- 添加了快速SSE2/SSSE3/SSE4.2复制功能。
第三十二次更新于2020年7月6日
发布 1.16.0 - 版本 1.16.0。此版本包含以下更改:
- 添加了用于混合视频和音频流的接口
IMixerNodeFactory
IVideoMixerControl
IAudioMixerControl
添加了新的演示程序
第三十三次更新于2020年7月20日
- 发布了
CaptureManager
SDK的源代码,采用开源许可。源代码可从此链接下载。
第三十四次更新于2020年11月16日
发布 1.17.0 - 版本 1.17.0。此版本包含以下更改:
- H264和H265视频编码器比特率扩展至2^25 (33,554,432)
第三十五次更新于2021年2月1日
发布 1.18.0 - 版本 1.18.0。此版本包含以下更改:
- 添加了音频渲染器;
- 添加了WPFStreamingAudioRenderer演示程序
第三十六次更新于2021年4月12日
发布 1.19.0 - 版本 1.19.0。此版本包含以下更改:
- 添加了对H264网络摄像头的支持
第三十七次更新于2021年9月6日
发布 1.19.1 - 版本 1.19.1。此版本包含以下更改:
- 修复了拉取模式的bug
- 修复了摄像机已被占用时无法打开的bug
第三十八次更新于2021年12月6日
发布 1.20.0 - 版本 1.20.0。此版本包含以下更改:
- 添加了async/await调用模型
第三十九次更新于2022年7月4日
发布 1.21.0 - 版本 1.21.0。此版本包含以下更改:
- 将
DirectX9
渲染替换为DirectX11
渲染
添加了新的演示程序。
- 添加了WPFVirtualCamera演示程序
第四十次更新于2022年12月12日
发布 1.22.0 - 版本 1.22.0。此版本包含以下更改:
- 添加了新接口
ILogPrintOutCallback
添加了新的演示程序。
- 添加了WPFWebViewerEVRLog4net演示程序
第四十一次更新于2023年4月1日
发布 1.23.0 - 版本 1.23.0。此版本包含以下更改:
- 改进了对VMware虚拟机的支持。
第四十二次更新于2023年12月18日
发布 1.24.0 - 版本 1.24.0。此版本包含以下更改:
- 增加硬件按钮触发事件支持。
添加了新的演示程序。
历史
- 2015年8月11日:版本1
- 2015年8月21日:更新
- 2015年8月31日:更新
- 2015年11月13日:更新
- 2016年3月7日:更新
- 2016年3月21日:更新
- 2016年4月12日:更新
- 2016年6月13日:更新
- 2016年8月1日:更新
- 2016年9月5日:更新
- 2016年10月3日:更新
- 2016年12月19日:更新
- 2017年1月2日:更新
- 2017年1月9日:更新
- 2017年1月16日:更新
- 2017年2月6日:更新
- 2017年3月13日:更新
- 2017年5月1日:更新
- 2017年7月10日:更新
- 2017年7月31日:更新
- 2017年8月21日:更新
- 2017年10月23日:更新
- 2018年1月15日:更新
- 2018年3月5日:更新
- 2018年4月9日:更新
- 2018年8月13日:更新
- 2018年10月1日:更新
- 2018年11月19日:更新
- 2019年2月11日:更新
- 2019年4月15日:更新
- 2020年7月6日:更新
- 2020年7月20日:更新
- 2020年11月16日:更新
- 2021年2月1日:更新
- 2021年4月12日:更新
- 2021年9月6日:更新
- 2021年12月6日:更新
- 2022年7月4日:更新
- 2022年12月12日:更新
- 2023年5月1日:更新
- 2023年12月18日:更新