(c#) 使用 DirectShow 播放和控制多个声音文件
(c#) Playing and controlling multiple sound files using DirectShow
我对 DirectShow 的经验很少,到目前为止,我已经在特定输出设备上管理播放 .wav 文件,同时能够控制其音量和 get/set 其轨道位置。基本上我能够创建一个非常简单的声音播放器应用程序。
这是我目前使用的代码:
//select an output device
DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory
DsDevice device = (DsDevice)devices[xxx];
//define a source
Guid iid = typeof(IBaseFilter).GUID;
object source = null;
device.Mon.BindToObject(null, null, ref iid, out source);
//build a basic graph to play the sound
IGraphBuilder player_gra = (IGraphBuilder)new FilterGraph();
player_gra.AddFilter((IBaseFilter)source, "Audio Render");
player_gra.RenderFile(@"test.wav", "");
//start the sound
(player_gra as IMediaControl).Run();
//control the volume
(player_gra as IBasicAudio).put_Volume(volume);
//get/set position on the track
(player_gra as IMediaPosition).get_Duration(out out1);//how long the track is
(player_gra as IMediaPosition).get_CurrentPosition(out out2);
(player_gra as IMediaPosition).put_CurrentPosition(yyy);
我现在想做的是同时播放多个 .wav 文件,同时能够在 运行 时间控制每个文件的音量和音轨位置。
我的第一次尝试是创建多个 IGraphBuilder 实例并同时 运行 它们,但似乎只有一个可以同时播放,而其他的则等待当前播放的实例通过以下方式终止:
Marshal.ReleaseComObject(player_gra);
我的第二次尝试是在启动 IGraphBuilder 之前给它几个要渲染的文件。
…
player_gra.RenderFile(@"testA.wav", "");
player_gra.RenderFile(@"testB.wav", "");
player_gra.RenderFile(@"testC.wav", "");
…
通过这种方式可以同时播放文件,但我看不出有什么办法可以控制每个声音的音量,更不用说它在音轨上的位置了。
提前谢谢你;-)
在这些行中
DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[0];
您枚举音频输出设备并选择第一个看起来是 Default WaveOut Device 或其实例之一的“随机”设备。
它有一个遗留行为,即只有一个活动实例实际发送数据进行播放。系统中没有防止同时回放的基本限制,这只是遗留行为。
也就是说,您同时播放了两个图表,但第二个图表的音频被静音了。
Audio mixing is disabled in the waveOut Audio Renderer, so if you need to mix multiple audio streams during playback, use the DirectSound renderer.
如果您改用 Default DirectSound Device(您可以通过在代码中使用 device[NNN]
中的不同索引快速获取),您将听到您期望听到的声音。
DirectShow.NET 以某种方式令人困惑地进行枚举,默认的 DirectSound 设备通常具有最高的价值并列在第一位,并且您似乎以不同的顺序获得设备。
我对 DirectShow 的经验很少,到目前为止,我已经在特定输出设备上管理播放 .wav 文件,同时能够控制其音量和 get/set 其轨道位置。基本上我能够创建一个非常简单的声音播放器应用程序。
这是我目前使用的代码:
//select an output device
DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory
DsDevice device = (DsDevice)devices[xxx];
//define a source
Guid iid = typeof(IBaseFilter).GUID;
object source = null;
device.Mon.BindToObject(null, null, ref iid, out source);
//build a basic graph to play the sound
IGraphBuilder player_gra = (IGraphBuilder)new FilterGraph();
player_gra.AddFilter((IBaseFilter)source, "Audio Render");
player_gra.RenderFile(@"test.wav", "");
//start the sound
(player_gra as IMediaControl).Run();
//control the volume
(player_gra as IBasicAudio).put_Volume(volume);
//get/set position on the track
(player_gra as IMediaPosition).get_Duration(out out1);//how long the track is
(player_gra as IMediaPosition).get_CurrentPosition(out out2);
(player_gra as IMediaPosition).put_CurrentPosition(yyy);
我现在想做的是同时播放多个 .wav 文件,同时能够在 运行 时间控制每个文件的音量和音轨位置。
我的第一次尝试是创建多个 IGraphBuilder 实例并同时 运行 它们,但似乎只有一个可以同时播放,而其他的则等待当前播放的实例通过以下方式终止:
Marshal.ReleaseComObject(player_gra);
我的第二次尝试是在启动 IGraphBuilder 之前给它几个要渲染的文件。
…
player_gra.RenderFile(@"testA.wav", "");
player_gra.RenderFile(@"testB.wav", "");
player_gra.RenderFile(@"testC.wav", "");
…
通过这种方式可以同时播放文件,但我看不出有什么办法可以控制每个声音的音量,更不用说它在音轨上的位置了。
提前谢谢你;-)
在这些行中
DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[0];
您枚举音频输出设备并选择第一个看起来是 Default WaveOut Device 或其实例之一的“随机”设备。
它有一个遗留行为,即只有一个活动实例实际发送数据进行播放。系统中没有防止同时回放的基本限制,这只是遗留行为。
也就是说,您同时播放了两个图表,但第二个图表的音频被静音了。
Audio mixing is disabled in the waveOut Audio Renderer, so if you need to mix multiple audio streams during playback, use the DirectSound renderer.
如果您改用 Default DirectSound Device(您可以通过在代码中使用 device[NNN]
中的不同索引快速获取),您将听到您期望听到的声音。
DirectShow.NET 以某种方式令人困惑地进行枚举,默认的 DirectSound 设备通常具有最高的价值并列在第一位,并且您似乎以不同的顺序获得设备。