l MCI简介:
首先,让我们来看看MCI的定义:
MCI [2]( Media Control Interface,媒体控制接口 ) 向基于Windows操作系统的应用程序提供了高层次的控制媒体设备接口的能力。程序员不再需要关心具体设备的差异,就可以对激光唱机(CD)、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。应用程序通过MCI发送相应的命令来控制媒体设备。MCI分为命令字符串和命令消息两种,两者具有类似的功能。命令字符串具有使用简单的特点,但是它的执行效率略低于命令消息。
再看看MSDN如何说的:
The Media Control Interface (MCI) provides standard commands for playing multimedia devices and recording multimedia resource files. These commands are a generic interface to nearly every kind of multimedia device.
通过对MCI的定义我们可知,通过MCI我们可以操控几乎所有的媒体设备,它独立于设备,让我们可以更有效的进行媒体开发,而不必直到媒体设备的具体构造、工作原理等。还有一个必须要提一下的是:从MCI的定义中我们可以看出,与媒体设备通信是通过命令、消息来控制设备的,这也验证了SDK程序或者MFC之“以消息为基础,以事件驱动之”的道理。
l MCI设备类型
设备类型 | 字符串 | 文件类型 | 描述 |
CD audio | cdaudio |
| 音频 CD 播放器 |
Digital Audio Tape | dat |
| 数字音频磁带播放器 |
Digital video(not GDI-based) | DigitalVideo |
| 窗口中的数字视频 |
Other | Other |
| 未定义 MCI 设备 |
Overlay | Overlay |
| 覆盖设备 |
Scanner | Scanner |
| 图像扫描仪 |
Sequencer | Sequencer | .mid | 音响设备数字接口 (MIDI) 序列发生器 |
Vcr | VCR |
| 视频磁带录放器 |
AVI | AVIVideo | .avi | 视频文件 |
videodisc | Videodisc |
| 视盘播放器 |
waveaudio | Waveaudio | .wav | 播放数字波形文件的音频设备。 |
l MCI的基本操作
命令 | MCI 命令 | 描述 |
Open | MCI_OPEN | 打开 MCI 设备。 |
Close | MCI_CLOSE | 关闭 MCI 设备。 |
Play | MCI_PLAY | 用 MCI 设备进行播放。 |
Pause | MCI_PAUSE 或 MCI_RESUME | 暂停播放或录制。 |
Stop | MCI_STOP | 停止 MCI 设备。 |
Back | MCI_STEP | 向后步进可用的曲目。 |
Step | MCI_STEP | 向前步进可用的曲目。 |
Prev | MCI_SEEK | 使用 Seek 命令跳到当前曲目的起始位置。如果在前一 Prev 命令执行后三秒内再次执行,则跳到前一曲目的起始位置;或者如果已在第一个曲目则跳到第一个曲目的起始位置。 |
Next | MCI_SEEK | 使用 Seek 命令跳到下一个曲目的起始位置(如果已在最后一个曲目,则跳到最后一个曲目的起始位置)。 |
Seek | MCI_SEEK | 向前或向后查找曲目。 |
Record | MCI_RECORD | 录制 MCI 设备的输入。 |
Eject | MCI_SET | 从 CD 驱动器中弹出音频 CD。 |
Save | MCI_SAVE | 保存打开的文件。 |
更详细的命令表可以参考:
http://www.7880.com/Info/Article-822d3200.html
http://www.hostultra.com/~lucknet/programming/c/learnvc/005.html
l MCI常用API
下面看看与MCI相关的常用API的解析:
所有的MCI命令字符串都是通过多媒体API函数mciSendString传递给MCI的,该函数的声明为:
1.
MCIERROR mciSendString(
LPCTSTR lpszCommand, //MCI命令字符串
LPTSTR lpszReturnString, //存放反馈信息的缓冲区
UINT cchReturn, //缓冲区的长度
HANDLE hwndCallback //回调窗口的句柄,一般为NULL
); //若成功则返回0,否则返回错误码。
该函数返回的错误码可以用mciGetErrorString函数进行分析,该函数的声明为:
BOOL mciGetErrorString(
DWORD fdwError, //函数mciSendString或mciSendCommand返回的错误码
LPTSTR lpszErrorText, //接收描述错误的字符串的缓冲区
UINT cchErrorText //缓冲区的长度
);
下面是使用mciSendString函数的一个简单例子:
char buf[50];
MCIERROR mciError;
mciError=mciSendString(“open cdaudio”,buf,strlen(buf),NULL);
if(mciError)
{
mciGetErrorString(mciError,buf,strlen(buf));
AfxMessageBox(buf);
return;
}
2.
MCI的命令消息接口提供了C语言接口,它速度更快,并且更能符合C/C++程序员的需要。所有MCI命令消息都是通过mciSendCommand函数发送的,该函数的声明为:
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice, //设备的ID,在打开设备时不用该参数
UINT uMsg, //命令消息
DWORD fdwCommand, //命令消息的标志
DWORD dwParam //指向包含命令消息参数的结构
); //若成功则返回0,否则返回错误码
这里值得注意的是:当MCI使用MCI_OPEN控制消息打开一个多媒体设备时,可以不传入这个参数,而将它设置为NULL,如果打开正常,MCI会自动创建一个32位的整数来表示已经打开的多媒体设备具体的值可以通过mciOpenParms(数据类型为MCI_OPEN_PARMS)中的wDeviceID获得,也可以通过调用mciGetDeviceID函数来获得,以后打开设备所进行的操作都是通过这个整数标识(也即设备ID)来寻找设备对象的。
例如打开视频设备代码如下:
MCI_OPEN_PARMS mciOpenParms;
mciOpenParms.lpstrDeviceType=”AviVideo”; //设置播放设备为视频播放设备
mciOpenParms.wDeviceID=NULL; //设备ID设为NULL
mciOpenParms.dwStyle=WS_CHILD|WS_VISIBLE
……
//如果打开设备不成功
If(mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS,(DWORD)(LPVOID)& mciOpenParms))
{
//不成功的处理代码
}else{
//打开成功的处理代码
myDeviceID=mciOpenParms.wDeviceID; //获取设备ID
}
MciSendCommand函数的第四个参数是一个指向消息数据结构的指针,其结构由具体的消息类型来决定,例如在上面的例子中消息类型为MCI_OPEN_PARMS。
关于MCI的API现在还没有看出它们在实际中如何应用,现在只是做个大概的了解,让自己在心里有这个概念。
l MCI消息数据结构
上面在介绍MciSendCommand函数的第四个参数dwParam的时候已经提到了一下,现在我们来看看MCI的一些消息数据结构,看看他们都在发送什么常用命令的时候用到。
命令 | 对应数据结构 | 命令 | 对应数据结构 |
MCI_OPEN | MCI_DGV_OPEN_PARMS | MCI_SET | MCI_DGV_SET_PARMS |
MCI_PLAY | MCI_DGV_PLAY_PARMS | MCI_PUT | MCI_DGV_PUT_PARMS |
MCI_CLOSE | 没有对应数据结构 | MCI_SEEK | MCI_SEEK_PARMS |
MCI_STOP | 没有对应数据结构 | MCI_STATUS | MCI_DGV_STATUS_PARMS |
MCI_PAUSE | MCI_DGV_PAUSE_PARMS | MCI_WHERE | MCI_DGV_WHERE_PARMS |
MCI_STEP | MCI_DGV_STEP_PARMS |
|
|
消息数据的主要用法是,把消息数据结构中的成员赋予相应值,然后通过mciSendCommand函数把此消息数据按传地址方式传过去,操作成功后就可以查看该消息数据中的你需要的内容,当然每个消息的成员的数据成员都有可能不一样,在这里列出所有的消息结构显得不太合适,MSDN已经很完善了。
这里我还要提一下的就是MCI_DGV_STATUS_PARMS这个消息书籍结构,它可以用于多个地方,例如查看播放速度、获得视频现在的播放位置等等,这个结构中的两个成员dwItem和dwReturn很有意思,例如你将dwItem赋值为MCI_STATUS_POSITION时,得到dwReturn的值是视频现在的播放位置,而当你dwItem赋值为MCI_DGV_STATUS_SPEED时,得到dwReturn的值是视频的播放速度。
其实MCI编程并不难,比较烦人的地方就是它有太多的参数要记,而这么多参数中又有很多不同的数据结构,解决的唯一办法就是多练习多记,只有在熟悉大部分数据结构的基础上才能在MCI编程里面游刃有余。
参考资料:
http://hi.baidu.com/hacknothack/blog/item/77783923e81d5f4c92580713.html
http://www.7880.com/Info/Article-822d3200.html
http://www.hostultra.com/~lucknet/programming/c/learnvc/005.html