在 SAPI 文本转语音之前先播放 MediaPlayer 声音 VB.Net
Play MediaPlayer sound first before SAPI text to speech VB.Net
我们使用 Vb.net 2015 和 SQL SERVER 2012 创建了一个排队系统
我们想编程先播放叮咚声(以通知等待队列),然后是文本到语音以读取号码和计数器服务。
然而,输出变得相反。它先播放文本到语音 [SAPI],然后再播放叮咚声。我还注意到,当 SAPI 是 "reading" 文本时,阅读它时时间会冻结。
这是我的代码:
'play ding dong sound
Dim fileLoc As String = Application.StartupPath & "\" & "ding dong queue.mp3" '"Reminder.wav" '
Me.AxWindowsMediaPlayer1.URL = fileLoc
If (Me.AxWindowsMediaPlayer1.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
'playStateLabel.Text = "Windows Media Player is playing!"
Else
Dim tempString As String = ""
For Each element As Char In lblTicketNoShow.Text 'seperate each number for tts ex. "1 0 0 1"
tempString = tempString & element & vbTab
Next
Dim tts = CreateObject("SAPI.spvoice")
tts.rate = -4
tts.volume = 100
tts.speak("NOW SERVING " & tempString & " on Counter " & lblCounterNo.Text)
End If
我的代码有什么问题。我错过了什么吗?
顺便说一句,你不是在等叮咚声播放完。
正如所写,您在媒体播放器对象上设置 URL,然后 立即 告诉 SAPI 说话。这是一个竞争条件,显然 SAPI 的速度要快一些,从而导致您看到的行为。
您需要 AxWindowsMediaPlayer1
上的 PlayStateChange
事件处理程序;当您从 PlayStateChange
处理程序获得 MediaEnded
事件时,您可以告诉 SAPI 读取下一个事件。 (您可能还需要一个 SAPI 事件处理程序来告知 SAPI 何时完成。)
感谢 Eric Brown 我更新了我的代码:
我将事件处理程序添加到我的 AxWindowsPlayer1。这样系统就可以在使用SAPI读取文本之前先判断叮咚声是否结束。
Public Sub player_PlayStateChange(ByVal sender As Object, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) Handles AxWindowsMediaPlayer1.PlayStateChange
' Test the current state of the player, display a message for each state.
Select Case e.newState
Case 0 ' Undefined
'currentStateLabel.Text = "Undefined"
Case 1 ' Stopped
' currentStateLabel.Text = "Stopped"
Case 2 ' Paused
' currentStateLabel.Text = "Paused"
Case 3 ' Playing
' currentStateLabel.Text = "Playing"
Case 4 ' ScanForward
' currentStateLabel.Text = "ScanForward"
Case 5 ' ScanReverse
' currentStateLabel.Text = "ScanReverse"
Case 6 ' Buffering
'currentStateLabel.Text = "Buffering"
Case 7 ' Waiting
' currentStateLabel.Text = "Waiting"
Case 8 ' MediaEnded
'currentStateLabel.Text = "MediaEnded"
Dim tempString As String = ""
For Each element As Char In lblTicketNoShow.Text 'seperate each number for tts ex. "1 0 0 1"
tempString = tempString & element & vbTab
Next
Dim tts = CreateObject("SAPI.spvoice")
tts.rate = -4
tts.volume = 100
tts.speak("NOW SERVING " & tempString & " on Counter " & lblCounterNo.Text)
Dim controls As WMPLib.IWMPControls3 = Me.AxWindowsMediaPlayer2.Ctlcontrols
' Check first to be sure the operation is valid.
If (controls.isAvailable("play")) Then
controls.play()
End If
Case 9 ' Transitioning
' currentStateLabel.Text = "Transitioning"
Case 10 ' Ready
'currentStateLabel.Text = "Ready"
Case 11 ' Reconnecting
'currentStateLabel.Text = "Reconnecting"
Case 12 ' Last
'currentStateLabel.Text = "Last"
Case Else
'currentStateLabel.Text = ("Unknown State: " + e.newState.ToString())
End Select
End Sub
我们使用 Vb.net 2015 和 SQL SERVER 2012 创建了一个排队系统
我们想编程先播放叮咚声(以通知等待队列),然后是文本到语音以读取号码和计数器服务。 然而,输出变得相反。它先播放文本到语音 [SAPI],然后再播放叮咚声。我还注意到,当 SAPI 是 "reading" 文本时,阅读它时时间会冻结。
这是我的代码:
'play ding dong sound
Dim fileLoc As String = Application.StartupPath & "\" & "ding dong queue.mp3" '"Reminder.wav" '
Me.AxWindowsMediaPlayer1.URL = fileLoc
If (Me.AxWindowsMediaPlayer1.playState = WMPLib.WMPPlayState.wmppsPlaying) Then
'playStateLabel.Text = "Windows Media Player is playing!"
Else
Dim tempString As String = ""
For Each element As Char In lblTicketNoShow.Text 'seperate each number for tts ex. "1 0 0 1"
tempString = tempString & element & vbTab
Next
Dim tts = CreateObject("SAPI.spvoice")
tts.rate = -4
tts.volume = 100
tts.speak("NOW SERVING " & tempString & " on Counter " & lblCounterNo.Text)
End If
我的代码有什么问题。我错过了什么吗?
顺便说一句,你不是在等叮咚声播放完。
正如所写,您在媒体播放器对象上设置 URL,然后 立即 告诉 SAPI 说话。这是一个竞争条件,显然 SAPI 的速度要快一些,从而导致您看到的行为。
您需要 AxWindowsMediaPlayer1
上的 PlayStateChange
事件处理程序;当您从 PlayStateChange
处理程序获得 MediaEnded
事件时,您可以告诉 SAPI 读取下一个事件。 (您可能还需要一个 SAPI 事件处理程序来告知 SAPI 何时完成。)
感谢 Eric Brown 我更新了我的代码:
我将事件处理程序添加到我的 AxWindowsPlayer1。这样系统就可以在使用SAPI读取文本之前先判断叮咚声是否结束。
Public Sub player_PlayStateChange(ByVal sender As Object, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) Handles AxWindowsMediaPlayer1.PlayStateChange
' Test the current state of the player, display a message for each state.
Select Case e.newState
Case 0 ' Undefined
'currentStateLabel.Text = "Undefined"
Case 1 ' Stopped
' currentStateLabel.Text = "Stopped"
Case 2 ' Paused
' currentStateLabel.Text = "Paused"
Case 3 ' Playing
' currentStateLabel.Text = "Playing"
Case 4 ' ScanForward
' currentStateLabel.Text = "ScanForward"
Case 5 ' ScanReverse
' currentStateLabel.Text = "ScanReverse"
Case 6 ' Buffering
'currentStateLabel.Text = "Buffering"
Case 7 ' Waiting
' currentStateLabel.Text = "Waiting"
Case 8 ' MediaEnded
'currentStateLabel.Text = "MediaEnded"
Dim tempString As String = ""
For Each element As Char In lblTicketNoShow.Text 'seperate each number for tts ex. "1 0 0 1"
tempString = tempString & element & vbTab
Next
Dim tts = CreateObject("SAPI.spvoice")
tts.rate = -4
tts.volume = 100
tts.speak("NOW SERVING " & tempString & " on Counter " & lblCounterNo.Text)
Dim controls As WMPLib.IWMPControls3 = Me.AxWindowsMediaPlayer2.Ctlcontrols
' Check first to be sure the operation is valid.
If (controls.isAvailable("play")) Then
controls.play()
End If
Case 9 ' Transitioning
' currentStateLabel.Text = "Transitioning"
Case 10 ' Ready
'currentStateLabel.Text = "Ready"
Case 11 ' Reconnecting
'currentStateLabel.Text = "Reconnecting"
Case 12 ' Last
'currentStateLabel.Text = "Last"
Case Else
'currentStateLabel.Text = ("Unknown State: " + e.newState.ToString())
End Select
End Sub