好的,我已经在这里待了 2 天,在最后一部分需要帮助。
我有一个 Microsoft LifeCam Cinema 摄像机,我使用 .NET DirectShowLib 来捕获视频流。好吧,实际上我使用的是 WPFMediaKit,但我现在在直接处理直接显示库的源代码中。
我的工作是: - 查看摄像机的视频输出 - 在 ASF 或 AVI 中记录摄像机的视频输出(ICaptureGraphBuilder2 支持的唯一 2 个 MediaType)
问题是:我可以将其保存为 .avi。这工作正常,分辨率为 1280x720,但它将文件保存在 RAW 输出中。这意味着它大约是每秒 50-60MB。太高了
或者我可以将它切换到 .asf 并输出 WMV,但是当我这样做时,捕获和输出都达到 320x240 分辨率。
在 WPFMediaKit 中,我更改了一个功能,因为显然使用 Microsoft LifeCam Cinema 相机很多人都有这个问题。因此,您无需创建或更改 AMMediaType,而是通过迭代然后使用它来调用 SetFormat。
///* Make the VIDEOINFOHEADER 'readable' */
var videoInfo = new VideoInfoHeader();
int iCount = 0, iSize = 0;
videoStreamConfig.GetNumberOfCapabilities(out iCount, out iSize);
IntPtr TaskMemPointer = Marshal.AllocCoTaskMem(iSize);
AMMediaType pmtConfig = null;
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
IntPtr ptr = IntPtr.Zero;
videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, TaskMemPointer);
videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader));
if (videoInfo.BmiHeader.Width == DesiredWidth && videoInfo.BmiHeader.Height == DesiredHeight)
{
///* Setup the VIDEOINFOHEADER with the parameters we want */
videoInfo.AvgTimePerFrame = DSHOW_ONE_SECOND_UNIT / FPS;
if (mediaSubType != Guid.Empty)
{
int fourCC = 0;
byte[] b = mediaSubType.ToByteArray();
fourCC = b[0];
fourCC |= b[1] << 8;
fourCC |= b[2] << 16;
fourCC |= b[3] << 24;
videoInfo.BmiHeader.Compression = fourCC;
// pmtConfig.subType = mediaSubType;
}
/* Copy the data back to unmanaged memory */
Marshal.StructureToPtr(videoInfo, pmtConfig.formatPtr, true);
hr = videoStreamConfig.SetFormat(pmtConfig);
break;
}
}
/* Free memory */
Marshal.FreeCoTaskMem(TaskMemPointer);
DsUtils.FreeAMMediaType(pmtConfig);
if (hr < 0)
return false;
return true;
实现该功能后,只要将 SetOutputFilename 设置为 MediaType.Avi,我终于可以将捕获的视频视为 1280x720。
如果我将它设置为 MediaType.Asf,它会变为 320x240 并且输出是相同的。
或者 AVI 以正确的格式工作和输出,但在 RAW 视频中这样做,因此文件大小非常大。我试图在图表中添加一个压缩器,但没有运气,这远远超出了我的经验。
我正在寻找 2 个答案中的 1 个。
- 以 1280x720 录制 ASF
- 将压缩器添加到图表中,以便我输出的 AVI 的文件大小很小。