确定Windows当前是否正在播放声音 [英] Determine if windows is currently playing sound

查看:330
本文介绍了确定Windows当前是否正在播放声音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我一直在思考这个问题已有一段时间,但我不知道解决此问题的正确方法是什么。我想确定Windows是否在特定时间使用 Powershell 脚本输出声音。我可以确定音频驱动程序是否有错误,但是我一生无法确定系统是否正在播放声音。

So I've been pondering on this problem for a while and I can't figure out what the right way to go about this is. I want to determine if Windows is outputting sound at a certain time using a Powershell script. I can determine whether or not the audio driver has an error, but I cannot for the life of me figure out if the system is playing sound.

我看着< System.Media 的code> .NET 类以及其中的三个类都与播放声音或操纵系统声音有关。

I looked at the .NET class for System.Media and the three classes inside all had to do with playing sound or manipulating the system sounds.

我不是要为我编写代码,我只需要知道从哪里开始检查Windows系统当前是否正在播放声音。

I'm not asking for code to be written for me, I just need to know where to start to check if the windows system is currently playing sound.

我有一个声音监控器,它在Node.js平台上持续监控声音,当声音消失时,它会向我发送文本。好吧,我也希望它能够遍历它所连接的所有系统,并查看故障所在。这就是为什么我要查看Windows计算机是否正在播放声音的原因。

I have a sound monitor that is continuously monitoring sound on the Node.js platform and when it loses sound it sends me a text. Well, I also want it to go through all the systems its hooked up to and see where the fault lies. That's why I want to see whether or not the windows computer is playing sound.

推荐答案

这是如何使用Simon Mourier的代码的原因

Here's how to use the code that Simon Mourier provided.

运行以下代码:

Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

namespace Foo
{
    public class Bar
    {
        public static bool IsWindowsPlayingSound()
        {
            IMMDeviceEnumerator enumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
            IMMDevice speakers = enumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
            IAudioMeterInformation meter = (IAudioMeterInformation)speakers.Activate(typeof(IAudioMeterInformation).GUID, 0, IntPtr.Zero);
            float value = meter.GetPeakValue();

            // this is a bit tricky. 0 is the official "no sound" value
            // but for example, if you open a video and plays/stops with it (w/o killing the app/window/stream),
            // the value will not be zero, but something really small (around 1E-09)
            // so, depending on your context, it is up to you to decide
            // if you want to test for 0 or for a small value
            return value > 1E-08;
        }

        [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
        private class MMDeviceEnumerator
        {
        }

        private enum EDataFlow
        {
            eRender,
            eCapture,
            eAll,
        }

        private enum ERole
        {
            eConsole,
            eMultimedia,
            eCommunications,
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
        private interface IMMDeviceEnumerator
        {
            void NotNeeded();
            IMMDevice GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role);
            // the rest is not defined/needed
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D666063F-1587-4E43-81F1-B948E807363F")]
        private interface IMMDevice
        {
            [return: MarshalAs(UnmanagedType.IUnknown)]
            object Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams);
            // the rest is not defined/needed
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064")]
        private interface IAudioMeterInformation
        {
            float GetPeakValue();
            // the rest is not defined/needed
        }
    }
}
'@

我替换了所有 var 类型,因为这似乎解决了该问题,因为代码未在PowerShell版本2上编译。

I replaced all var types as that seems to fix the issue with the code not compiling on PowerShell version 2.

加载后,您可以像这样检查状态:

Once loaded you can check the state like so:

[Foo.Bar]::IsWindowsPlayingSound()
True or False

我已经测试过在PowerShell 5.1上运行Windows 10 1703

I've tested this working with Windows 10 1703 on PowerShell 5.1

但是有一些警告:

this is a bit tricky. 0 is the official "no sound" value
but for example, if you open a video and plays/stops with it (w/o killing the app/window/stream),
the value will not be zero, but something really small (around 1E-09)
so, depending on your context, it is up to you to decide
if you want to test for 0 or for a small value

因此,如果您更改返回值> 1E-08 返回值> 0 ,当视频暂停时,您将获得成功。

So if you change return value > 1E-08 to return value > 0 you will get true when a video is paused.

这篇关于确定Windows当前是否正在播放声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