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();
        }
    }
}
相关推荐
泓铮8 小时前
Windows 环境下 WSL2 与 VMware Workstation 17 共存机制研究与工程实践
windows
明湖起风了11 小时前
mqtt消费堆积
java·jvm·windows
私人珍藏库11 小时前
[Windows] 【灵犀Claw生成】酷狗加密音乐批量转换工具 Xy Music Converter
windows·工具·软件·多功能
handsomestWei13 小时前
claude-code在win环境安装使用
windows·ai编程·claude·安装配置·cc-switch
秦时明月之君临天下14 小时前
Windows如何删除任务管理器中的某个服务?
windows
麦田里的守望者_zhg15 小时前
Windows 执行 wsl --update 报错 1603:注册表权限导致 WSL 安装损坏问题排查与修复
windows
❆VE❆16 小时前
Claude Code 安装与配置完整指南(Windows)
windows·claude code
航Hang*17 小时前
VMware vSphere 云平台运维与管理基础——第5章:VMware vSphere 5.5 高级特性
运维·服务器·开发语言·windows·学习·虚拟化
Mapleay17 小时前
Ubuntu 源的重要性!之 libgmp-dev 无法安装
linux·服务器·windows
humors22117 小时前
微软工具包下载网址
windows·microsoft·微软·office·工具包·sysintervals