mciSendString函数简介(播放音乐以及录音相关操作)

news2024/11/27 0:38:02

函数功能:播放多媒体音乐,视频等

mciSendString是用来播放多媒体文件的API指令,可以播放MPEG,AVI,WAV,MP3,等等。这个函数有自己的mci指令,可以通过不同的指令实现不同的功能。这里我会详细讲解mciSendString这个函数的常见用法,以及怎么去对音乐播放,快进、快退、录音等功能。

目录

设置环境

 mciSendString函数相关介绍

        mciSendString函数的参数(一共有4个参数):

 1.播放功能

 2.关闭结束播放

 3.暂停与继续

4.音量的调节

 5.快进,快退

6.进度条显示以及打印进度条

7.录音功能


设置环境

 首先要建立一个vs文件

 建立好了之后,要调整项目的属性

 改用为多字节字符集,否则会报错。

 然后点去链接器中的输入,找到附加依赖项,点进去编译,导入静态库,winmm.lib

 最后去关闭 SDL安全检查,改成否就行了

 mciSendString函数相关介绍

头文件:#include<Windows.h>
               #include<mmsystem.h>

静态库:#pragma comment(lib,"winmm.lib")

 在文件项目已经导入静态库的情况下,可加可不加;如果没有导入静态库,就必须在头文件下面加上静态库

        mciSendString函数的参数(一共有4个参数):

#include<Windows>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")//已导入静态库,可写可不写

MCIERROR mciSendString(
LPCTSTR lpszCommand, //命令字符串:如 open、play 、close等
LPTSTR lpszReturnString, //接受返回信息的字符串 ,即字符串
UINT cchReturn,   //返回字符串的大小,sizeof
HANDLE hwndCallback //回调窗口句柄,一般设置为NULL
);
//模板
	mciSendString(操作指令 , 获取返回的信息(字符串) , 返回信息的长度 , 窗口句柄(一般为NULL));

相关指令:

 1.播放功能

这里我的当前音乐文件相对路径 kk.mp3 , 如果想要播放这个音乐,我们可以通过open与play这两个指令进行播放。

	mciSendString("open kk.mp3 alias music", 0, 0, 0);//alias是别名的意思,下面就可以去直接用music来代替kk.mp3
	mciSendString("play music", 0, 0, 0);//播放音乐

 在打开文件时我以及给这个mp3文件取了别名,下面我是直接用music来表示这个文件的名字.

如果我们想重复播放音乐,那么就直接在play music后面加上repeat 就行了

mciSendString("open kk.mp3 alias music", 0, 0, 0);
mciSendString("play music repeat", 0, 0, 0);

如果我们想等播放完了音乐在接着执行下面的语句,那就在play music后面加上wait

mciSendString("open kk.mp3 alias music", 0, 0, 0);
mciSendString("play music wait", 0, 0, 0);

如果想播放视频,全屏播放加上fullscreen就OK

mciSendString("play music fullscreen", 0, 0, 0);

 2.关闭结束播放

当播放完毕后要关闭音乐。

mciSendString("close music", 0, 0, 0);

 3.暂停与继续

当然了,播放音乐嘛,暂停与继续是少不了的,对此我们也可以通过mciSendString来实现这个功能的。

//暂停
mciSendString("pause music",0,0,0);
//或者  
mciSendString("stop music",0,0,0);

//继续播放
mciSendString("resume music",0,0,0);

 所以我们可以通过键盘指令来控制音乐的播放与暂停,代码如下:

void stopresume()
{
	char ch;
	int i = 1;
	//这个表示在键盘获取一个字符,但是不打印出来,接着继续往下执行,getch函数的头文件是#include<conio.h>
	mciSendString("play music", 0, 0, 0);//开始,先播放音乐
again:
	ch = getch();
	if (ch == ' '&& i % 2!= 0)//如果获取的字符为空格,同时i为奇数的话,那么就暂停
	{
		mciSendString("pause music", 0, 0, 0);
		++i;
	}
	else if (ch ==' ' && i % 2 == 0)//如果获取的字符为空格,同时i为偶数的话,那么就继续
	{
		mciSendString("resume music", 0, 0, 0);
		++i;
	}
	goto again;//回到上面,继续以下的操作
}

