You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ISimpleAudioVolume::SetMasterVolume调节特定应用音量及获取混音器应用列表

实现特定应用音量调节与混音器应用列表获取(Windows平台)

要实现调节特定应用音量、获取系统音量混音器中的应用列表,需要用到Windows核心音频API(Core Audio APIs),以下是基于C#的实现方案:

一、定义COM互操作接口

首先需要定义Core Audio相关的COM接口,用于和系统音频服务交互:

using System;
using System.Runtime.InteropServices;

[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionManager2
{
    int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);
    // 省略其他未用到的方法
}

[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionEnumerator
{
    int GetCount(out int SessionCount);
    int GetSession(int SessionIndex, out IAudioSessionControl2 Session);
}

[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionControl2
{
    int GetDisplayName(out string pRetVal);
    int GetProcessId(out uint pRetVal);
    // 省略其他未用到的方法
}

[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ISimpleAudioVolume
{
    int SetMasterVolume(float fLevel, Guid EventContext);
    int GetMasterVolume(out float pfLevel);
    // 省略其他未用到的方法
}

[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMMDeviceEnumerator
{
    int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
    // 省略其他未用到的方法
}

[Guid("D666063F-1587-4E43-81F1-B948E807363F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMMDevice
{
    int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, out object ppInterface);
    // 省略其他未用到的方法
}

internal enum EDataFlow
{
    eRender,
    eCapture,
    eAll
}

internal enum ERole
{
    eConsole,
    eMultimedia,
    eCommunications
}

[ComImport]
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
internal class MMDeviceEnumeratorComObject { }

二、获取音量混音器中的应用列表

通过枚举音频会话,获取每个应用的名称、进程ID、当前音量等信息:

using System.Collections.Generic;

public static List<AppAudioSession> GetAudioSessions()
{
    var sessions = new List<AppAudioSession>();
    IMMDeviceEnumerator enumerator = new MMDeviceEnumeratorComObject();
    enumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out IMMDevice device);
    
    Guid sessionManagerGuid = typeof(IAudioSessionManager2).GUID;
    device.Activate(ref sessionManagerGuid, 0, IntPtr.Zero, out object obj);
    IAudioSessionManager2 sessionManager = (IAudioSessionManager2)obj;
    
    sessionManager.GetSessionEnumerator(out IAudioSessionEnumerator sessionEnum);
    sessionEnum.GetCount(out int count);
    
    for (int i = 0; i < count; i++)
    {
        sessionEnum.GetSession(i, out IAudioSessionControl2 sessionControl);
        sessionControl.GetDisplayName(out string appName);
        sessionControl.GetProcessId(out uint pid);
        
        // 获取当前音量
        sessionControl.QueryInterface(typeof(ISimpleAudioVolume).GUID, out IntPtr volPtr);
        ISimpleAudioVolume volume = (ISimpleAudioVolume)Marshal.GetObjectForIUnknown(volPtr);
        volume.GetMasterVolume(out float currentVol);
        
        sessions.Add(new AppAudioSession
        {
            AppName = string.IsNullOrEmpty(appName) ? $"进程ID: {pid}" : appName,
            ProcessId = pid,
            CurrentVolume = currentVol * 100
        });
        
        Marshal.ReleaseComObject(sessionControl);
        Marshal.ReleaseComObject(volume);
    }
    
    Marshal.ReleaseComObject(sessionEnum);
    Marshal.ReleaseComObject(sessionManager);
    Marshal.ReleaseComObject(device);
    Marshal.ReleaseComObject(enumerator);
    
    return sessions;
}

public class AppAudioSession
{
    public string AppName { get; set; }
    public uint ProcessId { get; set; }
    public float CurrentVolume { get; set; }
}

三、调节特定应用的音量

根据进程ID找到对应的音频会话,设置其音量:

public static bool SetAppVolume(uint processId, float volumePercent)
{
    if (volumePercent < 0 || volumePercent > 100)
        return false;
    
    float normalizedVol = volumePercent / 100f;
    IMMDeviceEnumerator enumerator = new MMDeviceEnumeratorComObject();
    enumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out IMMDevice device);
    
    Guid sessionManagerGuid = typeof(IAudioSessionManager2).GUID;
    device.Activate(ref sessionManagerGuid, 0, IntPtr.Zero, out object obj);
    IAudioSessionManager2 sessionManager = (IAudioSessionManager2)obj;
    
    sessionManager.GetSessionEnumerator(out IAudioSessionEnumerator sessionEnum);
    sessionEnum.GetCount(out int count);
    
    bool success = false;
    for (int i = 0; i < count; i++)
    {
        sessionEnum.GetSession(i, out IAudioSessionControl2 sessionControl);
        sessionControl.GetProcessId(out uint pid);
        
        if (pid == processId)
        {
            sessionControl.QueryInterface(typeof(ISimpleAudioVolume).GUID, out IntPtr volPtr);
            ISimpleAudioVolume volume = (ISimpleAudioVolume)Marshal.GetObjectForIUnknown(volPtr);
            volume.SetMasterVolume(normalizedVol, Guid.Empty);
            success = true;
            
            Marshal.ReleaseComObject(volume);
        }
        
        Marshal.ReleaseComObject(sessionControl);
        if (success) break;
    }
    
    Marshal.ReleaseComObject(sessionEnum);
    Marshal.ReleaseComObject(sessionManager);
    Marshal.ReleaseComObject(device);
    Marshal.ReleaseComObject(enumerator);
    
    return success;
}

四、使用示例

// 获取应用列表并打印
var appList = GetAudioSessions();
foreach (var app in appList)
{
    Console.WriteLine($"应用名: {app.AppName}, 进程ID: {app.ProcessId}, 当前音量: {app.CurrentVolume:F1}%");
}

// 将进程ID为1234的应用音量设置为50%
SetAppVolume(1234, 50);

注意事项

  • 部分应用可能会隐藏自身音频会话信息,或同时使用多个会话
  • 普通用户权限即可运行,无需管理员权限
  • 若需处理音频输入设备(麦克风),只需将EDataFlow.eRender改为EDataFlow.eCapture

内容的提问来源于stack exchange,提问作者ilw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:58:09