最近有很多人咨询我关于 windows phone 8 语音识别方面的用法,今天我就在这里给大家总结一下以便大家学习交流
在windows phone8中语音可以理解为三部分功能即: 语音控制 voice commands, 语音识别 speech recognition, 文字语音 text-to-speech (TTS)。
在写程序之前要先把你的WP8 声明成支持Voice command的APP
1. 语音控制 voice commands 对应 ID_CAP_SPEECH_RECOGNITION, ID_CAP_MICROPHONE, and ID_CAP_NETWORKING capabilities in the app manifest file
语音控制顾名思义可以使用语音命令来操作应用程程序,包括启动和页面跳转。
首先你要现在你的WP8项目中添加一个VCD文件,它的用途就是来声明你的WP8App 可以接受那些 语音命令并且会给用户那些语音反馈以及会执行那些动作。
例如: CommandPrefix 就是声明你的应用程序打开关键字 Command Name 声明你的应用可以识别执行那些动作 Navigate 可以将包含关键字的命令导航到特定页面。
当然你还要在你的系统中注册你的应用是一个支持语音控制的应用 这里MSDN推荐用一个单独的方法承载
- public async void InitCommand()
- {
- await VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri("ms-appx:///VoiceCommandDefinition1.xml"));
- }
- // Code to execute when the application is launching (eg, from Start)
- // This code will not execute when the application is reactivated
- private void Application_Launching(object sender, LaunchingEventArgs e)
- {
- InitCommand();
- }
既然你的应用可以支持语音的目标导航当然在我们的目标页面也是可以拿到用户的语音参数的,当然请放心这里我们的SDK已经帮我们吧语音翻译成文字了,相信大家处理文字还会很得心应手的.
你只重写一下你的目标页面的 onNavigatedTo事件
- protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- // Is this a new activation or a resurrection from tombstone?
- if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
- {
- // Was the app launched using a voice command?
- if (NavigationContext.QueryString.ContainsKey("voiceCommandName"))
- {
- // If so, get theon name of the voice command.
- string voiceCommandName
- = NavigationContext.QueryString["voiceCommandName"];
- // Define app actions for each voice command name.
- switch (voiceCommandName)
- {
- case "showWidgets":
- string viewWidget = NavigationContext.QueryString["widgetViews"];
- // Add code to display specified widgets.
- break;
- // Add cases for other voice commands.
- default:
- // There is no match for the voice command name.
- onbreak;
- }
- }
- }
- }
msdn参考: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206959(v=vs.105).aspx
2. 语音识别 speech recognition 对应 ID_CAP_SPEECH_RECOGNITION, ID_CAP_MICROPHONE, and ID_CAP_NETWORKING capabilities in the app manifest
语音识别分为两种
2.1 基于本地的语音识别
本地语音识别不需要访问网络 但是只能识别个别字对于功能性操作已经够了下面给大家一个例子
这里提到了 Exception from HRESULT: 0x800455BC
有不少朋友问我这个问题是怎么回事儿? 这里请注意我的 rengionizer 设置是 zh-cn, 因为操作系统大家习惯选择中文 然而默认rengionizer 是英文的 很多朋友都卡在这个问题上了 这里我特意提一下。
这段代码就可以再没有网络的情况下识别你说出的中文数字。
- recoWithUI = new SpeechRecognizerUI();
- SpeechRecognitionUIResult recoResult;
- try
- {
- // Query for a recognizer that recognizes French as spoken in France.
- IEnumerable
frenchRecognizers = from recognizerInfo in InstalledSpeechRecognizers.All - where recognizerInfo.Language == "zh-CN"
- select recognizerInfo;
- // Set the recognizer to the top entry in the query result.
- recoWithUI.Recognizer.SetRecognizer(frenchRecognizers.ElementAt(0));
- // Create a string array of China numbers.
- string[] nombres = { "一", "二", "三", "四", "五",
- "六", "七", "八", "九", "十" };
- // Create a list grammar from the string array and add it to the grammar set.
- recoWithUI.Recognizer.Grammars.AddGrammarFromList("ChinaNumbers", nombres);
- // Display text to prompt the user's input.
- recoWithUI.Settings.ListenText = "Say a china number";
- // Give an example of ideal speech input.
- recoWithUI.Settings.ExampleText = " '一', '二', '三', '四' ";
- // Load the grammar set and start recognition.
- recoResult = await recoWithUI.RecognizeWithUIAsync();
- }
- catch (Exception ex)
- {
- //Exception from HRESULT: 0x800455BC
- string ext = ex.Message;
- return;
- }
- // Do something with the recognition result.
- MessageBox.Show(string.Format("You said {0}.", recoResult.RecognitionResult.Text));
2.2 基于网络的语音识别
当然用户可以随便说点儿什么 windows phone 8 可以使用网络进行一个云识别 从实现上来说稍有不同 但也很简单我也写了一个demo给大家参考
这里我注释掉的code是另外一种没有UI的识别过程 请大家根据自己App需求来定吧,这里是初始化了一个基于网络的语音识别器 SpeechPredefinedGrammar.WebSearch
- // Constructor
- public MainPage()
- {
- InitializeComponent();
- //SpeechRecognizer myRecognizer = new SpeechRecognizer();
- //recoWithUI.Grammars.AddGrammarFromPredefinedType("citySearch", SpeechPredefinedGrammar.WebSearch);
- // Initialize the SpeechRecognizer and add the WebSearch grammar.
- recoWithUI = new SpeechRecognizerUI();
- recoWithUI.Recognizer.Grammars.AddGrammarFromPredefinedType("citySearch", SpeechPredefinedGrammar.WebSearch);
- // Prompt the user for a city name.
- displayText.Text = "What's your destination city?";
- // Subscribe to the AudioCaptureStateChanged event.
- recoWithUI.Recognizer.AudioCaptureStateChanged += myRecognizer_AudioCaptureStateChanged;
- }
由于需要访问网络 所以是一个异步的访问过程 所以注册了一个 myRecognizer_AudioCaptureStateChanged 的返回事件
- // Detect capture state changes and write the capture state to the text block.
- void myRecognizer_AudioCaptureStateChanged(SpeechRecognizer sender, SpeechRecognizerAudioCaptureStateChangedEventArgs args)
- {
- if (args.State == SpeechRecognizerAudioCaptureState.Capturing)
- {
- this.Dispatcher.BeginInvoke(delegate { displayText.Text = "Listening"; });
- }
- else if (args.State == SpeechRecognizerAudioCaptureState.Inactive)
- {
- this.Dispatcher.BeginInvoke(delegate { displayText.Text = "Thinking"; });
- }
- }
最后我通过一个按钮来激发这个语音识别的过程
- private async void Button_Click_1(object sender, RoutedEventArgs e)
- {
- // Start recognition.
- SpeechRecognitionUIResult recoResult = await recoWithUI.RecognizeWithUIAsync();
- // Do something with the recognition result.
- MessageBox.Show(string.Format("You said {0}.", recoResult.RecognitionResult.Text));
- //// Check to see if speech input was rejected and prompt the user.
- //if (recoResult.RecognitionResult.TextConfidence == SpeechRecognitionConfidence.Rejected)
- //{
- // displayText.Text = "Sorry, didn't catch that. \n\nSay again.";
- //}
- //// Check to see if speech input was recognized with low confidence and prompt the user to speak again.
- //else if (recoResult.RecognitionResult.TextConfidence == SpeechRecognitionConfidence.Low)
- //{
- // displayText.Text = "Not sure what you said. \n\nSay again.";
- //}
- //// Check to see if speech input was recognized and confirm the result.
- //else if (recoResult.RecognitionResult.TextConfidence == SpeechRecognitionConfidence.High ||
- // recoResult.RecognitionResult.TextConfidence == SpeechRecognitionConfidence.Medium)
- //{
- // displayText.Text = "Heard you say: \n\n" + recoResult.RecognitionResult.Text;
- //}
- }
MSDN 参考: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206963(v=vs.105).aspx
3. 文字语音 text-to-speech (TTS) 对应 ID_CAP_SPEECH_RECOGNITION capability in the app manifest
最后 TTS 大家很容易理解的 就是把文字转换成声音念出来很简单
- private async void ButtonSimpleTTS_Click(object sender, RoutedEventArgs e)
- {
- SpeechSynthesizer synth = new SpeechSynthesizer();
- await synth.SpeakTextAsync("You have a meeting with Peter in 15 minutes.");
- }
当然也同样支持语言的选择
- // Declare the SpeechSynthesizer object at the class level.
- SpeechSynthesizer synth;
- // Handle the button click event.
- private async void SpeakFrench_Click_1(object sender, RoutedEventArgs e)
- {
- // Initialize the SpeechSynthesizer object.
- synth = new SpeechSynthesizer();
- // Query for a voice that speaks French.
- IEnumerable
frenchVoices = from voice in InstalledVoices.All - where voice.Language == "fr-FR"
- select voice;
- // Set the voice as identified by the query.
- synth.SetVoice(frenchVoices.ElementAt(0));
- // Count in French.
- await synth.SpeakTextAsync("un, deux, trois, quatre");
- }
这里我就是直接粘贴的MSDN代码 真的很简单就不废话了
连接给出 : http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207057(v=vs.105).aspx
如果有什么问题或者建议请在新浪微博上 @王博_Nick