2013-12-19 19 views
3

我想改變某個過程的音量,我必須在一個字符串中定義應用程序的名稱。但是我可以改變音量的唯一過程就是Mozilla Firefox。我將添加一些代碼作爲解釋;只能改變過程中的Firefox的音量,而不是其他音量

Audio.cs

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

    internal enum EDataFlow 
    { 
     eRender, 
     eCapture, 
     eAll, 
     EDataFlow_enum_count 
    } 

    internal enum ERole 
    { 
     eConsole, 
     eMultimedia, 
     eCommunications, 
     ERole_enum_count 
    } 

    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IMMDeviceEnumerator 
    { 
     int NotImpl1(); 

     [PreserveSig] 
     int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice); 

     // the rest is not implemented 
    } 

    [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IMMDevice 
    { 
     [PreserveSig] 
     int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); 

     // the rest is not implemented 
    } 

    [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IAudioSessionManager2 
    { 
     int NotImpl1(); 
     int NotImpl2(); 

     [PreserveSig] 
     int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum); 

     // the rest is not implemented 
    } 

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

     [PreserveSig] 
     int GetSession(int SessionCount, out IAudioSessionControl Session); 
    } 

    [Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IAudioSessionControl 
    { 
     int NotImpl1(); 

     [PreserveSig] 
     int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); 

     // the rest is not implemented 
    } 

    [Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface ISimpleAudioVolume 
    { 
     [PreserveSig] 
     int SetMasterVolume(float fLevel, ref Guid EventContext); 

     [PreserveSig] 
     int GetMasterVolume(out float pfLevel); 

     [PreserveSig] 
     int SetMute(bool bMute, ref Guid EventContext); 

     [PreserveSig] 
     int GetMute(out bool pbMute); 
    } 

    static class Audio 
    { 
     public static void SetVolume(string app, int volume) 
     { 
      foreach (string name in Audio.EnumerateApplications()) 
      { 
       Console.WriteLine("name:" + name); 
       if (name.Equals(app, StringComparison.OrdinalIgnoreCase)) 
       { 
        // display mute state & volume level (% of master) 
        Console.WriteLine("Mute:" + Audio.GetApplicationMute(app)); 
        Console.WriteLine("Volume:" + Audio.GetApplicationVolume(app)); 

        // set the volume to half of master volume (50%) 
        Audio.SetApplicationVolume(app, volume); 
       } 
      } 
     } 

     public static float? GetApplicationVolume(string name) 
     { 
      ISimpleAudioVolume volume = GetVolumeObject(name); 
      if (volume == null) 
       return null; 

      float level; 
      volume.GetMasterVolume(out level); 
      return level * 100; 
     } 

     public static bool? GetApplicationMute(string name) 
     { 
      ISimpleAudioVolume volume = GetVolumeObject(name); 
      if (volume == null) 
       return null; 

      bool mute; 
      volume.GetMute(out mute); 
      return mute; 
     } 

     public static void SetApplicationVolume(string name, float level) 
     { 
      ISimpleAudioVolume volume = GetVolumeObject(name); 
      if (volume == null) 
       return; 

      Guid guid = Guid.Empty; 
      volume.SetMasterVolume(level/100, ref guid); 
     } 

     public static void SetApplicationMute(string name, bool mute) 
     { 
      ISimpleAudioVolume volume = GetVolumeObject(name); 
      if (volume == null) 
       return; 

      Guid guid = Guid.Empty; 
      volume.SetMute(mute, ref guid); 
     } 

     public static IEnumerable<string> EnumerateApplications() 
     { 
      // get the speakers (1st render + multimedia) device 
      IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); 
      IMMDevice speakers; 
      deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); 

      // activate the session manager. we need the enumerator 
      Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID; 
      object o; 
      speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o); 
      IAudioSessionManager2 mgr = (IAudioSessionManager2)o; 

      // enumerate sessions for on this device 
      IAudioSessionEnumerator sessionEnumerator; 
      mgr.GetSessionEnumerator(out sessionEnumerator); 
      int count; 
      sessionEnumerator.GetCount(out count); 

      for (int i = 0; i < count; i++) 
      { 
       IAudioSessionControl ctl; 
       sessionEnumerator.GetSession(i, out ctl); 
       string dn; 
       ctl.GetDisplayName(out dn); 
       yield return dn; 
       Marshal.ReleaseComObject(ctl); 
      } 
      Marshal.ReleaseComObject(sessionEnumerator); 
      Marshal.ReleaseComObject(mgr); 
      Marshal.ReleaseComObject(speakers); 
      Marshal.ReleaseComObject(deviceEnumerator); 
     } 

     private static ISimpleAudioVolume GetVolumeObject(string name) 
     { 
      // get the speakers (1st render + multimedia) device 
      IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); 
      IMMDevice speakers; 
      deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); 

      // activate the session manager. we need the enumerator 
      Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID; 
      object o; 
      speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o); 
      IAudioSessionManager2 mgr = (IAudioSessionManager2)o; 

      // enumerate sessions for on this device 
      IAudioSessionEnumerator sessionEnumerator; 
      mgr.GetSessionEnumerator(out sessionEnumerator); 
      int count; 
      sessionEnumerator.GetCount(out count); 

      // search for an audio session with the required name 
      // NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2) 
      ISimpleAudioVolume volumeControl = null; 
      for (int i = 0; i < count; i++) 
      { 
       IAudioSessionControl ctl; 
       sessionEnumerator.GetSession(i, out ctl); 
       string dn; 
       ctl.GetDisplayName(out dn); 
       if (string.Compare(name, dn, StringComparison.OrdinalIgnoreCase) == 0) 
       { 
        volumeControl = ctl as ISimpleAudioVolume; 
        break; 
       } 
       Marshal.ReleaseComObject(ctl); 
      } 
      Marshal.ReleaseComObject(sessionEnumerator); 
      Marshal.ReleaseComObject(mgr); 
      Marshal.ReleaseComObject(speakers); 
      Marshal.ReleaseComObject(deviceEnumerator); 
      return volumeControl; 
     } 
    } 
} 

