بداية سريعة: إنشاء مساعد صوت مخصص

في دليل التشغيل السريع، ستستخدم ⁧⁩Speech SDK⁧⁩ لإنشاء تطبيق مساعد صوتي مخصص يتصل ببوت قمت بتأليفه تهيئته بالفعل. إذا كنت بحاجة إلى إنشاء بوت، فراجع ⁧⁩البرنامج التعليمي المعني⁧⁩؛ للحصول على إرشادات أكثر شمولاً.

بعد استيفاء بعض المتطلبات الأساسية، لا يستغرق الاتصال بالمساعد الصوتي المخصص سوى بضع خطوات:

  • إنشاء كائن ⁧BotFrameworkConfig⁩ من مفتاح الاشتراك والمنطقة.
  • إنشاء كائن ⁧DialogServiceConnector⁩ باستخدام الكائن ⁧BotFrameworkConfig⁩ من أعلى.
  • باستخدام الكائن ⁧DialogServiceConnector⁩، ابدأ عملية الاستماع إلى كلمة واحدة.
  • تحقق من ⁧ActivityReceivedEventArgs⁩ العائدة.

ملاحظة

يدعم Speech SDK لـC++وJavaScript وObjective-C وPython وSwift المساعدين الصوتيين المخصصين، لكننا لم ندرج بعد دليلًا هنا.

يمكنك عرض أو تنزيل جميع عينات Speech SDK C#‎ على GitHub.

المتطلبات الأساسية

قبل البدء، تأكد من:

ملاحظة

يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩ والتأكد من نشر مواردك في إحدى تلك المناطق.

افتح المشروع في Visual Studio

الخطوة الأولى هي التأكد من فتح المشروع الخاص بك في Visual Studio.

ابدأ ببعض الأكواد الخاصة بـ boilerplate

دعنا نضيف بعض التعليمات البرمجية التي تعمل كبنية لمشروعنا.

  1. في ⁧⁩Solution Explorer⁧⁩، افتح ⁧MainPage.xaml⁩.

  2. في طريقة عرض مصمم XAML استبدال المحتويات بأكملها مع المقتطف التالي الذي يعرف واجهة مستخدم بدائية:

    <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>
    

يتم تحديث طريقة عرض التصميم لإظهار واجهة المستخدم للتطبيق.

  1. في ⁧⁩Solution Explorer⁧⁩، افتح الملف المصدر خلف التعليمات البرمجية ⁧MainPage.xaml.cs⁩. (يتم تجميعها تحت ⁧MainPage.xaml⁩.) استبدال محتويات هذا الملف مع ما يلي، والذي يتضمن:
  • using⁩بيانات عن⁧Speech⁩ و ⁧Speech.Dialog⁩ مساحات الأسماء

  • تنفيذ بسيط لضمان الوصول إلى الميكروفون، متصل بمعالج أزرار

  • مساعدو واجهة المستخدم الأساسية لتقديم الرسائل والأخطاء في التطبيق

  • نقطة هبوط لمسار رمز التهيئة الذي سيتم ملؤه لاحقا

  • مساعد لتشغيل النص مرة أخرى إلى الكلام (دون دعم الدفق)

  • معالج زر فارغ لبدء الاستماع الذي سيتم ملؤه لاحقا

    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. قم بإضافة التعليمات البرمجية التالية إلى نص الأسلوب من ⁧InitializeDialogServiceConnector⁩. ينشئ هذا الرمز ⁧DialogServiceConnector⁩ معلومات الاشتراك الخاصة بك.

    // 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);
    

    ملاحظة

    يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩ والتأكد من نشر مواردك في إحدى تلك المناطق.

    ملاحظة

    للحصول على معلومات حول تكوين الروبوت الخاص بك، راجع وثائق Bot Framework من أجل ⁧⁩قناة Direct Line Speech⁧⁩.

  2. استبدل السلاسل ⁧YourSpeechSubscriptionKey⁩ والقيم الخاصة بك للاشتراك في الكلام الخاص بك⁧YourServiceRegion⁩⁧⁩والمنطقة.⁧

  3. إلحاق مقتطف التعليمات البرمجية التالية إلى نهاية نص الأسلوب من ⁧InitializeDialogServiceConnector⁩. يقوم هذا الرمز بإعداد معالجات للأحداث التي يعتمد عليها ⁧DialogServiceConnector⁩ لتوصيل أنشطة البوت ونتائج التعرف على الكلام والمعلومات الأخرى.

    // 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. قم بإضافة التعليمات البرمجية التالية إلي هيكل ⁧ListenButton_ButtonClicked⁩ الأسلوب في ⁧MainPage⁩ الفئة. يتم إعداد هذه التعليمات البرمجية ⁧DialogServiceConnector⁩ للاستماع، حيث قمت بالفعل بتأسيس التكوين وتسجيل معالجات الأحداث.

    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);
    }
    