看吧,这个函数的功能跟我们平时用的软件暂停继续播放功能一模一样,按空格就暂停,再按一次就继续播放。 

4.音量的调节

(1)获取当前的音量

	char a[100];
	mciSendString("status music volume", a, 100, 0);//获取此时的音量数据返回到a,这里的100是表示a的长度,sizeof(a)
//其中a是字符串,如果想把a转换为数字,可以调用atoi函数
int b=atoi(a);//通过atoi函数进行字符数字串转换到int类型
char s[100];
sprintf(s, "setaudio music volume to %d", b%1000+200);//这里建议去取模,此时获得的音量加上200,再除以1000乘上此时媒体音量就是将要播放出来的音量
mciSendString(s,0,0,0);

 我们可以在这个基础上进行音量的加减,例如:

当前媒体音量

我们可以直接通过mciSendString("setaudio music volume to a",0,0,0),其中a是一个数字,来实现播放音量的改变,这个音量的换算是此时多媒体的音量乘上a/1000,所以这个a的范围是0~1000;如果a超过了1000,那么实际上a还是以1000来算。

mciSendString("setaudio music volume to 800",0,0,0);
//意思是把音量调节到当前媒体音量的80%,换算过来就是此时的音量为32

既然知道了这些,那我们怎么去通过键盘或者鼠标的外部操作来改变播放音量呢?其实非常简单,利用循环就可以搞定了,代码如下:

void volume()
{
int i=0;
char a[100];
	mciSendString("open kk.mp3 alias music", 0, 0, 0);
while (true) {
	mciSendString("play music", 0, 0, 0);
	char s = getch();//在键盘上获取一个字符,但是不打印出来,接着往下执行
    system("cls");//清屏
	if (s == 'w')//如果获取的字符为w,那么音量加100
		i += 100;
	else if(s=='s')//如果为s,音量减少100
		i -=100 ;
printf("%d",i);//打印此时的音量
	sprintf(a, "setaudio music volume to %d", i);//把此时的音量以及操作字符串赋给a
	mciSendString(a, 0, 0, 0);//音量的设置
	
}
}

这个函数的功能其实就是我们用的音乐软件里面的音量调节功能一样的,如下所示:

 5.快进,快退

播放多媒体音乐或者视频的时候,我们可以通过mciSendString函数的指令来实现快进,快退的。

//mci 中的seek指令可以实现把播放进度从某一个位置开始,从而实现快进与快退
mciSendString("seek music to 7*1000", 0, 0, 0);//这里表示把music从7秒处开始播放
//这个时间的单位是毫秒,所以我写成7*1000 比较直观表示的7秒

 我们也可以用start与end来表示从头开始(当然,音乐一般自然而然是从头开始的),或者直接把播放进度拉倒尾部。如下所示:

	mciSendString("seek music to start", 0, 0, 0);//从开头开始播放

	mciSendString("seek music to end", 0, 0, 0);//从最后位置开始播放

既然如此,我们可以通过键盘来实现快进快退,代码如下:

void forwardbackdard()
{
	char arr;
	int i = 0;
	char ss[100];
	mciSendString("open kk.mp3 alias music", 0, 0, 0);
	while (true)
	{
		mciSendString("play music", 0, 0, 0);
		arr = getch();
		system("cls");
		if (arr == 'd')
			i += 2 * 1000;//每次快进2秒
		else if (arr == 'a')
			i -= 2 * 1000;//每次快退了2秒
		sprintf(ss,"seek music to %d", i);//懂的都懂
		mciSendString(ss, 0, 0, 0);
		printf("%d", i/1000);//打印出此时快进或者快退了多少秒
	}
}

6.进度条显示以及打印进度条

 进度条,顾名思义就是在一段有限的线长度来表示音乐的时间长度,这里我们可以通过图形库去打印出进度条,或者在控制面板上用符号去打印进度条。

        要想打印出进度条,首先就要获取到歌曲的时间长度,可以用mci指令中的length来获取时间长度(其中的时间长度单位是毫秒来计算的,跟音量一样)。

