You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms应用使用Speech-To-Text后TTS播放音量过低问题

问题描述

免责声明:我是C#和Xamarin.Forms的新手,如有明显疏漏请见谅。

我正在开发一款应用,功能是通过语音转文本(Speech-To-Text)接收用户语音命令输入,再通过文本转语音(Text-To-Speech)输出应用的语音播报内容。

目前遇到的问题是:启动语音转文本服务的音频录制后,设备音频会进入录音模式(我不确定对应的专业术语名称),后续播放音频的音量会变得非常低。

我希望找到方法解决该问题:在Xamarin Forms应用中,通过语音转文本识别到对应语音命令(即“Secret command”)后,用户可以听到文本转语音以全量/正常音量播报对应的秘密提示语。

我改编了Azure Cognitive Speech Service的示例代码复现问题,克隆代码后略微修改了MainPage的Xaml和CS代码,如下所示,逻辑是触发指定语音命令后停止语音识别服务,再调用文本转语音服务播报指定语句。我的示例可以复现该问题:用户点击“Transcribe”按钮后输入对应语音命令,应该能听到返回的秘密提示语,但在iOS真机测试时播放音量极低,几乎听不到。

XAML代码

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="CognitiveSpeechService.MyPage"
             Title="Speech Services Transcription"
             Padding="10,35,10,10">

    <StackLayout>
        <Frame BorderColor="DarkGray"
               CornerRadius="10"
               HeightRequest="300"
               WidthRequest="280"
               HorizontalOptions="Center"
               VerticalOptions="Start"
               BackgroundColor="LightGray">
            <ScrollView x:Name="scroll">
                <Label x:Name="transcribedText"
                       Margin="10,10,10,10" />
            </ScrollView>
        </Frame>

        <ActivityIndicator x:Name="transcribingIndicator"
                           HorizontalOptions="Center"
                           VerticalOptions="Start"
                           WidthRequest="300"
                           IsRunning="False" />
        <Button x:Name="transcribeButton"
                WidthRequest="300"
                HeightRequest="50"
                Text="Transcribe"
                TextColor="White"
                CornerRadius="10"
                BackgroundColor="Green"
                BorderColor="DarkGray"
                BorderWidth="1"
                FontAttributes="Bold"
                HorizontalOptions="Center"
                VerticalOptions="Start"
                Clicked="TranscribeClicked"/>

        <Button x:Name="SpeakBtn"
                WidthRequest="300"
                HeightRequest="50"
                Text="Speak"
                TextColor="White"
                CornerRadius="10"
                BackgroundColor="Red"
                BorderColor="DarkGray"
                BorderWidth="1"
                FontAttributes="Bold"
                HorizontalOptions="Center"
                VerticalOptions="Start"
                Clicked="SpeakBtn_Clicked"/>

    </StackLayout>

</ContentPage>

后台代码(Code-behind)

namespace CognitiveSpeechService
{
    public partial class MyPage : ContentPage
    {

        AudioRecorderService recorder = new AudioRecorderService();

        SpeechRecognizer recognizer;
        IMicrophoneService micService;
        bool isTranscribing = false;

        public MyPage()
        {
            InitializeComponent();

            micService = DependencyService.Resolve<IMicrophoneService>();
        }

        async void TranscribeClicked(object sender, EventArgs e)
        {
            bool isMicEnabled = await micService.GetPermissionAsync();

            // 提前退出:确保麦克风权限可用
            if (!isMicEnabled)
            {
                UpdateTranscription("Please grant access to the microphone!");
                return;
            }

            // 初始化语音识别器
            if (recognizer == null)
            {
                var config = SpeechConfig.FromSubscription(Constants.CognitiveServicesApiKey, Constants.CognitiveServicesRegion);
                recognizer = new SpeechRecognizer(config);
                recognizer.Recognized += (obj, args) =>
                {
                    UpdateTranscription(args.Result.Text);
                };
            }

            // 如果正在识别中,停止语音识别服务
            if (isTranscribing)
            {
                StopSpeechRecognition();
            }

            // 如果未在识别中,启动语音识别服务
            else
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    InsertDateTimeRecord();
                });
                try
                {
                    await recognizer.StartContinuousRecognitionAsync();
                }
                catch (Exception ex)
                {
                    UpdateTranscription(ex.Message);
                }
                isTranscribing = true;
            }
            UpdateDisplayState();
        }

        private async void StopSpeechRecognition()
        {
            if (recognizer != null)
            {
                try
                {
                    await recognizer.StopContinuousRecognitionAsync();
                    Console.WriteLine($"IsRecording: {recorder.IsRecording}");
                }
                catch (Exception ex)
                {
                    UpdateTranscription(ex.Message);
                }
                isTranscribing = false;
                UpdateDisplayState();
            }
        }

        void UpdateTranscription(string newText)
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                if (!string.IsNullOrWhiteSpace(newText))
                {

                    if (newText.ToLower().Contains("Secret command"))
                    {
                        Console.WriteLine("heart rate voice command detected");

                        // 停止语音识别
                        StopSpeechRecognition();

                        // 执行播报
                        string success = "this works!";

                        var settings = new SpeechOptions()
                        {
                            Volume = 1.0f,
                        };

                        TextToSpeech.SpeakAsync(success, settings);

                        // 后续重新启动语音识别


                    } else
                    {
                        transcribedText.Text += $"{newText}\n";
                    }
                }
            });
        }

        void InsertDateTimeRecord()
        {
            var msg = $"=================\n{DateTime.Now.ToString()}\n=================";
            UpdateTranscription(msg);
        }

        void UpdateDisplayState()
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                if (isTranscribing)
                {
                    transcribeButton.Text = "Stop";
                    transcribeButton.BackgroundColor = Color.Red;
                    transcribingIndicator.IsRunning = true;
                }
                else
                {
                    transcribeButton.Text = "Transcribe";
                    transcribeButton.BackgroundColor = Color.Green;
                    transcribingIndicator.IsRunning = false;
                }
            });
        }

        async void SpeakBtn_Clicked(object sender, EventArgs e)
        {
            await TextToSpeech.SpeakAsync("Sample audio line. Blah blah blah. ");
        }
    }
}

感谢您的帮助!


内容的提问来源于stack exchange,提问作者ProgrammerInPractice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 06:54:02