我正在编写使用DirectShow库在C#中捕获音频并将其写入ogg容器的程序。我在GraphEditPlus中创建了一个图形。它生成一个GraphBuilder方法代码,我将其复制到我的代码中。这段代码是:
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;
}
}
当我尝试执行此代码程序时,在尝试连接麦克风和vorbis编码器过滤器后,会向我发出“无法找到引脚”的消息。调试后我发现它找不到麦克风引脚。有谁知道我的错误在哪里?
答案 0 :(得分:0)
你不应该按名字寻找别针,因为这不太可靠。如果你绝对确定你正在处理什么过滤器/类,或许它绝对不是通用音频源过滤器的方式(更具体地说:没有人给出捕获引脚被命名的承诺),也许它或多或少可以接受。 “捕获”,而不是引脚实现IKsPropertySet
来表示)。
您最好的方法是使用带有ICaptureGraphBuilder::RenderStream
参数的PIN_CATEGORY_CAPTURE
,以便它可以为您选择捕获引脚。有关详细信息,请参阅MSDN http://msdn.microsoft.com/en-us/library/dd311932%28v=vs.85%29.aspx,我很确定您也可以轻松找到执行此操作的示例代码。
答案 1 :(得分:0)
在寻找引脚时尝试做这样的事情
pinout = FindPinByDirection( Source, PinDirection.Output);
pinin = FindPinByDirection( Target, PinDirection.Input);
Graph.Connect(pinout, pinin);
这是更好的方式,然后取决于名称。