char length[100];
mciSendString("status music length", length, 100, 0);//获取音乐长度,返回到字符串length
//同上我们可以把字符串转换为int类型
int num;
num=atoi(length);

        其次还有获取此时音乐播放了多少的长度,mci指令中的position来获取此时此刻已播放时间的长度。

char now[100];
mciSendString("status music position", now, 100, 0);//把此时此刻已播放的时间以字符串形式返回到字符串now中
int t;
t=atoi(now);//转化到int类型

下面我通过图形库来打印出进度条,完整代码奉上:

#include<stdio.h>
#include<graphics.h>
#include<Windows.h>
#include<mmsystem.h>
void progress()
{
	char length[100];
	char now[100];
	int x;
	int t = 0;
	int time;
	mciSendString("status music length", length, 100, 0);
	time = atoi(length);
	while (true) {
		
		x = getwidth() * t / time;	//获取窗口的宽度乘上此时的进度/总进度
		setfillcolor(BLUE);//设置填充颜色为蓝色
		fillrectangle(0, 300, x, 320);//画一个长方形,这个长方形会随着x的值变化
			fillcircle(x, 310, 10);//画一个填充圆
		mciSendString("status music position", now, 100, 0);
		 t = atoi(now);	
	}
}
void alllong()//画出进度总长度,初始化
{
	setfillcolor(RGB(100, 100, 100));//颜色为灰色
	fillrectangle(0, 300, 1000, 320);
}
int main()
{
	                                      
	initgraph(1000, 400);
	alllong();
	mciSendString("open 2.mp3 alias music", 0, 0, 0);
	mciSendString("play music", 0, 0, 0);
	progress();
    system("pause");
}

下面是运行结果:

7.录音功能

千万别以为mciSendString函数只有播放功能,其实这个函数还有录音功能,通过相关指令,从而实现录音并且生成音频文件保存到电脑中。

        实现录音可以分4步走:首先打开一个录音文件,然后记录录下的声音,再保存到计算机里面去,最后关闭文件,(其实会发现这个过程跟文本文件的写入几乎一样)。

mciSendString("open new type waveaudio alias moo", 0, 0, 0);//打开建立一个声音类型的文件项目,别名为moo
mciSendString("record moo", 0, 0, 0);//开始记录声音

//中间这里可以通过延迟函数Sleep去控制录音时间,或者自行设立一个结束录音按键

mciSendString("save moo e:\\jojo\\123.mp3", 0, 0, 0);//设为mp3格式(还可以设置为其他格式例如wav),保存到 ……
mciSendString("close moo", 0, 0, 0);//关闭这个项目

        上面4步可以虽然可以录音,但是效果并不是非常专业化。如果想要提高专业性,mci指令是相对比较多的,首先要设置好声音的清晰度(位度),可接收的声音频率(赫兹),还有播放的声道(单声道或者双声道),另外还有声音的编码格式(如不同类型声音的数字信号与模拟信号的编码格式),等等……这里我就不过多讲,如果想了解更多http://t.csdn.cn/NclCi

         那,这里我就写一个完整的代码奉上:

#include<stdio.h>
#include<Windows.h>
#include<mmsystem.h>
void recordvoice()
{
//初始化声音规格
	mciSendString("set wave bitpersample 8", 0, 0, 0);//设置音频的位度 8位,(还有16,24位,位度越高,声音越清晰)
	mciSendString("set wave samplespersec 1",0,0, 0);//设置录音赫兹,11025是人类可
	mciSendString("set wave channels 2", 0, 0, 0);//设置声道,2是表示立体声(双声道),1是表示单声道
	mciSendString("set wave format tag pcm", 0, 0, 0);//设置pcm格式,是数字信号比模拟信号质量要好
	mciSendString("open new type waveaudio alias moo", 0, 0, 0);//打开建立一个声音类型的文件项目
	mciSendString("record moo", 0, 0, 0);//开始记录声音
	char d;
	d = getch();
	if (d == ' '); //按下空格表示录音结束
	{
        printf("录音结束\n");
		mciSendString("save moo e:\\jojo\\123.wav", 0, 0, 0);//保存
		mciSendString("close moo", 0, 0, 0);//关闭
	}
}
int main()
{
	                                      
	prinft("开始录音\n");
	recordvoice();
    system("pause");
}

