简体   繁体   中英

C# mute other application

I am building an app that starts a screen recorder application (like OBS) automatically (to record a zoom meeting).

I don't want any other application's audio to play during the recording, but I can't find a working code.

I used the example in this site with some codefrom here just to check the 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}");
            }
        }
    }

}

The above code, always returns MMSYSERR_BADDEVICEID for the waveOutGetVolume and waveOutSetVolume methods.

Thanks you Make that 4 for the help.

The links you provided helped me find this answer ,, which I modified a bit to fit my needs.

First of all, this answer requires the NuGet package CSCore .

This is an example code that I used (I am still learning the package):

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;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM