C# 使用DirectShow捕获音频
我正在编写一个程序,它使用DirectShow库在C#中捕获音频并将其写入ogg容器。我用GrapherDitPlus创建了一个图形。它生成一个GraphBuilder方法代码,我将其复制到我的代码中。该代码是:C# 使用DirectShow捕获音频,c#,audio,directshow,C#,Audio,Directshow,我正在编写一个程序,它使用DirectShow库在C#中捕获音频并将其写入ogg容器。我用GrapherDitPlus创建了一个图形。它生成一个GraphBuilder方法代码,我将其复制到我的代码中。该代码是: class AudioCapture { public static void checkHR(int hr, string msg) { if (hr < 0) { MessageBox.Show(msg); DsError.Th
class AudioCapture
{
public static void checkHR(int hr, string msg)
{
if (hr < 0)
{
MessageBox.Show(msg);
DsError.ThrowExceptionForHR(hr);
}
}
public static void BuildGraph (IGraphBuilder pGraph, string dstFile)
{
int hr = 0;
//graph builder
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = pBuilder.SetFiltergraph(pGraph);
checkHR(hr, "Can't SetFiltergraph");
Guid CLSID_XiphOrgVorbisEncoder = new Guid("{5C94FE86-B93B-467F-BFC3-BD6C91416F9B}");
Guid CLSID_XiphOrgOggMuxer = new Guid("{1F3EFFE4-0E70-47C7-9C48-05EB99E20011}");
//add microphone
IBaseFilter pMicrophone = (IBaseFilter) new AudioRecord();
hr = pGraph.AddFilter(pMicrophone, "Microphone");
checkHR(hr, "Can't add microphone to graph");
//add Vorbis Encoder
IBaseFilter pVorbisEncoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgVorbisEncoder));
checkHR(hr, "Can't add Vorbis Encoder to graph");
//connect Microphone and Vorbis Encoder
hr = pGraph.ConnectDirect(GetPin(pMicrophone, "Capture"), GetPin(pVorbisEncoder, "PCM In"), null);
checkHR(hr, "Can't connect Microphone and Vorbis Encoder");
//add Ogg Muxer
IBaseFilter pOggMuxer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgOggMuxer));
checkHR(hr, "Can't add Ogg Muxer to graph");
//set destination filename
IFileSinkFilter pOggMuxer_sink = pOggMuxer as IFileSinkFilter;
if (pOggMuxer_sink == null)
checkHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter");
hr = pOggMuxer_sink.SetFileName(dstFile, null);
checkHR(hr, "Can't set filename");
//connect Vorbis Encoder and Ogg Muxer
hr = pGraph.ConnectDirect(GetPin(pVorbisEncoder, "VorbisOut"), GetPin(pOggMuxer, "Ogg Packet In"), null);
checkHR(hr, "Can't connect Vorbis Encoder and Ogg Muxer");
}
static IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}
}
类音频捕获
{
公共静态void checkHR(int hr,string msg)
{
如果(hr<0)
{
MessageBox.Show(msg);
DsError.THROWEExceptionForHR(hr);
}
}
公共静态void BuildGraph(IGraphBuilder pGraph,字符串文件)
{
int-hr=0;
//图形生成器
ICaptureGraphBuilder2 pBuilder=(ICaptureGraphBuilder2)新CaptureGraphBuilder2();
hr=pBuilder.SetFiltergraph(pGraph);
检查hr(hr,“无法设置FilterGraph”);
Guid CLSID_XiphOrgVorbisEncoder=新Guid({5C94FE86-B93B-467F-BFC3-BD6C91416F9B});
Guid CLSID_xiphorgmuxer=新Guid({1f3effef4-0E70-47C7-9C48-05EB99E20011});
//添加麦克风
IBaseFilter pMicrophone=(IBaseFilter)新录音();
hr=pGraph.AddFilter(pMicrophone,“麦克风”);
检查hr(hr,“无法将麦克风添加到图表”);
//添加Vorbis编码器
IBaseFilter pVorbisEncoder=(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgVorbisEncoder));
checkHR(hr,“无法将Vorbis编码器添加到图形”);
//连接麦克风和Vorbis编码器
hr=pGraph.ConnectDirect(GetPin(pmicromphone,“Capture”)、GetPin(pVorbisEncoder,“PCM In”)、null;
检查hr(hr,“无法连接麦克风和Vorbis编码器”);
//添加Ogg多路复用器
IBaseFilter pOggMuxer=(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_xiphorggmuxer));
checkHR(hr,“无法将Ogg Muxer添加到图形中”);
//设置目标文件名
IFileSinkFilter pOggMuxer_sink=pOggMuxer作为IFileSinkFilter;
if(pOggMuxer_sink==null)
checkHR(未选中((int)0x80004002),“无法获取IFileSinkFilter”);
hr=pOggMuxer_sink.SetFileName(dstFile,null);
checkHR(hr,“无法设置文件名”);
//连接Vorbis编码器和Ogg Muxer
hr=pGraph.ConnectDirect(GetPin(pVorbisEncoder,“vorbiout”),GetPin(pOggMuxer,“Ogg数据包输入”),null;
检查hr(hr,“无法连接Vorbis编码器和Ogg Muxer”);
}
静态IPin GetPin(IBaseFilter筛选器,字符串pinname)
{
伊努宾斯皮恩斯;
int hr=过滤器.枚举管脚(输出管脚);
checkHR(hr,“无法枚举PIN”);
IntPtr fetched=Marshal.alloctaskmem(4);
IPin[]引脚=新IPin[1];
while(epins.Next(1,pins,fetched)=0)
{
PinInfo-pinfo;
引脚[0]。QueryPinfo(输出引脚信息);
bool found=(pinfo.name==pinname);
DsUtils.FreePinInfo(pinfo);
如果(找到)
返回销[0];
}
检查HR(-1,“未找到Pin”);
返回null;
}
}
当我尝试执行此代码时,在尝试连接麦克风和vorbis编码器过滤器后,程序会抛出一条消息“Pin找不到”。调试后,我发现它找不到麦克风pin。有人知道我的错误在哪里吗?您不应该按名称查找PIN,因为这不太可靠。如果您完全确定要处理的是什么过滤器/类,那么这可能或多或少还是可以接受的,但这绝对不是使用通用音频源过滤器的方式(更具体地说:没有人承诺将捕获pin命名为“capture”,而是pins实现
iksprropertySet
,以表明这一点)
最好的方法是将
ICaptureGraphBuilder::RenderStream
与PIN\u CATEGORY\u CAPTURE
参数一起使用,这样它就可以为您提取CAPTURE PIN。有关详细信息,请参阅MSDN,我相信您也可以很容易地找到执行此操作的示例代码。在查找PIN时尝试执行类似操作
pinout = FindPinByDirection( Source, PinDirection.Output);
pinin = FindPinByDirection( Target, PinDirection.Input);
Graph.Connect(pinout, pinin);
这是一个更好的方法,然后取决于名称 最好搜索音频输入设备。只是
new AudioRecord()
不会自动创建micropone输入。您好,如何录制视频和音频并将其保存到单个视频文件中?我可以通过创建文件来做到这一点。你能帮我吗。