发送语音识别参数.结果作为UWP桌面桥程序包中的参数 [英] Send speech recognition args.Result as parameter in UWP desktop-bridge package

查看:144
本文介绍了发送语音识别参数.结果作为UWP桌面桥程序包中的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出是否可能将using Windows.Media.SpeechRecognition; args.Result.Text作为参数从 UWP 发送到 Console 应用程序.

I'm trying to figure out, if it is possible send using Windows.Media.SpeechRecognition; args.Result.Text as parameter from UWP to Console application.

例如,通过以下情形,我将发送带有args.Result.Text;值的TextToSpeech(args.Result.Text);,其中,每次出现args.Result.Text;时,using Windows.Media.SpeechSynthesis;文本语音转换都会发出识别结果. textBlock2.Text = args.Result.Text;还会显示结果:

For example by following scenario I'm sending TextToSpeech(args.Result.Text); with args.Result.Text; value, where using Windows.Media.SpeechSynthesis; text-to-speech pronounces the recognition result each time when args.Result.Text; appears. textBlock2.Text = args.Result.Text; also displays result:

 private async void ContinuousRecognitionSession_ResultGenerated(
            SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
        {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {               
                textBlock1.Text = args.Result.Text;    

                TextToSpeech(args.Result.Text);               
            });
        }

但是,如果我尝试将args.Result.Text;作为参数发送到控制台应用程序(包含在 Desktop-Bridge 软件包中的 UWP 中):

but if I'm trying to send args.Result.Text; as parameter to console application, included with UWP in Desktop-Bridge package:

    private async void ContinuousRecognitionSession_ResultGenerated(
        SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
    {
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {                            
          textBlock1.Text = args.Result.Text; 

          SendTTSResult(args.Result.Text);
        });
    }

到请求的功能:

 private async void SendTTSResult(string res)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
            }
        });
    }

失败的行为在我看来还不是很清楚:

Behavior of failure looks to me not really clear:

具有第一个识别结果,它将参数发送到控制台应用程序,控制台应用程序成功加载,获取并显示此参数.但是对于第二个请求,即使参数发送功能明确无误,问题也会从该处理级别退却.SendTTSResult(args.Result.Text);函数不会接收到args.Result.Text失败,但这已经在函数生效之前发生,因为先前的输出显示textBlock1.Text = args.Result.Text;也不再接收事件.

With first recognition result, it sends parameter to console application, which successfully loads, gets and displays this parameter. But with second request the problem backs away from this processing level, even if parameters sending function is unambiguously the cause of a failure SendTTSResult(args.Result.Text); function does not receives args.Result.Text but this happens already before function will comes in action, because preceding output display textBlock1.Text = args.Result.Text; also does not receives event anymore.

async() =>的行为有些不同,它成功接收事件并将值作为参数发送到控制台,在这种情况下,它从开始执行和发出语音请求开始就发生2-3次,然后事件消失(如果不是)甚至通过SendTTSResult(string res)传递,想像SendTTSResult(string res)中的内容不允许从识别中传递字符串,而是停止,即使我将其放在TextToSpeech(string text)函数的末尾,文本到语音也停止接收事件:

With async() => behavior is a bit different, it successfully receives event and sends value as parameter to console, in this case it happens 2-3 times from beginning of execution and voice requesting, then event disappears, when it is not even passed through SendTTSResult(string res), to imagine that the something in SendTTSResult(string res) does not allows pass string from recognition, but just stops, even if I put it in the end of TextToSpeech(string text) function, text to speech also stops receive event:

private async void SendTTSResult(string res)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
            {
                if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
                {
                    ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                    await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
                }
            });
        }

使用SendTTSResult(string res)函数作为参数发送args.Result.Text值似乎可以正常工作,可以成功发送字符串,但是同时ContinuousRecognitionSession_ResultGenerated中此函数的存在会以某种方式影响其内部事件的接收.同时,ContSpeechRecognizer_HypothesisGenerated的行为看起来完全不同,每次都会出现args.Hypothesis.Text事件,并且结果成功地传递为具有相同SendTTSResult(string res)的参数.