إنشاء تطبيق خاص بك وتشغيله

الآن أنت مستعد لبناء التطبيق واختبار مساعد الصوت المخصص باستخدام Speech service.

  1. من شريط القوائم، اختر ⁧⁩إنشاء⁧⁩⁧>⁩⁧⁩ حل⁧⁩ بناء لبناء التطبيق. يجب أن تتم ترجمة التعليمات البرمجية بدون أخطاء الآن.

  2. اختر ⁧⁩Debug⁧⁩⁧>⁩⁧⁩Start Debugging⁧⁩ (أو اضغط ⁧⁩F5⁧⁩) لبدء تشغيل التطبيق. تظهر نافذة ⁧⁩helloworld⁧⁩.

    نموذج UWP تطبيق مساعد الصوت في C # - تشغيل سريع

  3. حدد ⁧⁩تمكين الميكروفون⁧⁩، وعندما يظهر طلب إذن الوصول، حدد ⁧⁩نعم⁧⁩.

    طلب إذن الوصول إلى الميكروفون

  4. حدد ⁧⁩التحدث إلى البوت الخاص بك،⁧⁩وتحدث عبارة أو جملة باللغة الإنجليزية في ميكروفون جهازك. يتم إرسال الكلام إلى قناة Direct Line Speech ونسخه إلى نص يظهر في الإطار.

الخطوات التالية


يمكنك عرض أو تنزيل جميع نماذج Speech SDK Java على GitHub.

اختَر البيئة المستهدفة

المتطلبات الأساسية

قبل البدء، تأكد من:

ملاحظة

يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩، والتأكد من نشر مواردك في إحدى تلك المناطق.

إنشاء وتكوين المشروع

إنشاء مشروع Eclipse وتثبيت Speech SDK.

بالإضافة إلى ذلك، لتمكين التسجيل، قم بتحديث ملف⁧⁩ pom.xml ⁧⁩ ليشمل التبعية التالية:

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

