Udostępnij za pośrednictwem


Szybki start: tworzenie niestandardowego asystenta głosowego

W tym przewodniku Szybki start utworzysz niestandardową aplikację asystenta głosowego, która łączy się z botem, który został już utworzony i skonfigurowany za pomocą zestawu SDK usługi Mowa. Jeśli musisz utworzyć bota, zapoznaj się z powiązanym samouczkiem , aby zapoznać się z bardziej kompleksowym przewodnikiem.

Po spełnieniu kilku wymagań wstępnych połączenie niestandardowego asystenta głosowego wykonuje tylko kilka kroków:

  • Utwórz BotFrameworkConfig obiekt na podstawie klucza subskrypcji i regionu.
  • DialogServiceConnector Utwórz obiekt przy użyciu obiektu z powyższegoBotFrameworkConfig.
  • DialogServiceConnector Za pomocą obiektu uruchom proces nasłuchiwania pojedynczej wypowiedzi.
  • Sprawdź zwrócone ActivityReceivedEventArgs dane.

Uwaga

Zestaw SPEECH SDK dla języków C++, JavaScript, Objective-C, Python i Swift obsługuje niestandardowe asystenty głosowe, ale nie dołączyliśmy jeszcze tutaj przewodnika.

Wszystkie przykłady języka C# zestawu SPEECH SDK można wyświetlić lub pobrać w witrynie GitHub.

Wymagania wstępne

Przed rozpoczęciem upewnij się, że:

Uwaga

Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

Otwieranie projektu w programie Visual Studio

Pierwszym krokiem jest upewnienie się, że projekt jest otwarty w programie Visual Studio.

Zacznij od kodu kociołowego

Dodajmy kod, który działa jako szkielet naszego projektu.

  1. W Eksplorator rozwiązań otwórz plik MainPage.xaml.

  2. W widoku XAML projektanta zastąp całą zawartość następującym fragmentem kodu, który definiuje podstawowe interfejs użytkownika:

    <Page
        x:Class="helloworld.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:helloworld"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    
        <Grid>
            <StackPanel Orientation="Vertical" HorizontalAlignment="Center"  
                        Margin="20,50,0,0" VerticalAlignment="Center" Width="800">
                <Button x:Name="EnableMicrophoneButton" Content="Enable Microphone"  
                        Margin="0,0,10,0" Click="EnableMicrophone_ButtonClicked" 
                        Height="35"/>
                <Button x:Name="ListenButton" Content="Talk to your bot" 
                        Margin="0,10,10,0" Click="ListenButton_ButtonClicked" 
                        Height="35"/>
                <StackPanel x:Name="StatusPanel" Orientation="Vertical" 
                            RelativePanel.AlignBottomWithPanel="True" 
                            RelativePanel.AlignRightWithPanel="True" 
                            RelativePanel.AlignLeftWithPanel="True">
                    <TextBlock x:Name="StatusLabel" Margin="0,10,10,0" 
                               TextWrapping="Wrap" Text="Status:" FontSize="20"/>
                    <Border x:Name="StatusBorder" Margin="0,0,0,0">
                        <ScrollViewer VerticalScrollMode="Auto"  
                                      VerticalScrollBarVisibility="Auto" MaxHeight="200">
                            <!-- Use LiveSetting to enable screen readers to announce 
                                 the status update. -->
                            <TextBlock 
                                x:Name="StatusBlock" FontWeight="Bold" 
                                AutomationProperties.LiveSetting="Assertive"
                                MaxWidth="{Binding ElementName=Splitter, Path=ActualWidth}" 
                                Margin="10,10,10,20" TextWrapping="Wrap"  />
                        </ScrollViewer>
                    </Border>
                </StackPanel>
            </StackPanel>
            <MediaElement x:Name="mediaElement"/>
        </Grid>
    </Page>
    

