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();
        }
    }
}
相关推荐
女程序猿!!!6 小时前
视频分辨率
windows
不讲废话的小白6 小时前
文件拖不进企微了怎么办
windows·企微
聪明努力的积极向上6 小时前
【.net framework】WINDOWS服务和控制台程序简单介绍
windows·.net
程序员霸哥哥10 小时前
snipaste免费版下载安装使用教程(附安装包)
windows·microsoft·snipaste
程序员霸哥哥11 小时前
Keil5下载教程及安装教程(附安装包)
windows·keil5·keil5下载教程·keil5安装教程
AI大模型学徒12 小时前
Chatbox 安装 for Windows
windows·语言模型·chatgpt
千里马学框架14 小时前
windows系统上aosp15上winscope离线html如何使用?
android·windows·html·framework·安卓窗口系统·winscope
2501_9389639614 小时前
Flutter 3.19 桌面应用开发:适配 Windows/macOS 端窗口大小与菜单栏自定义
windows·flutter·macos
G311354227314 小时前
云服务器系统 选择Windows和Linux的理由
linux·服务器·windows
龙须草AI笔记16 小时前
N8N系列:新手课程,本地 N8N 不安全?Windows 下 HTTPS 配置指南,新手也能看懂
windows·安全·https·入门教程·ai技术·ai工具·n8n