Windows MCI多媒体接口实现 wave/mdi/mpeg(mp3) 多媒体播放

操作系统接口函数:

mciSendString

例子:

Win32Mci mci("C:\\晨光劍舞_豪情九州.mp3");

mci.Play();

头文件:

cpp 复制代码
#pragma once

#include <iostream>
#include <string>

namespace ppp
{
    namespace win32
    {
        class Win32Mci final
        {
        public:
            enum class PlayState
            {
                Closed,
                Stopped,
                Paused,
                Playing,
                NotReady,
                Open,
                Recording,
                Parked,
                Seeking,
            };

        public:
            explicit Win32Mci(const std::string& path);
            ~Win32Mci() noexcept;

        public:
            void                                    Play();
            void                                    Stop();
            void                                    Pause();
            void                                    Resume();
            void                                    Seek(int64_t offset, uint32_t loc);
            void                                    SetVolume(int volume);
            int64_t                                 Position() const;
            int64_t                                 Length() const;
            PlayState                               State() const;
            void                                    SetRepeat(bool repeat);
            void                                    Dispose() noexcept;

        private:
            std::string                             Command(const std::string& command) const;
            bool                                    PlayCommand(const std::string& command) const;
            void                                    Close() noexcept;

        private:
            std::string                             path_;
            std::string                             alias_;
            bool                                    Repeat_;
        };
    }
}

源文件:

cpp 复制代码
#include <windows/ppp/win32/Win32Mci.h>
#include <ppp/stdafx.h>

#include <Windows.h>
#include <mmsystem.h>

#include <string>
#include <stdexcept>

namespace ppp
{
    namespace win32
    {
        Win32Mci::Win32Mci(const std::string& path)
            : Repeat_(false)
        {
            alias_ = "mci-" + std::to_string(ppp::GetTickCount()) + "-" + std::to_string(ppp::RandomNext());
            if (!path.empty())
            {
                path_ = path;
            }
            else
            {
                throw std::invalid_argument("Path is empty.");
            }

            if (!PlayCommand("open \"" + path_ + "\" type mpegvideo alias " + alias_))
            {
                throw std::runtime_error("Failed to open audio file.");
            }
        }

        Win32Mci::~Win32Mci() noexcept
        {
            Close();
        }

        void Win32Mci::Play()
        {
            if (Repeat_)
            {
                PlayCommand("play " + alias_ + " repeat");
            }
            else
            {
                PlayCommand("play " + alias_);
            }
        }

        void Win32Mci::Stop()
        {
            PlayCommand("stop " + alias_);
        }

        void Win32Mci::Pause()
        {
            PlayCommand("pause " + alias_);
        }

        void Win32Mci::Resume()
        {
            PlayCommand("resume " + alias_);
        }

        void Win32Mci::Seek(int64_t offset, uint32_t loc)
        {
            int64_t position = 0;

            switch (loc)
            {
            case SEEK_SET:
                position = offset;
                break;
            case SEEK_CUR:
                position = Position() + offset;
                break;
            case SEEK_END:
                position = Length() + offset;
                break;
            default:
                throw std::invalid_argument("Invalid seek origin.");
            }

            PlayCommand("seek " + alias_ + " to " + std::to_string(position));
        }

        void Win32Mci::SetVolume(int volume)
        {
            int vol = std::min(volume, 1000);
            if (vol < 0)
            {
                vol = 0;
            }

            PlayCommand("setaudio " + alias_ + " volume to " + std::to_string(vol));
        }

        int64_t Win32Mci::Position() const
        {
            std::string result = Command("status " + alias_ + " position");
            return std::stoll(result);
        }

        int64_t Win32Mci::Length() const
        {
            std::string result = Command("status " + alias_ + " length");
            return std::stoll(result);
        }

        Win32Mci::PlayState Win32Mci::State() const
        {
            std::string result = Command("status " + alias_ + " mode");
            std::string mode = result.empty() ? "" : result.substr(0, result.find_first_of("\r\n"));

            if (mode == "stopped")
            {
                return PlayState::Stopped;
            }
            else if (mode == "paused")
            {
                return PlayState::Paused;
            }
            else if (mode == "playing")
            {
                return PlayState::Playing;
            }
            else if (mode == "not ready")
            {
                return PlayState::NotReady;
            }
            else if (mode == "open")
            {
                return PlayState::Open;
            }
            else if (mode == "recording")
            {
                return PlayState::Recording;
            }
            else if (mode == "parked")
            {
                return PlayState::Parked;
            }
            else if (mode == "seeking")
            {
                return PlayState::Seeking;
            }

            return PlayState::Closed;
        }

        void Win32Mci::SetRepeat(bool repeat)
        {
            Repeat_ = repeat;

            if (State() == PlayState::Playing || State() == PlayState::Paused)
            {
                Seek(0, SEEK_SET);
                Play();
                if (State() == PlayState::Paused)
                {
                    Pause();
                }
            }
        }

        std::string Win32Mci::Command(const std::string& command) const
        {
            const DWORD bufferSize = 1000;
            char buffer[bufferSize] = { 0 };

            if (mciSendStringA(command.c_str(), buffer, bufferSize, nullptr) != MMSYSERR_NOERROR)
            {
                throw std::runtime_error("MCI command failed.");
            }

            return buffer;
        }

        bool Win32Mci::PlayCommand(const std::string& command) const
        {
            return mciSendStringA(command.c_str(), nullptr, 0, nullptr) == MMSYSERR_NOERROR;
        }

        void Win32Mci::Close() noexcept
        {
            PlayCommand("close " + alias_);
        }

        void Win32Mci::Dispose() noexcept
        {
            Close();
        }
    }
}
相关推荐
zhangfeng11338 小时前
Windows 的 Git Bash 中使用 md5sum 命令非常简单 md5做文件完整性检测 WinRAR 可以计算文件的 MD5 值
人工智能·windows·git·bash
彭波3969 小时前
.NET Framework 3.5问题修复教程!可以离线修复
windows·安全·电脑·.net·开源软件
love530love10 小时前
OpenClaw 手机直连配置全流程
人工智能·windows·python·智能手机·c#·agent·openclaw
AnalogElectronic14 小时前
windows递归遍历当前目录下文件并重命名程序
windows
web3.088899914 小时前
taoxi商品详情|商品属性|包装规格信息 API接口
windows
新手886015 小时前
Oracle VirtualBox虚拟机安装 和 安装 window11版本虚拟机 及 启用EFI和硬盘无法使用 问题
服务器·windows·计算机网络·安全·虚拟机
门豪杰16 小时前
Windows下配置针对WSL的cc-switch
windows·claude·claude code·cc-switch·cc switch
姓王名礼16 小时前
一份 Windows/macOS/Linux 完整安装 + 运行 + 对接 WebUI 的步骤
linux·windows·macos
开开心心就好16 小时前
绿色版PDF多功能工具,支持编辑转换
人工智能·windows·pdf·ocr·excel·语音识别·harmonyos
武藤一雄17 小时前
C#常见面试题100问 (第一弹)
windows·microsoft·面试·c#·.net·.netcore