就介绍到这里吧,欢迎各位阅读,如果学会了mciSendString函数的小伙伴们,记得关注关注随便点个赞呗,下一期讲讲怎么利用mciSendString函数,做一个音乐播放器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/585561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Web】HTTP代理和反向代理

直接访问 就是从客户端直接访问服务端&#xff0c;相当于我直接去厂家买可乐&#xff0c;没有中间商赚差价 HTTP代理 HTTP代理指在客户端先访问代理服务器&#xff0c;然后由代理服务器去访问服务端&#xff0c;代理服务器收到响应后再转发个客户端&#xff0c;就像我去商店…

【C++】类与对象——六个默认成员函数、构造函数的概念和特征,析构函数的概念和特征

文章目录 1.类的六个默认成员函数2.构造函数2.1构造函数的概念2.2构造函数的特性 3.析构函数3.1析构函数的概念3.2析构函数的特征 1.类的六个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。   空类中真的什么都没有吗&#xff1f; 并不是&#xff0c;任何…

跨域图像识别

跨域图像识别 跨域图像识别&#xff08;Cross-domain Image Recognition&#xff09;是指在不同的数据集之间进行图像分类或识别的任务。由于不同数据集之间的分布差异&#xff0c;跨域图像识别面临着很大的挑战。 以下是几种代表性的跨域图像识别算法&#xff1a; DDC&#…

利用代码实现自动刷网课阅读时长功能 JAVA

目录 前言&#xff1a;理论依据&#xff1a;现实依据&#xff1a;朴素版只能循环阅读不能翻页&#xff1a;升级版 翻页 阅读&#xff1a;如何使用&#xff1a; 前言&#xff1a; 最近不也快结课了&#xff0c;网课该刷的都要刷掉&#xff0c;最近不就把一门思政课刷完了&#…

粉丝经济:互帮互助,众筹,人人帮我我帮人人

目录 用户精准定位&#xff1a; 用户裂变 用户在线“买卖需要注册&#xff1a;为后期思域流量变现 用户容器“APP&#xff0c;小程序”&#xff1a;用户资产化 LBS(一人千面&#xff0c;个性化定制&#xff0c;根据地理位置进行提醒&#xff1a;优惠券”) 粉丝渠道化&…

信息安全实践1.1(网络嗅探)

前言 这个网络嗅探其实就是用wireshark抓包。那时候赶着做&#xff0c;就随便写了点。参考价值比较少。 第一次实践是因为寒假在家摆烂&#xff0c;然后开学前两天做的&#xff0c;所以质量不是很好。不过也算是一次实践&#xff0c;看看就好。 要求 使用网络嗅探工具抓获网络…

TiDB x Bolt丨超强可扩展性与弹性助力超 1 亿用户畅享出行服务

作者&#xff1a;PingCAP 封小明 通过 TiDB 连接全球极限场景和创新场景&#xff0c;是 PingCAP 长期坚持的国际化战略。目前&#xff0c;在全球已有超过 3000 家企业选择 TiDB。无论在游戏、金融、物流、互联网还是智能制造等行业&#xff0c;基于规模化 OLTP 扩容、实时 HTA…

为什么说企业需要搭建产品手册?

企业需要搭建产品手册的原因有很多&#xff0c;其中包括提高产品使用体验、降低售后服务成本、促进产品销售等。本文将从这些方面来介绍企业为什么需要搭建产品手册&#xff0c;并探讨如何有效地搭建和管理产品手册。 一、提高产品使用体验 产品手册是一份指导用户如何正确使…

【数据结构】二叉树——链式结构的实现(代码演示)

目录 1 二叉树的链式结构 2 二叉树的创建 3 二叉树的遍历 3.1 前序遍历 3.1.1运行结果&#xff1a; 3.1.2代码演示图: 3.1.3 演示分析&#xff1a; 3.2 中序遍历 3.3 后序遍历 3.4 层序遍历 4 判断是否是完全二叉树 5 二叉树节点的个数 5.1 总个数 5.2 叶子节点…

Electron-Builder Windows系统代码签名