إضافة نموذج التعليمات البرمجية

  1. لإضافة فئة فارغة جديدة إلى مشروع Java الخاص بك، حدد ⁧⁩New⁧⁩ ⁧>⁩ ⁧⁩ File⁧⁩ ⁧>⁩ ⁧⁩ Class⁧⁩.

  2. في نافذة⁧⁩ New Java Class ⁧⁩، أدخل⁧⁩ speechsdk.quickstart⁧⁩ في حقل⁧⁩Package⁧⁩ و⁧⁩Main⁧⁩ في ⁧⁩Name⁧⁩ حقل.

    لقطة شاشة لنافذة فئة Java الجديدة

  3. افتح فئة ⁧Main⁩ المنشأة حديثًا، واستبدل محتويات ملف⁧Main.java⁩ برمز البداية التالي:

    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. في الطريقة⁧main⁩، تقوم أولاً بتهيئة⁧DialogServiceConfig⁩ الخاص بك، واستخدامه لإنشاء مثيل⁧DialogServiceConnector⁩. يتصل هذا المثيل بقناة الخط المباشر للتفاعل مع الروبوت الخاص بك. يتم استخدام مثيل⁧AudioConfig⁩ أيضًا لتحديد مصدر إدخال الصوت. في هذا المثال، يتم استخدام الميكروفون الافتراضي مع⁧AudioConfig.fromDefaultMicrophoneInput()⁩.

    • استبدل السلسلة YourSubscriptionKey بمفتاح مورد Speech، والذي يمكنك الحصول عليه من مدخل Microsoft Azure.
    • استبدل السلسلة YourServiceRegionبالمنطقة المقترنة باشتراكك.

    ملاحظة

    يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩، والتأكد من نشر مواردك في إحدى تلك المناطق.

    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. يعتمد الموصل⁧DialogServiceConnector⁩ على عدة أحداث لتوصيل أنشطة الروبوت، ونتائج التعرف على الكلام، وغيرها من المعلومات. أضف هؤلاء المستمعين إلى الحدث بعد ذلك.

    // 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. قم بتوصيل⁧DialogServiceConnector⁩ بالخطاب المباشر عن طريق استدعاء طريقة ⁧connectAsync()⁩. لاختبار برنامج الروبوت الخاص بك، يمكنك استدعاء طريقة⁧listenOnceAsync⁩ لإرسال إدخال صوتي من الميكروفون. بالإضافة إلى ذلك، يمكنك أيضًا استخدام طريقة⁧sendActivityAsync⁩ لإرسال نشاط مخصص كسلسلة متسلسلة. يمكن أن توفر هذه الأنشطة المخصصة بيانات إضافية يستخدمها الروبوت الخاص بك في المحادثة.

    connector.connectAsync();
    // Start listening.
    System.out.println("Say something ...");
    connector.listenOnceAsync();
    
    // connector.sendActivityAsync(...)
    
  7. احفظ التغييرات في ملف ⁧Main⁩.

  8. لدعم تشغيل الاستجابة، أضف فئة إضافية تعمل على تحويل كائن PullAudioOutputStream الذي تم إرجاعه من واجهة برمجة تطبيقات getAudio () إلى Java InputStream لسهولة المعالجة. هذه ⁧ActivityAudioStream⁩ فئة متخصصة تعالج الاستجابة الصوتية من قناة الخط المباشر. يوفر وصّلات لجلب معلومات تنسيق الصوت المطلوبة للتعامل مع التشغيل. لذلك، حدد ⁧⁩File⁧⁩⁧>⁩⁧⁩New⁧⁩⁧>⁩⁧⁩Class⁧⁩.

  9. في نافذة⁧⁩ New Java Class ⁧⁩، أدخل⁧⁩ speechsdk.quickstart⁧⁩ في حقل⁧⁩Package⁧⁩ و⁧⁩ ActivityAudioStream ⁧⁩ في حقل⁧⁩Name⁧⁩.

  10. افتح فئة ⁧ActivityAudioStream⁩ المنشأة حديثًا، واستبدلها بالتعليمة البرمجية التالية:

    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. احفظ التغييرات في ملف⁧ActivityAudioStream⁩.

إنشاء وتشغيل التطبيق

حدد F11، أو حدد⁧⁩Run⁧⁩ ⁧>⁩ ⁧⁩Debug⁧⁩. تعرض وحدة التحكم الرسالة "قل شيئا". عند هذه النقطة، تحدث بعبارة أو جملة إنجليزية يمكن أن يفهمها الروبوت الخاص بك. يتم نقل كلامك إلى الروبوت الخاص بك من خلال قناة الخط المباشر؛ حيث يتم التعرف عليه ومعالجته بواسطة الروبوت الخاص بك. يتم إرجاع الرد كنشاط. إذا أعاد الروبوت الكلام كرد فعل، فسيتم تشغيل الصوت باستخدام الفئة⁧AudioPlayer⁩.

لقطة شاشة لمخرجات وحدة التحكم بعد التعرف الناجح

الخطوات التالية

يمكنك عرض أو تنزيل جميع عينات Speech SDK Go على GitHub.

المتطلبات الأساسية

قبل البدء:

ملاحظة

يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩ والتأكد من نشر مواردك في إحدى تلك المناطق.

إعداد البيئة الخاصة بك

تحديث ملف go.mod مع أحدث إصدار SDK بإضافة هذا السطر

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

ابدأ ببعض الأكواد الخاصة بـ boilerplate