Widok Projekt jest aktualizowany w celu wyświetlenia interfejsu użytkownika aplikacji.

  1. W Eksplorator rozwiązań otwórz plik MainPage.xaml.csźródłowy za kodem . (Jest ona pogrupowana w obszarze MainPage.xaml.) Zastąp zawartość tego pliku poniższym ciągiem, który obejmuje:
  • usinginstrukcje dla Speech przestrzeni nazw i Speech.Dialog

  • Prosta implementacja zapewniająca dostęp do mikrofonu, przewodową do procedury obsługi przycisków

  • Podstawowe pomocniki interfejsu użytkownika do prezentowania komunikatów i błędów w aplikacji

  • Punkt docelowy ścieżki kodu inicjowania, która zostanie wypełniona później

  • Pomocnik do odtwarzania tekstu na mowę (bez obsługi przesyłania strumieniowego)

  • Pusta procedura obsługi przycisków w celu rozpoczęcia nasłuchiwania, które zostaną wypełnione później

    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Dialog;
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using Windows.Foundation;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;
    
    namespace helloworld
    {
        public sealed partial class MainPage : Page
        {
            private DialogServiceConnector connector;
    
            private enum NotifyType
            {
                StatusMessage,
                ErrorMessage
            };
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void EnableMicrophone_ButtonClicked(
                object sender, RoutedEventArgs e)
            {
                bool isMicAvailable = true;
                try
                {
                    var mediaCapture = new Windows.Media.Capture.MediaCapture();
                    var settings = 
                        new Windows.Media.Capture.MediaCaptureInitializationSettings();
                    settings.StreamingCaptureMode = 
                        Windows.Media.Capture.StreamingCaptureMode.Audio;
                    await mediaCapture.InitializeAsync(settings);
                }
                catch (Exception)
                {
                    isMicAvailable = false;
                }
                if (!isMicAvailable)
                {
                    await Windows.System.Launcher.LaunchUriAsync(
                        new Uri("ms-settings:privacy-microphone"));
                }
                else
                {
                    NotifyUser("Microphone was enabled", NotifyType.StatusMessage);
                }
            }
    
            private void NotifyUser(
                string strMessage, NotifyType type = NotifyType.StatusMessage)
            {
                // If called from the UI thread, then update immediately.
                // Otherwise, schedule a task on the UI thread to perform the update.
                if (Dispatcher.HasThreadAccess)
                {
                    UpdateStatus(strMessage, type);
                }
                else
                {
                    var task = Dispatcher.RunAsync(
                        Windows.UI.Core.CoreDispatcherPriority.Normal, 
                        () => UpdateStatus(strMessage, type));
                }
            }
    
            private void UpdateStatus(string strMessage, NotifyType type)
            {
                switch (type)
                {
                    case NotifyType.StatusMessage:
                        StatusBorder.Background = new SolidColorBrush(
                            Windows.UI.Colors.Green);
                        break;
                    case NotifyType.ErrorMessage:
                        StatusBorder.Background = new SolidColorBrush(
                            Windows.UI.Colors.Red);
                        break;
                }
                StatusBlock.Text += string.IsNullOrEmpty(StatusBlock.Text) 
                    ? strMessage : "\n" + strMessage;
    
                if (!string.IsNullOrEmpty(StatusBlock.Text))
                {
                    StatusBorder.Visibility = Visibility.Visible;
                    StatusPanel.Visibility = Visibility.Visible;
                }
                else
                {
                    StatusBorder.Visibility = Visibility.Collapsed;
                    StatusPanel.Visibility = Visibility.Collapsed;
                }
                // Raise an event if necessary to enable a screen reader 
                // to announce the status update.
                var peer = Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer.FromElement(StatusBlock);
                if (peer != null)
                {
                    peer.RaiseAutomationEvent(
                        Windows.UI.Xaml.Automation.Peers.AutomationEvents.LiveRegionChanged);
                }
            }
    
            // Waits for and accumulates all audio associated with a given 
            // PullAudioOutputStream and then plays it to the MediaElement. Long spoken 
            // audio will create extra latency and a streaming playback solution 
            // (that plays audio while it continues to be received) should be used -- 
            // see the samples for examples of this.
            private void SynchronouslyPlayActivityAudio(
                PullAudioOutputStream activityAudio)
            {
                var playbackStreamWithHeader = new MemoryStream();
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4); // ChunkID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(UInt32.MaxValue), 0, 4); // ChunkSize: max
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4); // Format
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4); // Subchunk1ID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16), 0, 4); // Subchunk1Size: PCM
                playbackStreamWithHeader.Write(BitConverter.GetBytes(1), 0, 2); // AudioFormat: PCM
                playbackStreamWithHeader.Write(BitConverter.GetBytes(1), 0, 2); // NumChannels: mono
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16000), 0, 4); // SampleRate: 16kHz
                playbackStreamWithHeader.Write(BitConverter.GetBytes(32000), 0, 4); // ByteRate
                playbackStreamWithHeader.Write(BitConverter.GetBytes(2), 0, 2); // BlockAlign
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16), 0, 2); // BitsPerSample: 16-bit
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("data"), 0, 4); // Subchunk2ID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(UInt32.MaxValue), 0, 4); // Subchunk2Size
    
                byte[] pullBuffer = new byte[2056];
    
                uint lastRead = 0;
                do
                {
                    lastRead = activityAudio.Read(pullBuffer);
                    playbackStreamWithHeader.Write(pullBuffer, 0, (int)lastRead);
                }
                while (lastRead == pullBuffer.Length);
    
                var task = Dispatcher.RunAsync(
                    Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.SetSource(
                        playbackStreamWithHeader.AsRandomAccessStream(), "audio/wav");
                    mediaElement.Play();
                });
            }
    
            private void InitializeDialogServiceConnector()
            {
                // New code will go here
            }
    
            private async void ListenButton_ButtonClicked(
                object sender, RoutedEventArgs e)
            {
                // New code will go here
            }
        }
    }
    
  1. Dodaj następujący fragment kodu do treści InitializeDialogServiceConnectormetody . Ten kod tworzy element DialogServiceConnector z informacjami o subskrypcji.

    // Create a BotFrameworkConfig by providing a Speech service subscription key
    // the botConfig.Language property is optional (default en-US)
    const string speechSubscriptionKey = "YourSpeechSubscriptionKey"; // Your subscription key
    const string region = "YourServiceRegion"; // Your subscription service region.
    
    var botConfig = BotFrameworkConfig.FromSubscription(speechSubscriptionKey, region);
    botConfig.Language = "en-US";
    connector = new DialogServiceConnector(botConfig);
    

    Uwaga

    Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

    Uwaga

    Aby uzyskać informacje na temat konfigurowania bota, zobacz dokumentację platformy Bot Framework dotyczącą kanału mowy direct line.

  2. Zastąp ciągi YourSpeechSubscriptionKey i YourServiceRegion własnymi wartościami dla subskrypcji i regionu mowy.

  3. Dołącz poniższy fragment kodu na końcu treści InitializeDialogServiceConnectormetody . Ten kod konfiguruje programy obsługi zdarzeń, na DialogServiceConnector których polegają informacje o działaniach bota, wynikach rozpoznawania mowy i innych informacjach.

    // ActivityReceived is the main way your bot will communicate with the client 
    // and uses bot framework activities
    connector.ActivityReceived += (sender, activityReceivedEventArgs) =>
    {
        NotifyUser(
            $"Activity received, hasAudio={activityReceivedEventArgs.HasAudio} activity={activityReceivedEventArgs.Activity}");
    
        if (activityReceivedEventArgs.HasAudio)
        {
            SynchronouslyPlayActivityAudio(activityReceivedEventArgs.Audio);
        }
    };
    
    // Canceled will be signaled when a turn is aborted or experiences an error condition
    connector.Canceled += (sender, canceledEventArgs) =>
    {
        NotifyUser($"Canceled, reason={canceledEventArgs.Reason}");
        if (canceledEventArgs.Reason == CancellationReason.Error)
        {
            NotifyUser(
                $"Error: code={canceledEventArgs.ErrorCode}, details={canceledEventArgs.ErrorDetails}");
        }
    };
    
    // Recognizing (not 'Recognized') will provide the intermediate recognized text 
    // while an audio stream is being processed
    connector.Recognizing += (sender, recognitionEventArgs) =>
    {
        NotifyUser($"Recognizing! in-progress text={recognitionEventArgs.Result.Text}");
    };
    
    // Recognized (not 'Recognizing') will provide the final recognized text 
    // once audio capture is completed
    connector.Recognized += (sender, recognitionEventArgs) =>
    {
        NotifyUser($"Final speech to text result: '{recognitionEventArgs.Result.Text}'");
    };
    
    // SessionStarted will notify when audio begins flowing to the service for a turn
    connector.SessionStarted += (sender, sessionEventArgs) =>
    {
        NotifyUser($"Now Listening! Session started, id={sessionEventArgs.SessionId}");
    };
    
    // SessionStopped will notify when a turn is complete and 
    // it's safe to begin listening again
    connector.SessionStopped += (sender, sessionEventArgs) =>
    {
        NotifyUser($"Listening complete. Session ended, id={sessionEventArgs.SessionId}");
    };
    
  4. Dodaj następujący fragment kodu do treści ListenButton_ButtonClicked metody w MainPage klasie . Ten kod konfiguruje nasłuchiwanie DialogServiceConnector , ponieważ już ustanowiono konfigurację i zarejestrowano programy obsługi zdarzeń.

    if (connector == null)
    {
        InitializeDialogServiceConnector();
        // Optional step to speed up first interaction: if not called, 
        // connection happens automatically on first use
        var connectTask = connector.ConnectAsync();
    }
    
    try
    {
        // Start sending audio to your speech-enabled bot
        var listenTask = connector.ListenOnceAsync();
    
        // You can also send activities to your bot as JSON strings -- 
        // Microsoft.Bot.Schema can simplify this
        string speakActivity = 
            @"{""type"":""message"",""text"":""Greeting Message"", ""speak"":""Hello there!""}";
        await connector.SendActivityAsync(speakActivity);
    
    }
    catch (Exception ex)
    {
        NotifyUser($"Exception: {ex.ToString()}", NotifyType.ErrorMessage);
    }
    

