代码之家  ›  专栏  ›  技术社区  ›  Ammar Ismaeel

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

  •  4
  • Ammar Ismaeel  · 技术社区  · 6 年前

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

    void Update()
    {   
        if (Input.GetKeyDown(KeyCode.A))
        {
            //Set Windows Volume 70%      
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  11
  •   sonnyb Programmer    6 年前

    这需要一个插件。因为这个问题是针对windows的,所以您可以使用 IAudioEndpointVolume 建立一个 C++ plugin 然后从C打电话给它。 This POST有一个工作C++如何改变卷的例子 音频端点音量 您可以使用它作为创建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做类似的事情。

    把它设置为 70% 按键时:

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            //Set Windows Volume 70%  
            SetSystemVolume(0.70f, VolumeUnit.Scalar);
        }
    }
    
        2
  •  0
  •   Draco18s no longer trusts SE    6 年前

    我知道你不能这么做。这不会带来任何好处,你在任何游戏/应用程序中都看到过吗?

    可以使用滑块更改Unity应用程序的主音量,也可以用同样的方式管理其他声音效果

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

    例子

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