mciSendString 的两个小坑

博客园地址

刚刚修正了自己用的小闹钟的代码。

坑1:REPEAT 选项的作用范围

原来用得好好的,之后选择 .wav 文件,居然不出声音了……

诶,MCI 肯定支持 .wav 的啊……

仔细想想,我以前都是选 .mp3 作为闹铃,和这个有关系吗?

查看源代码。

strSend = "PLAY " & STRING_SOUND_ALIAS & " REPEAT"
Call mciSendString(strSend, rbuf, 0, 0)

为了将我从睡梦中闹醒(一般来说我睡得很死的……),我选用了 REPEAT 选项来循环播放。

嗯,有。记得在哪里读到过,PLAY 指令的 REPEAT 选项只能作用于 MPEGVideo 类型的文件。(时间也这么晚了, 我想记录完直接睡觉,就不找引用来源了。)

那就很简单,打开的时候作为 MPEGVideo 打开就好了。

strSend = "OPEN " & Chr$(34) & FileName & Chr$(34) & " ALIAS " & STRING_SOUND_ALIAS & " TYPE MPEGVIDEO"
Call mciSendString(strSend, rbuf, 0, 0)

坑2:文件名长度

应该好了吧……来,试一下。

D:\Music\Themes\Anison Piano ~marasy animation songs cover on piano~ marasy\marasy - Anison Piano ~marasy animation songs cover on piano~.wav

嗯?没有特殊字符啊,为什么还是无法播放呢?(我没写调试输出,所以如果看成一个黑盒的话,我看到的结果只有无法播放。)总长度也明显小于 MAX_PATH,文件夹名称和文件名称长度也正常。

去看 mciSendString() 的返回字符串太麻烦了,推理吧。

你看,MCI 是一个历史久远的东西,那么……历史久远!历史久远的东西,在这种情况下能造成影响的,很大的可能性是8.3文件名(短文件名)。

那也好办。Windows API,GetShortPathName(),不要重复发明轮子。

strShortFilename = String$(MAX_PATH, vbNullChar)
Call GetShortPathName(FileName, strShortFilename, MAX_PATH)
strShortFilename = Strip(strShortFilename)
strSend = "OPEN " & Chr$(34) & strShortFilename & Chr$(34) & " ALIAS " & STRING_SOUND_ALIAS & " TYPE MPEGVIDEO"
Call mciSendString(strSend, rbuf, 0, 0)

(注意,上面的代码还有一个小坑。如果不进行字符串“修剪”去掉冗余的 vbNullChar 的话,也是无法播放的。不过我觉得这没必要单独提出来,就放在这括号里了。)

去睡觉

至少刚刚用了几个sample去测试,都通过了。今早应该能醒来吧……设置闹钟然后睡觉吧。

这篇文章就当是备忘录好了……看官别抱太大希望……

最后补充说明,MCI 其实是调用相应的已注册的解码器来工作的,所以其实如果安装了相应的解码器,就能播放相应格式的音频文件。当然,raw PCM 和 waveform 肯定要用 native 的 API 直接解决对不对……如果微软那群人不这么想我也没办法……

分享到 评论