SAPI.SpVoic微軟的這個組件非常強大,但是網上中文資料十分少,遇到的問題只能靠自己摸索,一個個坑自己填。
比如我就遇到語音播放異步的問題,正常都是播放完了才能繼續下面的代碼,而這個卻不行,網上搜索到的代碼是speak方法後面加個1就可以,但是我使用了就是不行,後來調查發現是沒有聲明變量導致的。
CreateObject("SAPI.SpVoice").speak "你好",1 '錯誤的異步使用方式
這樣是不可以的,直接沒聲音了。原理很簡單,這個是臨時創建的,如果是異步的話運行下一行代碼這個就結束了,創建的臨時變量隨即釋放,當然聲音也沒了。必須要修改爲下面的:
Dim objSpeech As Object
objSpeech.speak "你好", 1
也就是必須要聲明,執行下一行代碼後這個變量還是存在的。
不過這裏有另外一個問題,也就是停止播放的問題,爲什麼需要停止播放呢?因爲有的時候我們在當前播放一句話的時候需要改播放新的信息,然而由於之前的沒播放完,那麼程序只能等待之前的播放完纔行,這樣就造成了系統有點卡,而且體驗很不好。我之前做的辦法是將對象釋放,一釋放世界就立馬安靜了。
'停止當前播放,不推薦
If objSpeech.Status.runningState = 2 Then '如果當前正在播放,那麼就銷燬之前的對象然後重建
Set objSpeech = Nothing
Set objSpeech = CreateObject("SAPI.SpVoice")
End If
釋放後立馬再創建,這樣保證下面的代碼能正常調用。
可是後來在網上看到一個帖子,他不是這樣乾的,而是用的下面代碼:
'停止當前播放,推薦
If objSpeech.Status.runningState = 2 Then '如果當前正在播放,那麼就播放一個空字符串,並且使用掛斷之前的模式
objSpeech.Speak "", 2
End If
確實也可以達到效果,再看看我之前的方法,比他這方法差多了,我那方法消耗系統資源比較大,甚至在對象創建與銷燬的時候我覺得軟件有那麼一點點的小卡頓一下。所以推薦大家用上面的代碼。
關於vb調用發聲代碼,我寫了個方便調用的函數:
Public objSpeech As Object
'發聲函數 sysdzw整理
Public Sub playContent(ByVal str1$)
If objSpeech.Status.runningState = 2 Then '如果當前正在播放,那麼就播放一個空字符串,並且使用掛斷之前的模式
objSpeech.Speak "", 2
End If
objSpeech.Speak str1, 1
End Sub
附上一張spvoice的類成員圖:
可以看到SAPI還有很多其他的類,而一個spvoice就夠我們研究的了,真是太強大了。雖然中文文檔不全,但是好在微軟的變量命名十分規範,根據名字基本就能猜出意思,上面那個判斷是否是播放狀態我就是根據變量名猜想加驗證實現的。
再看下speak的第二個參數的情況,它是一個枚舉類型,有很多值。我們可以看到上面代碼中第二參數的1和2分別是什麼意思,根據變量名幾乎是一目瞭然,學計算機還是需要一點英文基礎的呀。
Const SVSFlagsAsync = 1 '異步
Const SVSFPurgeBeforeSpeak = 2 '掛起之前播放