It looks like sending of args.Result.Text value as parameter with SendTTSResult(string res) function works fine, sends string successfully, but at the same time presence of this function in ContinuousRecognitionSession_ResultGenerated somehow affects receiving of event inside of it. At the same time behavior of ContSpeechRecognizer_HypothesisGenerated looks completely different, args.Hypothesis.Text event appears each time and result successfully passes as parameter with same SendTTSResult(string res).

在处理过程中涉及发送参数的功能时,什么可以阻止事件执行?如何解决该问题?

What can prevent an event from being executed when the function of sending a parameter is involved in its process, and how to fix it if possible?

在Windows Dev Center上我的问题中添加了连续语音识别的完整代码 **************************************** ****************************************************** ***********

EDIT 1: **************************************************************************************************

在参数功能后面,控制台Connector.exe仅显示参数,而没有运行任何应用程序或其他任何东西:

Behind parameter function, Console Connector.exe only shows parameter without running of any app or anything else:

static void Main(string[] args)
        {
            string result = Assembly.GetExecutingAssembly().Location;
            int index = result.LastIndexOf("\\");
            string rootPath = $"{result.Substring(0, index)}\\..\\";
            if (args.Length > 2)
            {
                switch (args[2])
                {
                    case "/parameters":
                        string parameters = ApplicationData.Current.LocalSettings.Values["parameters"] as string;
                        Console.WriteLine("Parameter: " + parameters);
                        Console.ReadLine();
                        break;
                }
            }
        }

Packeage.appxmanifest:

Packeage.appxmanifest:

<uap:Extension Category="windows.appService">
  <uap:AppService Name="SampleInteropService" />
</uap:Extension>

<desktop:Extension Category="windows.fullTrustProcess" Executable="Connector\Connector.exe">
  <desktop:FullTrustProcess>
    <desktop:ParameterGroup GroupId="Parameters" Parameters="/parameters" />
  </desktop:FullTrustProcess>
</desktop:Extension>

****************************************** ****************************************************** ***********

EDIT 2: **************************************************************************************************

我尝试过SendTTSResult(SpeechRecogVal);更改变量值:

 private async void ContinuousRecognitionSession_ResultGenerated(
        SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
    {
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {               
            SpeechRecogVal = args.Result.Text;
        });
    }

但它是相同的行为tbRec.Text = SpeechRecogVal;成功显示输出,直到我添加SendTTSResult(SpeechRecogVal);

but it is same behavior tbRec.Text = SpeechRecogVal; shows output successfully until I add SendTTSResult(SpeechRecogVal);,

   private string _srVal;

    public string SpeechRecogVal
    {
        get
        {
            return _srVal;
        }

        set
        {
            _srVal = value;
            ValueChanged();
        }
    }

    void ValueChanged()
    {
        tbRec.Text = SpeechRecogVal;
        // SendTTSResult(SpeechRecogVal);
    }

因此,似乎问题出在await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>private async voidContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)(ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>之间

So, seems like problem is something between await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => and if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0)) and await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => of private async voidContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)

我也尝试过:

private async void ContinuousRecognitionSession_ResultGenerated(
    SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
       await  SendTTSResult(args.Result.Text);        
}

作为任务:

async Task SendTTSResult(string res)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
            }
        });
    }

它也只有在第一次请求事件实例响应时才成功,然后进行得相当顺利.因此,似乎ContinuousRecognitionSession_ResultGenerated Windows中的其他选项有所不同.Media.SpeechRecognition命名空间,并且与async Task SendTTSResult(string res)中的内容或以下代码行内容不兼容:

And it is also successful only with first request event instance response, then goes quite. So seems like ContinuousRecognitionSession_ResultGenerated is someway different from other options in Windows.Media.SpeechRecognition Namespace and not compatible with something in async Task SendTTSResult(string res) or rather with this code lines content:

 ApplicationData.Current.LocalSettings.Values["parameters"] = args.Result.Text;
 await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");

推荐答案

