“菜狗音乐”实现 - 1.C++封装MCI

这篇博客详细介绍了如何使用MCI接口在C++中实现音乐播放功能,包括打开、关闭、播放、暂停、设置音量等操作。通过mciSendString函数封装MCI命令,解决了文件名含有空格的问题,并提供了获取歌曲长度和当前位置的方法。此外,还讨论了音量调节的细节和处理未播放歌曲时的音量设置。
摘要由CSDN通过智能技术生成

菜狗音乐中封装都是MCI中mciSendString函数

1.open函数和音乐名称带有空格的解决办法

bool open(std::wstring& wstr) {
		close();
		last = wstr;
		order = L"open ";
		order += wstr;
		bool b =  (0 == mciSendString(order.c_str(), nullptr, 0, nullptr));
		if(b)
			set_audio(audio_size);
		return b;
	}

解释:close();每次打开都会关闭之前打开文件。

last = wstr;保存本次打开文件的名称,如果大家的文件名字中带有空格,可以在名字外面加上”“

                比如 DJ - 大风车 应该写成 “DJ - 大风车”

                如果直接写 DJ - 大风车 会被歌曲的名字是DJ 后面多出来的 - 大风车 会导致指令错误

 order = L"open " + wstr; 调用open指令播放歌曲

0 == mciSendString(order.c_str(), nullptr, 0, nullptr); mciSendString返回0说明执行成功

set_audio(audio_size); 设置音量,因为打开默认最大音量

                所以如果播放了新的歌曲,需要设置为之前的音量大小

2.close函数

void close() {
		if (!last.empty())
		{
			order = L"close ";
			order += last;
			last.clear();
			mciSendString(order.c_str(), nullptr, 0, nullptr);
		}
	}

void close(std::wstring& wstr) {
		if (!wstr.empty())
		{
			order = L"close ";
			order += wstr;
			last.clear();
			mciSendString(order.c_str(), nullptr, 0, nullptr);
		}
	}

if (!last.empty());防止关闭不存在文件导致错误

3.open函数

void play() {
		order = L"play ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

void play(int time) {
		order = L"play ";
		order += last;
		order += L" from ";
		order += std::to_wstring(time * 1000);
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

play 歌曲 from 位置;其中位置参数是现实时间*1000得到

                比如 播放1:23秒位置

                参数 time = 83;

                 实际执行指令:play “DJ - 大风车” from 83000;

4.返回歌曲总长和当前时间

int get_length() {
		order = L"status ";
		order += last;
		order += L" length";
		mciSendString(order.c_str(), data, 32, nullptr);
		order = data;
		return order.empty() ? 0 : std::stoi(order) / 1000;
	}

int get_postion() {
		order = L"status ";
		order += last;
		order += L" position";
		mciSendString(order.c_str(), data, 32, nullptr);
		order = data;
		return order.empty() ? 0 : std::stoi(order) / 1000;
	}

5.暂停和继续播放

void resume() {
		order = L"resume ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

void pause() {
		order = L"pause ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

6.设置音量

void set_audio(int size)
	{
		audio_size = size;
		if (last.empty())
			return;
		order = L"setaudio ";
		order += last;
		order += L" volume to ";
		order += std::to_wstring(size * 10);
		mciSendString(order.c_str(), nullptr, 0, nullptr);

	}

MCI中音量可以0-1000但是外部接口的音量一般是0-100,所以内部*10

先执行audio_size = size;的原因:需要考虑一种情况,如果音乐播放器被打开,但是没有播放任何一个歌曲,这个时候调节音量,我们必须保存调节之后的值,虽然这次操作前没有打开任何歌曲,调节音量是不正确的。

7.全部代码

#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

#include<stdio.h>

/**********************     music    音乐播放接口     **********************/
class music {
private:
	static std::wstring last;
	static std::wstring order;
	static wchar_t data[32];
	static int audio_size;

public:
	static void close() {
		if (!last.empty())
		{
			order = L"close ";
			order += last;
			last.clear();
			mciSendString(order.c_str(), nullptr, 0, nullptr);
		}
	}

	static void close(std::wstring& wstr) {
		if (!wstr.empty())
		{
			order = L"close ";
			order += wstr;
			last.clear();
			mciSendString(order.c_str(), nullptr, 0, nullptr);
		}
	}

	static bool open(std::wstring& wstr) {
		close();
		last = wstr;
		order = L"open ";
		order += wstr;
		bool b =  0 == mciSendString(order.c_str(), nullptr, 0, nullptr);
		if(b)
			set_audio(audio_size);
		return b;
	}

	static void play() {
		order = L"play ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

	static void play(int time) {
		order = L"play ";
		order += last;
		order += L" from ";
		order += std::to_wstring(time * 1000);
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

	static int get_length() {
		order = L"status ";
		order += last;
		order += L" length";
		mciSendString(order.c_str(), data, 32, nullptr);
		order = data;
		return order.empty() ? 0 : std::stoi(order) / 1000;
	}

	static int get_postion() {
		order = L"status ";
		order += last;
		order += L" position";
		mciSendString(order.c_str(), data, 32, nullptr);
		order = data;
		return order.empty() ? 0 : std::stoi(order) / 1000;
	}

	static void resume() {
		order = L"resume ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

	static void pause() {
		order = L"pause ";
		order += last;
		mciSendString(order.c_str(), nullptr, 0, nullptr);
	}

	static void set_audio(int size)
	{
		audio_size = size;
		if (last.empty())
			return;
		order = L"setaudio ";
		order += last;
		order += L" volume to ";
		order += std::to_wstring(size * 10);
		mciSendString(order.c_str(), nullptr, 0, nullptr);

	}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值