简体   繁体   English

如何在Windows中获取和设置系统卷

[英]How to Get and Set System Volume in Windows

I wanna set the OS volume on a certain level on keyboard click using unity and c# for example I wanna set the Windows volume(Not the unity) to 70: How Can I do that??? 我想使用unity和c#在键盘单击上将操作系统音量设置为某个级别,例如,我想将Windows音量(而非unitity)设置为70:我该怎么做?

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

This requires a plugin. 这需要一个插件。 Since this question is for Windows, you can use IAudioEndpointVolume to build a C++ plugin then call it from C#. 由于此问题是针对Windows的,因此您可以使用IAudioEndpointVolume构建C ++插件,然后从C#调用它。 This post has a working C++ example of how to change volume with IAudioEndpointVolume and you can use it as the base source to create the C++ plugin. 这篇文章有一个有效的C ++示例,说明如何使用IAudioEndpointVolume改变音量,您可以将其用作创建C ++插件的基础源。


I've gone ahead and cleaned that code up then converted into a dll plugin and placed the DLL at Assets/Plugins folder. 我已经将代码清理干净,然后转换为dll插件,并将DLL放在Assets / Plugins文件夹中。 You can see how to build the C++ plugin here . 您可以在此处查看如何构建C ++插件。

The C++ code : 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();
    }
}

The C# code : 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);
    }
}

The GetSystemVolume function is used to get the current volume and SetSystemVolume is used to set it. GetSystemVolume函数用于获取当前音量,而SetSystemVolume用于设置它。 This question is for Windows but you can do a similar thing with the API for other platforms. 这个问题是针对Windows的,但是您可以使用其他平台的API进行类似的操作。

To set it to 70% when A key is pressed: 按下A键时将其设置为70%

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

You cannot do this from what I am aware of. 据我所知,您无法执行此操作。 There would be no beneficial gain to this and have you seen this done in any game/application? 这样做不会有任何好处,您在任何游戏/应用程序中都看过吗?

You can change the master volume of the Unity application, using a slider and also manage other sound effects in the same way 您可以使用滑块更改Unity应用程序的主音量,并以相同方式管理其他声音效果

http://docs.unity3d.com/ScriptReference/AudioListener.html http://docs.unity3d.com/ScriptReference/AudioListener.html
http://docs.unity3d.com/ScriptReference/AudioListener-volume.html http://docs.unity3d.com/ScriptReference/AudioListener-volume.html

Example

public class AudioControl: MonoBehaviour {
void SetVolume(Slider slider) {
    AudioListener.volume = slider.Value;
    // probably save this value to a playerpref so it is remembered. 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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