代码之家  ›  专栏  ›  技术社区  ›  MartyIX

如何在整个应用程序中全局关闭声音?

  •  1
  • MartyIX  · 技术社区  · 14 年前

    我有一个插件系统在我的应用程序,我想防止这些插件播放声音。它不一定是一个完美的解决方案,不能被一个插件覆盖。

    声音将通过 MediaElement 插件中

    1 回复  |  直到 14 年前
        1
  •  2
  •   Ray Burns    14 年前

    禁用窗口中所有媒体元素的声音很容易。只需创建一个附加的继承属性,在应用它的任何MediaElement上强制IsMuted=false。属性的使用方式如下:

    <Window my:Silencer.Silence="true" ...>
      ...
    </Window>
    

    public class Silencer : DependencyObject
    {
      // Silence
      public static bool GetSilence(DependencyObject obj) { return (bool)obj.GetValue(SilenceProperty); }
      public static void SetSilence(DependencyObject obj, bool value) { obj.SetValue(SilenceProperty, value); }
      public static readonly DependencyProperty SilenceProperty = DependencyProperty.RegisterAttached("Silence", typeof(bool), typeof(Silencer), new FrameworkPropertyMetadata
      {
        Inherits = true,
        PropertyChangedCallback = (obj, e) =>
          {
            var element = obj as MediaElement; if(element==null) return;
            if((bool)e.NewValue)
            {
              element.SetBinding(UnmuteDetectedProperty, new Binding("IsMuted") { RelativeSource = RelativeSource.Self });
              element.IsMuted = true;
            }
            else
            {
              element.ClearValue(UnmuteDetectedProperty);
              element.IsMuted = false;
            }
          }
      });
    
      // UnmuteDetected
      public static readonly DependencyProperty UnmuteDetectedProperty = DependencyProperty.RegisterAttached("UnmuteDetected", typeof(bool), typeof(Silencer), new PropertyMetadata
      {
        PropertyChangedCallback = (obj, e) =>
          {
            ((MediaElement)obj).IsMuted = GetSilence(obj);
          }
      });
    }
    

    工作原理:当在窗口上将消音器设置为true时,所有子体都会收到属性更改通知。这包括已在窗口中或稍后添加到窗口中的任何MediaElement。属性更改通知将MediaElement的UnmuteDetected属性绑定到IsMuted,然后IsMuted设置为true。如果插件的代码设置IsMuted=false,它将触发第二个PropertyChangedCallback,它将再次设置为true。

    请注意,这仅适用于MediaElements,并且仅当它们被添加到可视化树中时才有效。

    阻止的不仅仅是媒体元素的声音

    一种更全面的阻止应用程序中所有声音的方法是Vista的 core audio APIs ISimpleAudioVolume 接口。除了PlaySound()和其他将输出路由到系统通知音频会话的技术外,这可以用来阻止应用程序生成音频的几乎所有方式。阻止指向系统通知会话的声音需要使用本机代码拦截Windows调用。