استبدل محتويات الملف المصدر (على سبيل ⁧quickstart.go⁩ المثال) بما يلي، والذي يتضمن:

  • تعريف الحزمة "الرئيسي"
  • استيراد الوحدات النمطية الضرورية من Speech SDK
  • المتغيرات الخاصة لتخزين معلومات الروبوت التي سيتم استبدالها في وقت لاحق في هذه البداية السريعة
  • تنفيذ بسيط لبرنامج باستخدام الميكروفون لإدخال الصوت
  • معالجات الأحداث للأحداث المختلفة التي تحدث في أثناء تفاعل بالكلام
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⁩ و⁧YOUR_BOT_REGION⁩القيم بالقيم الفعلية من مورد الكلام.

  • انتقل إلى مدخل Azure، وافتح مورد الكلام

  • ضمن ⁧⁩المفاتيح ونقطة النهاية⁧⁩ على اليسار، هناك مفتاحي اشتراك متاحين

    • استخدام أي واحد منهما ⁧YOUR_SUBSCRIPTION_KEY⁩ كبديل للقيمة
  • ضمن ⁧⁩نظرة عامة⁧⁩ على اليسار، لاحظ المنطقة واربط خريطة لها إلى معرف المنطقة

    • استخدم معرف المنطقة ⁧YOUR_BOT_REGION⁩ كبديل للقيمة، على سبيل المثال: ⁧"westus"⁩ لـ⁧⁩غرب الولايات المتحدة⁧

    ملاحظة

    يُرجى الرجوع إلى ⁧⁩قائمة المناطق المدعومة للمساعدين الصوتيين⁧⁩ والتأكد من نشر مواردك في إحدى تلك المناطق.

    ملاحظة

    للحصول على معلومات حول تكوين الروبوت الخاص بك، راجع وثائق إطار عمل الروبوت من أجل ⁧⁩قناة الكلام المباشر⁧⁩.

شرح التعليمات البرمجية

مطلوب مفتاح اشتراك Speech والمنطقة لإنشاء كائن تكوين الكلام. مطلوب كائن التكوين لإنشاء مثيل كائن التعرف على الكلام.

يعرض مثيل التعرف طرقًا متعددة للتعرف على الكلام. في هذا المثال، يتم التعرف على الكلام باستمرار. تتيح هذه الوظيفة لخدمة الكلام معرفة أنك ترسل العديد من العبارات للتعرف عليها، ومتى ينتهي البرنامج لإيقاف التعرف على الكلام. ومع تدفق النتائج، سيتقوم التعليمات البرمجية بكتابتها إلى وحدة التحكم.

إنشاء وتشغيل

لقد تم إعدادك الآن لإنشاء مشروعك واختبار مساعد الصوت المخصص باستخدام خدمة الكلام.

  1. بناء مشروعك، على سبيل المثال ⁧⁩"go build"⁧
  2. قم بتشغيل الوحدة النمطية وتحدث بعبارة أو جملة في ميكروفون جهازك. يتم إرسال الكلام إلى قناة الكلام المباشر ونسخه إلى نص يظهر كمخرجات.

ملاحظة

سيجرى ضبط Speech SDK افتراضياً على التعرف باستخدام اللغة الإنجليزية. ولمعرفة اللغة، راجعطريقة التعرف على الحديث للحصول على معلومات حول اختيار لغة المصدر.

الخطوات التالية

دعم إضافي للغة والأنظمة الأساسية

إذا حددت علامة التبويب هذه، فمن المحتمل أنك لم تشاهد بداية سريعة في لغة البرمجة المفضلة لديك. لا تقلق، لدينا مواد سريعة إضافية وعينات أكواد متاحة على GitHub. استخدم الجدول للعثور على العينة المناسبة للغة البرمجة وتركيبة النظام الأساسي/نظام التشغيل.

اللغة نماذج التعليمات البرمجية
C#‎ .NET Framework, .NET Core, UWP, Unity, Xamarin
C++‎ Windows, Linux, macOS
Java Android, JRE
JavaScript متصفح, Node.js
Objective-C iOS, macOS
Python Windows, Linux, macOS
Swift iOS, macOS