變量i請致電FormMain

const string APP = "Mozilla Firefox"; 

上述作品中的一個,但這樣的事情沒有;

const string APP = "Spotify"; 

我想它與我在代碼中發佈的GUID的東西,但我似乎無法找出什麼。

+0

是Spotify的一個獨立的應用程序或它在運行瀏覽器嗎? –

+0

這是一個獨立的應用程序 – joostmakaay

+0

任何人都可以幫助我? – joostmakaay

回答

0

如果您嘗試與進程名稱匹配,firefox適用於Mozilla Firefox。在這種情況下,您可以使用String.Contains()進行搜索。

+0

我知道,但是爲什麼當我使Spotify或spotify.exe無法工作呢? – joostmakaay

0

它似乎是爲了讓您的進程顯示在系統托盤混音器中,它必須先播放聲音。可能有另一種方法。

無論如何,這裏是播放一個空的聲音片段:

// wave signature for no sound 
    byte[] arr = new byte[] { 82, 73, 70, 70, 36, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 2, 0, 68, 172, 0, 0, 16, 177, 2, 0, 4, 0, 16, 0, 100, 97, 116, 97, 0, 0, 0, 0}; 
    using (MemoryStream ms = new MemoryStream()) { 
     ms.Write(arr); 
     ms.Position = 0; 
     using (SoundPlayer p = new SoundPlayer(ms)) { 
      p.Play(); 
     } 
    } 

上波產生更深入的討論可以found here

字節數組是通過使用上述鏈接中的示例創建的,只是頁眉和頁腳。

在Volume Mixer中完成您的過程之後,您應該通過其進程ID而不是其名稱來檢索其音量控制對象。所以,如果Spotify.exe是自己的過程,那麼你可以使用:

Process.GetCurrentProcess().Id 

安德斯·凱勒卡斯特森發佈的解決方案做到這一點的位置:Controlling Application's Volume: By Process-ID

相關問題