jtwc 发表于 2023-10-3 20:28

各位老师,C++代码如何检测音频文件正在播放呢?

各位老师,C++代码如何检测音频文件有没有正在播放呢?用C++写一个监控程序,当监控检测到1.wav的文件发出声音时(确定为wav格式),监控程序马上把1写入文件a.csv。下面的代码不管用,该如何改呢?#include <iostream>
#include <fstream>
#include <Windows.h>
#include <sstream>

#include <mmsystem.h>

#pragma comment(lib, "winmm.lib")

int main() {
        std::string wavFile = "D:\\1.wav";
        std::string csvFile = "a.csv";
        while (true) {
                // 监控文件
                HANDLE hFile = CreateFile(wavFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE) {
                        std::cerr << "无法打开文件 " << wavFile << std::endl;
                        return 1;
                }

                // 创建CSV文件
                std::ofstream csv(csvFile);
                if (!csv) {
                        std::cerr << "无法创建文件 " << csvFile << std::endl;
                        CloseHandle(hFile);
                        return 1;
                }

                // 监控文件声音
                DWORD bytesRead;
                BYTE buffer; // WAV文件头部大小为44字节

                if (ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) {
                        // 检查是否为WAV文件
                        if (bytesRead == sizeof(buffer) && buffer == 'R' && buffer == 'I' && buffer == 'F' && buffer == 'F' && buffer == 'W' && buffer == 'A' && buffer == 'V' && buffer == 'E') {
                                // 检查是否有声音
                                if (buffer != 0 || buffer != 0) {
                                        // 检查文件是否正在播放声音
                                        if (waveOutGetNumDevs() > 0) {
                                                csv << "1" << std::endl;
                                                csv.flush();
                                                std::cout << "有声音" << std::endl;
                                        }
                                }
                                else {
                                        std::cout << "无声音" << std::endl;
                                }
                        }
                }
                // 关闭文件和句柄
                csv.close();
                CloseHandle(hFile);
                Sleep(1000); // 每隔0.1秒检查一次文件

               
        }

        system("pause");
        return 0;
}

huanghan89 发表于 2023-10-3 21:06

膜拜高手···

DEATHTOUCH 发表于 2023-10-3 22:22

waveOutGetNumDevs只是获取设备数量的,要判断有没有播放声音可以用WASAPI来环回录制,给你微软官方文档链接吧:

https://learn.microsoft.com/zh-cn/windows/win32/coreaudio/capturing-a-stream
这个是捕获用的,用来录音

https://learn.microsoft.com/zh-cn/windows/win32/coreaudio/loopback-recording
这个是环回录制,在捕获的基础上改一下代码就行了

不过WASAPI有一点点小麻烦

jtwc 发表于 2023-10-4 09:53

DEATHTOUCH 发表于 2023-10-3 22:22
waveOutGetNumDevs只是获取设备数量的,要判断有没有播放声音可以用WASAPI来环回录制,给你微软官方文档链 ...

老师,谢谢了,有没有简单的方法,我只是检测有没有播放声音?

DEATHTOUCH 发表于 2023-10-4 19:40

jtwc 发表于 2023-10-4 09:53
老师,谢谢了,有没有简单的方法,我只是检测有没有播放声音?

找到了个更简单的方法:
https://learn.microsoft.com/zh-cn/windows/win32/api/endpointvolume/nn-endpointvolume-iaudiometerinformation
用这个接口获取某个设备当前播放情况。
使用IAudioMeterInformation::GetChannelsPeakValues方法获取峰值,如果峰值大于0说明在播放。

jtwc 发表于 2023-10-5 10:32

DEATHTOUCH 发表于 2023-10-4 19:40
找到了个更简单的方法:
https://learn.microsoft.com/zh-cn/windows/win32/api/endpointvolume/nn-endp ...

谢谢老师

小雨网络 发表于 2023-10-6 14:28

#include <iostream>
#include <fstream>
#include <SDL.h>
#include <SDL_mixer.h>

void writeToCSV(const std::string& csvFile) {
    std::ofstream csv(csvFile, std::ios::app);
    if (!csv) {
      std::cerr << "无法创建文件 " << csvFile << std::endl;
      return;
    }
    csv << "1" << std::endl;
    csv.close();
}

int main(int argc, char* argv[]) {
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
      std::cerr << "无法初始化SDL: " << SDL_GetError() << std::endl;
      return 1;
    }

    if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096) == -1) {
      std::cerr << "无法初始化SDL_mixer: " << Mix_GetError() << std::endl;
      return 2;
    }

    std::string wavFile = "1.wav";
    std::string csvFile = "a.csv";
    Mix_Chunk *sound = Mix_LoadWAV(wavFile.c_str());

    if (!sound) {
      std::cerr << "无法加载音频文件: " << Mix_GetError() << std::endl;
      return 3;
    }

    // 监控文件
    if (Mix_PlayChannel(-1, sound, 0) == -1) {
      std::cerr << "无法播放音频文件: " << Mix_GetError() << std::endl;
      return 4;
    } else {
      writeToCSV(csvFile);
      std::cout << "正在播放: " << wavFile << std::endl;
    }

    SDL_Delay(5000); // 假设音频文件长度至少为5秒,或使用Mix_Playing()进行检测。
   
    Mix_FreeChunk(sound);
    Mix_CloseAudio();
    SDL_Quit();

    return 0;
}

jtwc 发表于 2023-10-7 13:24

小雨网络 发表于 2023-10-6 14:28
#include
#include
#include


感谢老师

jtwc 发表于 2023-10-7 13:27

小雨网络 发表于 2023-10-6 14:28
#include
#include
#include


老师,下面这2个头文哪里有呢?#include <SDL.h>
#include <SDL_mixer.h>

小雨网络 发表于 2023-10-7 16:17

jtwc 发表于 2023-10-7 13:27
老师,下面这2个头文哪里有呢?#include
#include

去SDL官方库下载这两个
https://www.libsdl.org/

页: [1] 2
查看完整版本: 各位老师,C++代码如何检测音频文件正在播放呢?