Kompilowanie i uruchamianie aplikacji

Teraz możesz przystąpić do kompilowania aplikacji i testowania niestandardowego asystenta głosowego przy użyciu usługi Mowa.

  1. Na pasku menu wybierz pozycję Kompiluj>rozwiązanie kompilacji, aby skompilować aplikację. Kod powinien teraz zostać skompilowany bez błędów.

  2. Wybierz pozycję Debuguj>Rozpocznij debugowanie (lub naciśnij F5), aby uruchomić aplikację. Zostanie wyświetlone okno helloworld .

    Przykładowa aplikacja asystenta głosowego platformy UWP w języku C# — Szybki start

  3. Wybierz pozycję Włącz mikrofon, a po wyświetleniu żądania uprawnień dostępu wybierz pozycję Tak.

    Żądanie uprawnień dostępu do mikrofonu

  4. Wybierz pozycję Porozmawiaj z botem i powiedz frazę w języku angielskim lub zdanie do mikrofonu urządzenia. Twoja mowa jest przesyłana do kanału mowy direct line i transkrybowana do tekstu, który pojawia się w oknie.

Następne kroki


Możesz wyświetlić lub pobrać wszystkie przykłady języka Java zestawu SDK usługi Mowa w witrynie GitHub.

Wybieranie środowiska docelowego

