我正在构建一个应用程序,该应用程序可以自动启动屏幕录制应用程序(如OBS((以录制缩放会议(。
我不想在录制过程中播放任何其他应用程序的音频,但我找不到工作代码。
我在这个网站上使用了这个例子和这里的一些代码,只是为了检查API
public enum MMRESULT : uint
{
// Source: https://www.pinvoke.net/default.aspx/winmm/MMRESULT.html?diff=y
MMSYSERR_NOERROR = 0,
MMSYSERR_ERROR = 1,
MMSYSERR_BADDEVICEID = 2,
MMSYSERR_NOTENABLED = 3,
MMSYSERR_ALLOCATED = 4,
MMSYSERR_INVALHANDLE = 5,
MMSYSERR_NODRIVER = 6,
MMSYSERR_NOMEM = 7,
MMSYSERR_NOTSUPPORTED = 8,
MMSYSERR_BADERRNUM = 9,
MMSYSERR_INVALFLAG = 10,
MMSYSERR_INVALPARAM = 11,
MMSYSERR_HANDLEBUSY = 12,
MMSYSERR_INVALIDALIAS = 13,
MMSYSERR_BADDB = 14,
MMSYSERR_KEYNOTFOUND = 15,
MMSYSERR_READERROR = 16,
MMSYSERR_WRITEERROR = 17,
MMSYSERR_DELETEERROR = 18,
MMSYSERR_VALNOTFOUND = 19,
MMSYSERR_NODRIVERCB = 20,
WAVERR_BADFORMAT = 32,
WAVERR_STILLPLAYING = 33,
WAVERR_UNPREPARED = 34
}
[DllImport("winmm.dll")]
public static extern MMRESULT waveOutGetVolume(IntPtr hwo, out uint dwVolume);
[DllImport("winmm.dll")]
public static extern MMRESULT waveOutSetVolume(IntPtr hwo, uint dwVolume);
public static void Main(string[] args)
{
foreach (Process process in Process.GetProcesses())
{
if (process.MainWindowHandle != IntPtr.Zero)
{
// Source: https://sites.google.com/site/lalitpundir/s-1
try
{
uint CurrVol = 0;
// At this point, CurrVol gets assigned the volume
MMRESULT res = waveOutGetVolume(process.Handle, out CurrVol);
// Calculate the volume
ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
// Get the volume on a scale of 1 to 10 (to fit the trackbar)
Console.WriteLine($"The volume of {process.ProcessName} is {CalcVol / (ushort.MaxValue / 10)}");
// Try muting chrome
if (process.ProcessName.Equals("chrome"))
{
Console.WriteLine("Muting chrome");
int NewVolume = 0;
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
res = waveOutSetVolume(process.Handle, NewVolumeAllChannels);
Console.WriteLine(res);
Thread.Sleep(5000);
}
}
catch (Win32Exception e)
{
Console.WriteLine($"Error with {process.ProcessName}");
}
}
}
}
对于waveOutGetVolume
和waveOutSetVolume
方法,上面的代码总是返回MMSYSERR_BADDEVICEID
。
感谢Make that 4的帮助。
你提供的链接帮助我找到了这个答案,我对它进行了一些修改以满足我的需求。
首先,这个答案需要NuGet包CSCore。
这是我使用的示例代码(我仍在学习包(:
public class MixerTest
{
static void Main(string[] args)
{
foreach (AudioSessionManager2 sessionManager in GetDefaultAudioSessionManager2(DataFlow.Render))
{
using (sessionManager)
{
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
foreach (var session in sessionEnumerator)
{
using var simpleVolume = session.QueryInterface<SimpleAudioVolume>();
using var sessionControl = session.QueryInterface<AudioSessionControl2>();
Console.WriteLine((sessionControl.Process.ProcessName, sessionControl.SessionIdentifier));
if (Process.GetProcessById(sessionControl.ProcessID).ProcessName.Equals("chrome"))
{
simpleVolume.IsMuted = true;
}
}
}
}
}
Console.ReadKey();
}
private static IEnumerable<AudioSessionManager2> GetDefaultAudioSessionManager2(DataFlow dataFlow)
{
using var enumerator = new MMDeviceEnumerator();
using var devices = enumerator.EnumAudioEndpoints(dataFlow, DeviceState.Active);
foreach (var device in devices)
{
Console.WriteLine("Device: " + device.FriendlyName);
var sessionManager = AudioSessionManager2.FromMMDevice(device);
yield return sessionManager;
}
}
}