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();
        }
    }
}
相关推荐
一个人旅程~1 小时前
linux如何“抢”过windows的usb移动硬盘权限对0磁道损坏的移动硬盘进行尝试修复
linux·windows·经验分享·电脑
Keano Reurink2 小时前
长尾关键词自动化扩展:从1个种子词到1000个长尾词
运维·windows·自动化
新时代农民工~3 小时前
PostgreSQL 主从复制(流复制)实战配置指南:Windows 环境详细步骤
数据库·windows·postgresql
AI周红伟4 小时前
通用业务智能体OpenClaw+Skills+RAG+Agent构建案例实操
大数据·人工智能·windows·百度·copilot
a58808114 小时前
WarCraft III《魔兽争霸3冰封王座》原版安装包——游戏玩法、配置要求与详细安装教程
windows·游戏·游戏程序
Chirp6 小时前
Windows下借助wsl2读取ext4格式磁盘
linux·windows
CAE虚拟与现实8 小时前
img格式的文件在windows上怎么打开
windows·img文件·微软img
a58808119 小时前
星际争霸1原版安装包——游戏玩法、配置要求与详细安装教程
windows·游戏·游戏程序
A懿轩A10 小时前
Claude Code 2026 最新版下载安装教程详细版 涵盖Windows 和 MacOS 安装 附常见问题解决方案
windows·macos
dhjabc_110 小时前
Windows 超完整配置 OpenCode 教程(改D盘安装+永久国内镜像+全套使用指南)
windows