Operating system interface functions:
mciSendString
example:
Win32Mci mci(“C:\Morning Sword Dance_Haoqing Jiuzhou.mp3”);
mci.Play();
head File:
#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 & amp; 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 & amp; command) const; bool PlayCommand(const std::string & amp; command) const; void Close() noexcept; private: std::string path_; std::string alias_; bool Repeat_; }; } }
Source File:
#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 & amp; 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\ ")); 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 & amp; 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 & amp; command) const { return mciSendStringA(command.c_str(), nullptr, 0, nullptr) == MMSYSERR_NOERROR; } void Win32Mci::Close() noexcept { PlayCommand("close " + alias_); } void Win32Mci::Dispose() noexcept { Close(); } } }