前言 项目打包签名是两年前做的了&#xff0c;使用Electron-Bulder&#xff0c;打包工具版本迭代较少&#xff0c;倒是electron版本更新飞快&#xff0c;目前官方推荐使用Electron Forge进行打包&#xff0c;后续再对两者进行对比&#xff0c;重新整理现在的实现方案。 签名简…

微信扫码授权到登录网页,中间究竟发生了什么?

关于我昨天突然接到神秘“面试”&#xff1a;微信扫码授权登录的实现逻辑是神魔&#xff1f;在这个扫码授权的过程中客户端、服务端、微信平台都做了些神魔&#xff1f;二维码里面又有哪些信息&#xff1f; 从手机微信扫一扫二维码到登录个人的知乎账户&#xff0c;中间究竟发生…

智警杯赛前学习1.2--excel统计函数

常用统计函数 count countif&#xff08;区域&#xff0c;条件&#xff09; countifs&#xff08;区域&#xff0c;条件&#xff0c;区域&#xff0c;条件&#xff09; 求和函数 sum sumif&#xff08;区域&#xff0c;条件&#xff0c;[求和区域]&#xff09; sumifs&#xff…

AOP日志功能实现

AOP日志功能实现 1、添加两个工具类2、新建一个接口为 LogAnnotation3、新建一个类 LogAspect4、使用自定义注解 LogAnnotation5、运行结果6、项目结构 转载自b站&#xff1a;码神之路 1、添加两个工具类 HttpContextUtils 用于获取当前请求的 HttpServletRequest 对象&#xf…

Pycharm中安装jupyter 以及一些会遇到的问题

1、确保电脑安装了 anaconda 和jupyter notebook 2、在命令行 启动jupyter Notebook &#xff08;启动后不要关闭这个命令窗口&#xff09; 命令&#xff1a;juputer Notebook 成功运行后的网页界面&#xff1a; 3、打开Pycharm 创建新的项目 &#xff08;注意是Conda) 4、 创…

【微信小程序开发小白零基础入门】微信小程序入门【建议收藏】

微信小程序入门 文章目录 微信小程序入门前言一、小程序的概述1.小程序简介2.小程序诞生3.小程序功能4.小程序创建步骤 二、小程序的准备工作1.注册开发者账号2.小程序信息完善3.成员管理 三、小程序的开发工具3.其他辅助工具 四、推荐小程序&#xff08;欢迎各位大佬指导&…

STM32F4_常用存储器简介

目录 1. 存储器的种类 单片机和电脑一样&#xff0c;其内核分别为ARM和CPU(CPU通常是不具备存储功能的)&#xff0c;内核是用来进行数据的运算和处理的。内核处理数据的来源就是存储器。 1. 存储器的种类 RAM存储器&#xff1a; RAM是 “Random Access Memory”的缩写&#x…

Java 集合、数组、字符串的相互转换(关于list.toArray(new String[0])的源码分析)

在 Java 中&#xff0c;可以通过以下方式实现集合、数组和字符串之间的相互转换。 一、集合和数组的相互转化 ①、将集合转为数组&#xff1a;&#xff08;toArray 方法&#xff09; List<String> list new ArrayList<>(); list.add("apple"); lis…

异构跨库数据同步还在用Datax?来看看这几个开源的同步方案

在遇到跨库或者异库数据同步时&#xff0c;我们一般都会借助ETL工具来实现数据同步功能。比如目前大家较为熟知的Kettle和Datax。但是&#xff0c;这两个需要定时去查询数据库的数据&#xff0c;会存在一定的延迟&#xff0c;而且&#xff0c;默认采用全量同步的方式&#xff0…

Java Spring概述

文章目录 1、Spring是什么&#xff1f;2、Spring 的狭义和广义3、Spring Framework特点4、Spring模块组成5、Spring6版本要求 1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff…

AD原理图元器件封装绘制

元器件封装界面 1.元器件可以新建原理图库&#xff0c;然后在新建的库中添加 2.采用下图中的方式&#xff0c;随便右键某个库中的元器件&#xff0c;选择“Edit…”&#xff0c;进入到元器件封装绘制界面 元器件封装设计步骤 1.点击工具——新器件 输入新器件ID&#xff0c…