System.NullReferenceException发生appservice断开连接的情况,您能否在发送消息之前检查apservice的连接?

System.NullReferenceException occurs appservice disconnect scenario, Could you check the apservice's connection before send message?

为对此进行解释,我创建了引用 Stefanwick 的示例项目.

For explain this, I create sample project that refer Stefanwick blog. And I also reproduce your issue when I does not invoke InitializeAppServiceConnection method in WPF client. If you want to send text to wpf, you could invoke Connection.SendMessageAsync method just like below SendMesssage click envent .

功能

      <Extensions>
        <uap:Extension Category="windows.appService">
          <uap:AppService Name="SampleInteropService" />
        </uap:Extension>
        <desktop:Extension Category="windows.fullTrustProcess" Executable="AlertWindow\AlertWindow.exe" />
      </Extensions>
    </Application>
  </Applications>
  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>

WPF

private AppServiceConnection connection = null;
public MainWindow()
{
    InitializeComponent();
    InitializeAppServiceConnection();
}
private async void InitializeAppServiceConnection()
{
    connection = new AppServiceConnection();
    connection.AppServiceName = "SampleInteropService";
    connection.PackageFamilyName = Package.Current.Id.FamilyName;
    connection.RequestReceived += Connection_RequestReceived;
    connection.ServiceClosed += Connection_ServiceClosed;

    AppServiceConnectionStatus status = await connection.OpenAsync();
    if (status != AppServiceConnectionStatus.Success)
    {
        MessageBox.Show(status.ToString());
        this.IsEnabled = false;
    }
}

private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
    {
        Application.Current.Shutdown();
    }));
}

private async void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
    // retrive the reg key name from the ValueSet in the request
    string key = args.Request.Message["KEY"] as string;

    if (key.Length > 0)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
        {
            InfoBlock.Text = key;

        }));
        ValueSet response = new ValueSet();
        response.Add("OK", "SEND SUCCESS");
        await args.Request.SendResponseAsync(response);
    }
    else
    {
        ValueSet response = new ValueSet();
        response.Add("ERROR", "INVALID REQUEST");
        await args.Request.SendResponseAsync(response);
    }
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
    ValueSet response = new ValueSet();
    response.Add("OK", "AlerWindow Message");
    await connection.SendMessageAsync(response);
}

UWP

 protected async override void OnNavigatedTo(NavigationEventArgs e)
 {
     base.OnNavigatedTo(e);

     if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
     {
         App.AppServiceConnected += MainPage_AppServiceConnected;
         App.AppServiceDisconnected += MainPage_AppServiceDisconnected;
         await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
     }
 }

 private async void MainPage_AppServiceDisconnected(object sender, EventArgs e)
 {
     await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
     {
         Reconnect();
     });
 }



private void MainPage_AppServiceConnected(object sender, AppServiceTriggerDetails e)
 {
     App.Connection.RequestReceived += AppServiceConnection_RequestReceived;

 }
 private async void AppServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
 {
     string value = args.Request.Message["OK"] as string;
     await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
      {
          InfoBlock.Text = value;
      });


 }     
 private async void Reconnect()
 {
     if (App.IsForeground)
     {
         MessageDialog dlg = new MessageDialog("Connection to desktop process lost. Reconnect?");
         UICommand yesCommand = new UICommand("Yes", async (r) =>
         {
             await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
         });
         dlg.Commands.Add(yesCommand);
         UICommand noCommand = new UICommand("No", (r) => { });
         dlg.Commands.Add(noCommand);
         await dlg.ShowAsync();
     }
 }
 private int count = 0;
 private async void SendMesssage(object sender, RoutedEventArgs e)
 {
     count++;
     ValueSet request = new ValueSet();
     request.Add("KEY", $"Test{count}");
     AppServiceResponse response = await App.Connection.SendMessageAsync(request);

     // display the response key/value pairs

     foreach (string value in response.Message.Values)
     {
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
         {
             StatusBlock.Text = value;
         });

     }
 }

这是完整的代码示例.

这篇关于发送语音识别参数.结果作为UWP桌面桥程序包中的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