天天看點

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 直接解決對不對……如果微軟那群人不這麼想我也沒辦法……