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();
        }
    }
}
相关推荐
DevilSeagull11 分钟前
Windows 批处理 (Batch) 编程: 从入门到入土. (一) 基础概念与环境配置
开发语言·windows·后端·batch·语言
CyL_Cly1 小时前
Parsec(parsec安卓/windows/macos下载)
windows
2601_958320572 小时前
【小白零基础上手 】钉钉内部机器人接入 OpenClaw 完整流程讲解(含安装包)
人工智能·windows·机器人·钉钉·open claw·open claw安装
love530love3 小时前
f2 项目(多平台的作品下载与接口数据处理)源码部署记录
人工智能·windows·f2
生而为虫3 小时前
在VScode中使用Claude Code agent并配置模型(仅mac电脑实际操作,windows电脑未实际操作如有问题可留言)
windows·vscode·macos
叶小鸡3 小时前
Java 篇-项目实战-天机学堂(从0到1)-day10
windows·microsoft
love530love4 小时前
如何在 Google Chrome 中强制开启 Gemini AI 侧边栏(完整图文教程)
前端·人工智能·chrome·windows
skilllite作者4 小时前
Zed 1.0 编辑器深度评测与实战指南
开发语言·人工智能·windows·python·编辑器·agi
杜哥无敌4 小时前
FreeSSHd vs FileZilla Server vs SFTPGo:Windows SFTP服务器易用性终极横向测评
运维·服务器·windows
李白的天不白4 小时前
vue 数据格式问题
前端·vue.js·windows