如何在Windows系统下用C语言检测PC是否正在播放音频?
检测PC音频播放状态的实现方案
Windows平台(优先C语言实现)
Windows下可直接使用Core Audio APIs(Windows SDK内置组件)检测系统音频输出的活动状态,核心通过IAudioSessionManager2枚举音频会话,判断是否存在活跃的播放会话(对应浏览器、Spotify等应用的音频输出)。
核心实现步骤:
- 初始化COM环境(Core Audio基于COM架构)
- 获取系统默认音频渲染设备(扬声器/耳机等输出设备)
- 激活
IAudioSessionManager2接口,用于管理所有音频会话 - 枚举所有音频会话,检查每个会话的活跃状态,只要有一个会话处于播放状态,即可判定系统正在输出音频
简化代码示例:
#include <windows.h> #include <mmdeviceapi.h> #include <audiopolicy.h> #include <stdio.h> #pragma comment(lib, "ole32.lib") #pragma comment(lib, "mmdevapi.lib") #pragma comment(lib, "audiopolicy.lib") BOOL IsAudioPlaying() { BOOL result = FALSE; HRESULT hr; IMMDeviceEnumerator* pEnumerator = NULL; IMMDevice* pDevice = NULL; IAudioSessionManager2* pSessionManager = NULL; IAudioSessionEnumerator* pSessionEnumerator = NULL; int sessionCount; // 初始化COM库 hr = CoInitialize(NULL); if (FAILED(hr)) goto cleanup; // 创建音频设备枚举器 hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator); if (FAILED(hr)) goto cleanup; // 获取默认音频输出设备 hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice); if (FAILED(hr)) goto cleanup; // 激活音频会话管理器 hr = pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**)&pSessionManager); if (FAILED(hr)) goto cleanup; // 枚举所有音频会话 hr = pSessionManager->GetSessionEnumerator(&pSessionEnumerator); if (FAILED(hr)) goto cleanup; hr = pSessionEnumerator->GetCount(&sessionCount); if (FAILED(hr)) goto cleanup; // 遍历会话,检查是否处于活跃播放状态 for (int i = 0; i < sessionCount; i++) { IAudioSessionControl* pSessionControl = NULL; hr = pSessionEnumerator->GetSession(i, &pSessionControl); if (SUCCEEDED(hr)) { AudioSessionState state; hr = pSessionControl->GetState(&state); // AudioSessionStateActive 表示会话正在播放音频 if (SUCCEEDED(hr) && state == AudioSessionStateActive) { result = TRUE; pSessionControl->Release(); break; } pSessionControl->Release(); } } cleanup: // 释放所有COM资源 if (pSessionEnumerator) pSessionEnumerator->Release(); if (pSessionManager) pSessionManager->Release(); if (pDevice) pDevice->Release(); if (pEnumerator) pEnumerator->Release(); CoUninitialize(); return result; } int main() { printf(IsAudioPlaying() ? "音频正在播放\n" : "未播放音频\n"); return 0; }
替代方案(Python)
若觉得C语言开发繁琐,可使用pycaw库(封装Windows Core Audio API),轻松检测音频会话活跃状态,解决你之前仅能检测麦克风输入的问题:
示例代码:
from pycaw.pycaw import AudioUtilities, IAudioSessionControl2 def is_audio_playing(): sessions = AudioUtilities.GetAllSessions() for session in sessions: if session.Process and session.Process.name() != "System Idle Process": try: control = session.QueryInterface(IAudioSessionControl2) # 状态1对应AudioSessionStateActive(正在播放) if control.GetState() == 1: return True except: continue return False print(is_audio_playing())
其他平台方案
- Linux:使用PulseAudio的
libpulse库,检测默认输出sink的活跃音频流状态 - macOS:通过Core Audio框架的
AudioObjectGetPropertyData接口,获取输出设备的音频流活动状态
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