Wymagania wstępne

Przed rozpoczęciem upewnij się, że:

Uwaga

Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

Tworzenie i konfigurowanie projektu

Utwórz projekt środowiska Eclipse i zainstaluj zestaw SPEECH SDK.

Ponadto, aby włączyć rejestrowanie, zaktualizuj plik pom.xml , aby uwzględnić następującą zależność:

 <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-simple</artifactId>
     <version>1.7.5</version>
 </dependency>

Dodawanie przykładowego kodu

  1. Aby dodać nową pustą klasę do projektu języka Java, wybierz kolejno pozycje Plik>Nowy>Klasa.

  2. W oknie Nowa klasa Java wprowadź ciąg speechsdk.quickstart w polu Pakiet i w polu Nazwa.

    Zrzut ekranu okna Nowa klasa Java

  3. Otwórz nowo utworzoną Main klasę i zastąp zawartość Main.java pliku następującym kodem początkowym:

    package speechsdk.quickstart;
    
    import com.microsoft.cognitiveservices.speech.audio.AudioConfig;
    import com.microsoft.cognitiveservices.speech.audio.PullAudioOutputStream;
    import com.microsoft.cognitiveservices.speech.dialog.BotFrameworkConfig;
    import com.microsoft.cognitiveservices.speech.dialog.DialogServiceConnector;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.SourceDataLine;
    import java.io.InputStream;
    
    public class Main {
        final Logger log = LoggerFactory.getLogger(Main.class);
    
        public static void main(String[] args) {
            // New code will go here
        }
    
        private void playAudioStream(PullAudioOutputStream audio) {
            ActivityAudioStream stream = new ActivityAudioStream(audio);
            final ActivityAudioStream.ActivityAudioFormat audioFormat = stream.getActivityAudioFormat();
            final AudioFormat format = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    audioFormat.getSamplesPerSecond(),
                    audioFormat.getBitsPerSample(),
                    audioFormat.getChannels(),
                    audioFormat.getFrameSize(),
                    audioFormat.getSamplesPerSecond(),
                    false);
            try {
                int bufferSize = format.getFrameSize();
                final byte[] data = new byte[bufferSize];
    
                SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(format);
    
                if (line != null) {
                    line.start();
                    int nBytesRead = 0;
                    while (nBytesRead != -1) {
                        nBytesRead = stream.read(data);
                        if (nBytesRead != -1) {
                            line.write(data, 0, nBytesRead);
                        }
                    }
                    line.drain();
                    line.stop();
                    line.close();
                }
                stream.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
  4. W metodzie main należy najpierw skonfigurować klasę DialogServiceConfig i użyć jej do utworzenia DialogServiceConnector wystąpienia. To wystąpienie łączy się z kanałem mowy direct line w celu interakcji z botem. Wystąpienie AudioConfig służy również do określania źródła danych wejściowych audio. W tym przykładzie domyślny mikrofon jest używany z AudioConfig.fromDefaultMicrophoneInput().

    • Zastąp ciąg YourSubscriptionKey kluczem zasobu usługi Mowa, który można pobrać z witryny Azure Portal.
    • Zastąp ciąg YourServiceRegion regionem skojarzonym z zasobem usługi Mowa.

    Uwaga

    Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

    final String subscriptionKey = "YourSubscriptionKey"; // Your subscription key
    final String region = "YourServiceRegion"; // Your speech subscription service region
    final BotFrameworkConfig botConfig = BotFrameworkConfig.fromSubscription(subscriptionKey, region);
    
    // Configure audio input from a microphone.
    final AudioConfig audioConfig = AudioConfig.fromDefaultMicrophoneInput();
    
    // Create a DialogServiceConnector instance.
    final DialogServiceConnector connector = new DialogServiceConnector(botConfig, audioConfig);
    
  5. Łącznik DialogServiceConnector opiera się na kilku zdarzeniach, aby komunikować swoje działania bota, wyniki rozpoznawania mowy i inne informacje. Dodaj te odbiorniki zdarzeń dalej.

    // Recognizing will provide the intermediate recognized text while an audio stream is being processed.
    connector.recognizing.addEventListener((o, speechRecognitionResultEventArgs) -> {
        log.info("Recognizing speech event text: {}", speechRecognitionResultEventArgs.getResult().getText());
    });
    
    // Recognized will provide the final recognized text once audio capture is completed.
    connector.recognized.addEventListener((o, speechRecognitionResultEventArgs) -> {
        log.info("Recognized speech event reason text: {}", speechRecognitionResultEventArgs.getResult().getText());
    });
    
    // SessionStarted will notify when audio begins flowing to the service for a turn.
    connector.sessionStarted.addEventListener((o, sessionEventArgs) -> {
        log.info("Session Started event id: {} ", sessionEventArgs.getSessionId());
    });
    
    // SessionStopped will notify when a turn is complete and it's safe to begin listening again.
    connector.sessionStopped.addEventListener((o, sessionEventArgs) -> {
        log.info("Session stopped event id: {}", sessionEventArgs.getSessionId());
    });
    
    // Canceled will be signaled when a turn is aborted or experiences an error condition.
    connector.canceled.addEventListener((o, canceledEventArgs) -> {
        log.info("Canceled event details: {}", canceledEventArgs.getErrorDetails());
        connector.disconnectAsync();
    });
    
    // ActivityReceived is the main way your bot will communicate with the client and uses Bot Framework activities.
    connector.activityReceived.addEventListener((o, activityEventArgs) -> {
        final String act = activityEventArgs.getActivity().serialize();
            log.info("Received activity {} audio", activityEventArgs.hasAudio() ? "with" : "without");
            if (activityEventArgs.hasAudio()) {
                playAudioStream(activityEventArgs.getAudio());
            }
        });
    
  6. Połącz się z DialogServiceConnector usługą Direct Line Speech, wywołując metodę connectAsync() . Aby przetestować bota, możesz wywołać metodę listenOnceAsync wysyłania danych wejściowych audio z mikrofonu. Ponadto można również użyć sendActivityAsync metody , aby wysłać działanie niestandardowe jako ciąg serializowany. Te niestandardowe działania mogą udostępniać dodatkowe dane używane przez bota w konwersacji.

    connector.connectAsync();
    // Start listening.
    System.out.println("Say something ...");
    connector.listenOnceAsync();
    
    // connector.sendActivityAsync(...)
    
  7. Zapisz zmiany w Main pliku.

  8. Aby obsługiwać odtwarzanie odpowiedzi, dodaj dodatkową klasę, która przekształca obiekt PullAudioOutputStream zwrócony z interfejsu API getAudio() do strumienia wejściowego Java w celu ułatwienia obsługi. Jest to ActivityAudioStream wyspecjalizowana klasa, która obsługuje odpowiedź audio z kanału mowy direct line. Zapewnia metody dostępu do pobierania informacji o formacie audio, które są wymagane do obsługi odtwarzania. W tym celu wybierz pozycję Plik>Nowa>klasa.

  9. W oknie Nowa klasa Java wprowadź ciąg speechsdk.quickstart w polu Pakiet i ActivityAudioStream w polu Nazwa.

  10. Otwórz nowo utworzoną ActivityAudioStream klasę i zastąp ją następującym kodem:

    package com.speechsdk.quickstart;
    
    import com.microsoft.cognitiveservices.speech.audio.PullAudioOutputStream;
    
    import java.io.IOException;
    import java.io.InputStream;
    
     public final class ActivityAudioStream extends InputStream {
         /**
          * The number of samples played per second (16 kHz).
          */
         public static final long SAMPLE_RATE = 16000;
         /**
          * The number of bits in each sample of a sound that has this format (16 bits).
          */
         public static final int BITS_PER_SECOND = 16;
         /**
          * The number of audio channels in this format (1 for mono).
          */
         public static final int CHANNELS = 1;
         /**
          * The number of bytes in each frame of a sound that has this format (2).
          */
         public static final int FRAME_SIZE = 2;
    
         /**
          * Reads up to a specified maximum number of bytes of data from the audio
          * stream, putting them into the given byte array.
          *
          * @param b   the buffer into which the data is read
          * @param off the offset, from the beginning of array <code>b</code>, at which
          *            the data will be written
          * @param len the maximum number of bytes to read
          * @return the total number of bytes read into the buffer, or -1 if there
          * is no more data because the end of the stream has been reached
          */
         @Override
         public int read(byte[] b, int off, int len) {
             byte[] tempBuffer = new byte[len];
             int n = (int) this.pullStreamImpl.read(tempBuffer);
             for (int i = 0; i < n; i++) {
                 if (off + i > b.length) {
                     throw new ArrayIndexOutOfBoundsException(b.length);
                 }
                 b[off + i] = tempBuffer[i];
             }
             if (n == 0) {
                 return -1;
             }
             return n;
         }
    
         /**
          * Reads the next byte of data from the activity audio stream if available.
          *
          * @return the next byte of data, or -1 if the end of the stream is reached
          * @see #read(byte[], int, int)
          * @see #read(byte[])
          * @see #available
          * <p>
          */
         @Override
         public int read() {
             byte[] data = new byte[1];
             int temp = read(data);
             if (temp <= 0) {
                 // we have a weird situation if read(byte[]) returns 0!
                 return -1;
             }
             return data[0] & 0xFF;
         }
    
         /**
          * Reads up to a specified maximum number of bytes of data from the activity audio stream,
          * putting them into the given byte array.
          *
          * @param b the buffer into which the data is read
          * @return the total number of bytes read into the buffer, or -1 if there
          * is no more data because the end of the stream has been reached
          */
         @Override
         public int read(byte[] b) {
             int n = (int) pullStreamImpl.read(b);
             if (n == 0) {
                 return -1;
             }
             return n;
         }
    
         /**
          * Skips over and discards a specified number of bytes from this
          * audio input stream.
          *
          * @param n the requested number of bytes to be skipped
          * @return the actual number of bytes skipped
          * @throws IOException if an input or output error occurs
          * @see #read
          * @see #available
          */
         @Override
         public long skip(long n) {
             if (n <= 0) {
                 return 0;
             }
             if (n <= Integer.MAX_VALUE) {
                 byte[] tempBuffer = new byte[(int) n];
                 return read(tempBuffer);
             }
             long count = 0;
             for (long i = n; i > 0; i -= Integer.MAX_VALUE) {
                 int size = (int) Math.min(Integer.MAX_VALUE, i);
                 byte[] tempBuffer = new byte[size];
                 count += read(tempBuffer);
             }
             return count;
         }
    
         /**
          * Closes this audio input stream and releases any system resources associated
          * with the stream.
          */
         @Override
         public void close() {
             this.pullStreamImpl.close();
         }
    
         /**
          * Fetch the audio format for the ActivityAudioStream. The ActivityAudioFormat defines the sample rate, bits per sample, and the # channels.
          *
          * @return instance of the ActivityAudioFormat associated with the stream
          */
         public ActivityAudioStream.ActivityAudioFormat getActivityAudioFormat() {
             return activityAudioFormat;
         }
    
         /**
          * Returns the maximum number of bytes that can be read (or skipped over) from this
          * audio input stream without blocking.
          *
          * @return the number of bytes that can be read from this audio input stream without blocking.
          * As this implementation does not buffer, this will be defaulted to 0
          */
         @Override
         public int available() {
             return 0;
         }
    
         public ActivityAudioStream(final PullAudioOutputStream stream) {
             pullStreamImpl = stream;
             this.activityAudioFormat = new ActivityAudioStream.ActivityAudioFormat(SAMPLE_RATE, BITS_PER_SECOND, CHANNELS, FRAME_SIZE, AudioEncoding.PCM_SIGNED);
         }
    
         private PullAudioOutputStream pullStreamImpl;
    
         private ActivityAudioFormat activityAudioFormat;
    
         /**
          * ActivityAudioFormat is an internal format which contains metadata regarding the type of arrangement of
          * audio bits in this activity audio stream.
          */
         static class ActivityAudioFormat {
    
             private long samplesPerSecond;
             private int bitsPerSample;
             private int channels;
             private int frameSize;
             private AudioEncoding encoding;
    
             public ActivityAudioFormat(long samplesPerSecond, int bitsPerSample, int channels, int frameSize, AudioEncoding encoding) {
                 this.samplesPerSecond = samplesPerSecond;
                 this.bitsPerSample = bitsPerSample;
                 this.channels = channels;
                 this.encoding = encoding;
                 this.frameSize = frameSize;
             }
    
             /**
              * Fetch the number of samples played per second for the associated audio stream format.
              *
              * @return the number of samples played per second
              */
             public long getSamplesPerSecond() {
                 return samplesPerSecond;
             }
    
             /**
              * Fetch the number of bits in each sample of a sound that has this audio stream format.
              *
              * @return the number of bits per sample
              */
             public int getBitsPerSample() {
                 return bitsPerSample;
             }
    
             /**
              * Fetch the number of audio channels used by this audio stream format.
              *
              * @return the number of channels
              */
             public int getChannels() {
                 return channels;
             }
    
             /**
              * Fetch the default number of bytes in a frame required by this audio stream format.
              *
              * @return the number of bytes
              */
             public int getFrameSize() {
                 return frameSize;
             }
    
             /**
              * Fetch the audio encoding type associated with this audio stream format.
              *
              * @return the encoding associated
              */
             public AudioEncoding getEncoding() {
                 return encoding;
             }
         }
    
         /**
          * Enum defining the types of audio encoding supported by this stream.
          */
         public enum AudioEncoding {
             PCM_SIGNED("PCM_SIGNED");
    
             String value;
    
             AudioEncoding(String value) {
                 this.value = value;
             }
         }
     }
    
    
  11. Zapisz zmiany w ActivityAudioStream pliku.

Skompiluj i uruchom aplikację

Wybierz pozycję F11 lub wybierz pozycję Uruchom>debugowanie. Konsola wyświetla komunikat "Powiedz coś". W tym momencie wypowiadaj frazę w języku angielskim lub zdanie, które bot może zrozumieć. Twoja mowa jest przesyłana do bota za pośrednictwem kanału mowy direct line, w którym jest rozpoznawana i przetwarzana przez bota. Odpowiedź jest zwracana jako działanie. Jeśli bot zwraca mowę jako odpowiedź, dźwięk jest odtwarzany przy użyciu AudioPlayer klasy .

Zrzut ekranu przedstawiający dane wyjściowe konsoli po pomyślnym ukończeniu rozpoznawania

Następne kroki

Możesz wyświetlić lub pobrać wszystkie przykłady języka Go zestawu SDK usługi Mowa w witrynie GitHub.

Wymagania wstępne

Przed rozpoczęciem pracy:

Uwaga

Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

Konfigurowanie środowiska

Zaktualizuj plik go.mod przy użyciu najnowszej wersji zestawu SDK, dodając ten wiersz

require (
    github.com/Microsoft/cognitive-services-speech-sdk-go v1.15.0
)

Zacznij od kodu kociołowego

Zastąp zawartość pliku źródłowego (np. quickstart.go) poniższym ciągiem, który obejmuje:

  • Definicja pakietu "main"
  • importowanie niezbędnych modułów z zestawu Speech SDK
  • zmienne do przechowywania informacji o botze, które zostaną zastąpione w dalszej części tego przewodnika Szybki start
  • prosta implementacja przy użyciu mikrofonu do wprowadzania dźwięku
  • programy obsługi zdarzeń dla różnych zdarzeń, które odbywają się podczas interakcji z mową
package main

import (
    "fmt"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/dialog"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func main() {
    subscription :=  "YOUR_SUBSCRIPTION_KEY"
    region := "YOUR_BOT_REGION"

    audioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    config, err := dialog.NewBotFrameworkConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    connector, err := dialog.NewDialogServiceConnectorFromConfig(config, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer connector.Close()
    activityReceivedHandler := func(event dialog.ActivityReceivedEventArgs) {
        defer event.Close()
        fmt.Println("Received an activity.")
    }
    connector.ActivityReceived(activityReceivedHandler)
    recognizedHandle := func(event speech.SpeechRecognitionEventArgs) {
        defer event.Close()
        fmt.Println("Recognized ", event.Result.Text)
    }
    connector.Recognized(recognizedHandle)
    recognizingHandler := func(event speech.SpeechRecognitionEventArgs) {
        defer event.Close()
        fmt.Println("Recognizing ", event.Result.Text)
    }
    connector.Recognizing(recognizingHandler)
    connector.ListenOnceAsync()
    <-time.After(10 * time.Second)
}

YOUR_SUBSCRIPTION_KEY Zastąp wartości i YOUR_BOT_REGION rzeczywistymi wartościami z zasobu usługi Mowa.

  • Przejdź do witryny Azure Portal i otwórz zasób usługi Mowa

  • W obszarze Klucze i punkt końcowy po lewej stronie znajdują się dwa dostępne klucze subskrypcji

    • Użyj jednej z nich jako zamiany YOUR_SUBSCRIPTION_KEY wartości
  • W obszarze Przegląd po lewej stronie zanotuj region i zamapuj go na identyfikator regionu

    • Użyj identyfikatora regionu jako wartości zastępczej YOUR_BOT_REGION , na przykład: "westus" dla zachodnich stanów USA

    Uwaga

    Zapoznaj się z listą obsługiwanych regionów dla asystentów głosowych i upewnij się, że zasoby są wdrażane w jednym z tych regionów.

    Uwaga

    Aby uzyskać informacje na temat konfigurowania bota, zobacz dokumentację platformy Bot Framework dotyczącą kanału mowy direct line.

Wyjaśnienie kodu

Klucz subskrypcji usługi Mowa i region są wymagane do utworzenia obiektu konfiguracji mowy. Obiekt konfiguracji jest potrzebny do utworzenia wystąpienia obiektu rozpoznawania mowy.

Wystąpienie rozpoznawania uwidacznia wiele sposobów rozpoznawania mowy. W tym przykładzie mowa jest stale rozpoznawana. Ta funkcja pozwala usłudze Rozpoznawanie mowy wiedzieć, że wysyłasz wiele fraz do rozpoznawania, a gdy program zakończy rozpoznawanie mowy. W miarę zwracania wyników kod zapisze je w konsoli.

Kompilowanie i uruchamianie

Teraz skonfigurujesz projekt i przetestujesz niestandardowy asystent głosowy przy użyciu usługi Mowa.

  1. Kompilowanie projektu, np. "go build"
  2. Uruchom moduł i powiedz frazę lub zdanie do mikrofonu urządzenia. Twoja mowa jest przesyłana do kanału mowy direct line i transkrybowana na tekst, który jest wyświetlany jako dane wyjściowe.

Uwaga

Zestaw SDK rozpoznawania mowy będzie domyślnie rozpoznawany przy użyciu języka en-us. Zobacz Jak rozpoznawać mowę , aby uzyskać informacje na temat wybierania języka źródłowego.

Następne kroki

Dodatkowa obsługa języka i platformy

Jeśli klikniesz tę kartę, prawdopodobnie nie widzisz przewodnika Szybki start w ulubionym języku programowania. Nie martw się, mamy dodatkowe materiały szybki start i przykłady kodu dostępne w witrynie GitHub. Skorzystaj z tabeli, aby znaleźć odpowiedni przykład dla języka programowania i kombinacji platformy/systemu operacyjnego.

Język Przykłady kodu
C# .NET Framework, .NET Core, UWP, Unity
C++ Windows, Linux, macOS
Java Android, JRE
JavaScript Przeglądarka, Node.js
Objective-C iOS, macOS
Python Windows, Linux, macOS
Swift iOS, macOS