c# - 如何在 Windows 中获取和设置系统音量

标签 c# c++ unity3d window

我想使用 unity 和 c# 在键盘单击时将操作系统音量设置在某个级别,例如我想将 Windows 音量(而不是 unity)设置为 70:我该怎么做???

void Update()
{   
    if (Input.GetKeyDown(KeyCode.A))
    {
        //Set Windows Volume 70%      
    }
}

最佳答案

这需要一个插件。由于这个问题是针对 Windows 的,您可以使用 IAudioEndpointVolume build 一个C++ plugin然后从 C# 调用它。 This帖子有一个有效的 C++ 示例,说明如何使用 IAudioEndpointVolume 更改音量,您可以将其用作创建 C++ 插件的基础源代码。


我已经清理了该代码,然后将其转换为一个 dll 插件并将该 DLL 放置在 Assets/Plugins 文件夹中。您可以看到如何构建 C++ 插件 here .

C++代码:

#include "stdafx.h"
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#define DLLExport __declspec(dllexport)

extern "C"
{
    enum class VolumeUnit {
        Decibel,
        Scalar
    };

    //Gets volume
    DLLExport float GetSystemVolume(VolumeUnit vUnit) {
        HRESULT hr;

        // -------------------------
        CoInitialize(NULL);
        IMMDeviceEnumerator *deviceEnumerator = NULL;
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
        IMMDevice *defaultDevice = NULL;

        hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
        deviceEnumerator->Release();
        deviceEnumerator = NULL;

        IAudioEndpointVolume *endpointVolume = NULL;
        hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
        defaultDevice->Release();
        defaultDevice = NULL;

        float currentVolume = 0;
        if (vUnit == VolumeUnit::Decibel) {
            //Current volume in dB
            hr = endpointVolume->GetMasterVolumeLevel(&currentVolume);
        }

        else if (vUnit == VolumeUnit::Scalar) {
            //Current volume as a scalar
            hr = endpointVolume->GetMasterVolumeLevelScalar(&currentVolume);
        }
        endpointVolume->Release();
        CoUninitialize();

        return currentVolume;
    }

    //Sets volume
    DLLExport void SetSystemVolume(double newVolume, VolumeUnit vUnit) {
        HRESULT hr;

        // -------------------------
        CoInitialize(NULL);
        IMMDeviceEnumerator *deviceEnumerator = NULL;
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
        IMMDevice *defaultDevice = NULL;

        hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
        deviceEnumerator->Release();
        deviceEnumerator = NULL;

        IAudioEndpointVolume *endpointVolume = NULL;
        hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
        defaultDevice->Release();
        defaultDevice = NULL;

        if (vUnit == VolumeUnit::Decibel)
            hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);

        else    if (vUnit == VolumeUnit::Scalar)
            hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);

        endpointVolume->Release();

        CoUninitialize();
    }
}

C#代码:

using System.Runtime.InteropServices;
using UnityEngine;

public class VolumeManager : MonoBehaviour
{
    //The Unit to use when getting and setting the volume
    public enum VolumeUnit
    {
        //Perform volume action in decibels</param>
        Decibel,
        //Perform volume action in scalar
        Scalar
    }

    /// <summary>
    /// Gets the current volume
    /// </summary>
    /// <param name="vUnit">The unit to report the current volume in</param>
    [DllImport("ChangeVolumeWindows")]
    public static extern float GetSystemVolume(VolumeUnit vUnit);
    /// <summary>
    /// sets the current volume
    /// </summary>
    /// <param name="newVolume">The new volume to set</param>
    /// <param name="vUnit">The unit to set the current volume in</param>
    [DllImport("ChangeVolumeWindows")]
    public static extern void SetSystemVolume(double newVolume, VolumeUnit vUnit);

    // Use this for initialization
    void Start()
    {
        //Get volume in Decibel 
        float volumeDecibel = GetSystemVolume(VolumeUnit.Decibel);
        Debug.Log("Volume in Decibel: " + volumeDecibel);

        //Get volume in Scalar 
        float volumeScalar = GetSystemVolume(VolumeUnit.Scalar);
        Debug.Log("Volume in Scalar: " + volumeScalar);

        //Set volume in Decibel 
        SetSystemVolume(-16f, VolumeUnit.Decibel);

        //Set volume in Scalar 
        SetSystemVolume(0.70f, VolumeUnit.Scalar);
    }
}

GetSystemVolume 函数用于获取当前音量,SetSystemVolume 用于设置音量。这个问题是针对 Windows 的,但您可以对其他平台的 API 做类似的事情。

按下 A 键时将其设置为 70%:

void Update()
{
    if (Input.GetKeyDown(KeyCode.A))
    {
        //Set Windows Volume 70%  
        SetSystemVolume(0.70f, VolumeUnit.Scalar);
    }
}

关于c# - 如何在 Windows 中获取和设置系统音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50722026/

相关文章:

c++ - 为什么 nvcc 对仿函数不满意

c# - 放大/缩小时Unity相机平移

c# - 光子 bolt |创建后将房间设为私有(private)

c# - Microsoft图表控件无法设置背景透明

c++ - 连接位 C++

c# - .NET中的密码加密/解密代码

c++ - 如果我不遵守无状态自定义分配器教条,会发生最糟糕的情况吗?

unity3d - 在 Unity 5 中更改相机 (Oculus Rift) 位置

c# - VpnManagementAgent 始终返回零配置文件,而且我似乎无法创建新配置文件

c# - 在我的 Azure 示例解决方案 AspProviders 中,项目 StorageClient 不可用