Använda codec-komprimerade ljudindata
Speech SDK och Speech CLI kan acceptera komprimerade ljudformat med hjälp av GStreamer. GStreamer dekomprimerar ljudet innan det skickas via kabel till Speech-tjänsten som rå PCM.
| Plattform | Språk | GStreamer-version som stöds |
|---|---|---|
| Linux | C++, C#, Java, Python, Go | Linux-distributioner och målarkitekturer som stöds |
| Windows (exklusive UWP) | C++, C#, Java, Python | 1.18.3 |
| Android | Java | 1.18.3 |
Installera GStreamer på Linux
Mer information finns i Installationsanvisningar för Linux.
sudo apt install libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly
Installera GStreamer på Windows
Mer information finns i Windows installationsanvisningar.
- Skapa en mapp c:\gstreamer
- Ladda ned installationsprogram
- Kopiera installationsprogrammet till c:\gstreamer
- Öppna PowerShell som administratör.
- Kör följande kommando i PowerShell:
cd c:\gstreamer
msiexec /passive INSTALLLEVEL=1000 INSTALLDIR=C:\gstreamer /i gstreamer-1.0-msvc-x86_64-1.18.3.msi
- Lägg till systemvariablerna GST_PLUGIN_PATH med värdet C:\gstreamer\1.0\msvc_x86_64\lib\gstreamer-1.0
- Lägg till systemvariablerna GSTREAMER_ROOT_X86_64 med värdet C:\gstreamer\1.0\msvc_x86_64
- Lägg till ytterligare en post i sökvägsvariabeln som C:\gstreamer\1.0\msvc_x86_64\bin
- Starta om datorn
Använda GStreamer i Android
Titta på Java-fliken ovan för information om hur du skapar libgstreamer_android.so
Mer information finns i Installationsanvisningar för Android.
Speech SDK-version krävs för komprimerade ljudindata
- Speech SDK version 1.10.0 eller senare krävs för RHEL 8 och CentOS 8
- Speech SDK version 1.11.0 eller senare krävs för Windows.
- Speech SDK version 1.16.0 eller senare för den senaste GStreamer på Windows och Android.
Standardformatet för ljudströmning är WAV (16 kHz eller 8 kHz, 16-bitars och mono PCM). Utanför WAV/PCM stöds även komprimerade indataformat som anges nedan med hjälp av GStreamer.
- MP3
- GS/OGG
- FLAC
- A WAV i wav-container
- MUCF i wav-container
- ANY (för scenariot där medieformatet inte är känt)
GStreamer krävs för att hantera komprimerat ljud
Hantering av komprimerat ljud implementeras med hjälp av GStreamer. Av licensieringsskäl kompileras inte GStreamer-binärfiler och länkas inte med Speech SDK. Utvecklare måste installera flera beroenden och plugin-program. Mer information finns i Installera på Windows eller Installera på Linux. GStreamer-binärfiler måste finnas i systemsökvägen så att Speech SDK kan läsa in binärfilerna under körning. Om speech SDK Windows kan hitta eller (för senaste GStreamer) under körning innebär det till exempel att libgstreamer-1.0-0.dll GStreamer-binärfilerna finns i gstreamer-1.0-0.dll systemsökvägen.
Hantering av komprimerat ljud implementeras med hjälp av GStreamer. Av licensskäl kompileras inte GStreamer-binärfiler och länkas inte till Speech SDK. Utvecklare måste installera flera beroenden och plugin-program.
Anteckning
Obligatoriska allmänna inställningar för Linux finns i systemkrav och installationsanvisningar.
sudo apt install libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly
Hantering av komprimerat ljud implementeras med hjälp av GStreamer. Av licensskäl kompileras inte GStreamer-binärfiler och länkas inte till Speech SDK. I stället måste du använda de fördefinierade binärfilerna för Android. Information om hur du laddar ned de fördefinierade biblioteken finns i Installera för Android-utveckling.
libgstreamer_android.so måste anges. Kontrollera att alla GStreamer-plugin-program (från Android.mk nedan) är länkade i libgstreamer_android.so . När du använder senaste speech SDK (1.16 och senare) med GStreamer version 1.18.3 måste också finnas från libc++_shared.so Android ndk.
GSTREAMER_PLUGINS := coreelements app audioconvert mpg123 \
audioresample audioparsers ogg opusparse \
opus wavparse alaw mulaw flac
Ett exempel Android.mk och en fil finns Application.mk nedan. Följ dessa steg för att skapa det gstreamer delade objektet: libgstreamer_android.so .
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := dummy
LOCAL_SHARED_LIBRARIES := gstreamer_android
include $(BUILD_SHARED_LIBRARY)
ifndef GSTREAMER_ROOT_ANDROID
$(error GSTREAMER_ROOT_ANDROID is not defined!)
endif
ifndef APP_BUILD_SCRIPT
$(error APP_BUILD_SCRIPT is not defined!)
endif
ifndef TARGET_ARCH_ABI
$(error TARGET_ARCH_ABI is not defined!)
endif
ifeq ($(TARGET_ARCH_ABI),armeabi)
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)/arm
else ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)/armv7
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)/arm64
else ifeq ($(TARGET_ARCH_ABI),x86)
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)/x86
else ifeq ($(TARGET_ARCH_ABI),x86_64)
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)/x86_64
else
$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
endif
GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/
include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) \
$(GSTREAMER_PLUGINS_CODECS) \
$(GSTREAMER_PLUGINS_PLAYBACK) \
$(GSTREAMER_PLUGINS_CODECS_GPL) \
$(GSTREAMER_PLUGINS_CODECS_RESTRICTED)
GSTREAMER_EXTRA_LIBS := -liconv -lgstbase-1.0 -lGLESv2 -lEGL
include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk
# Application.mk
APP_STL = c++_shared
APP_PLATFORM = android-21
APP_BUILD_SCRIPT = Android.mk
Du kan skapa libgstreamer_android.so med följande kommando i Ubuntu 18.04 eller 20.04. Följande kommandorader har endast testats för GStreamer Android version 1.14.4 med Android NDK b16b.
# Assuming wget and unzip already installed on the system
mkdir buildLibGstreamer
cd buildLibGstreamer
wget https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip
unzip -q -o android-ndk-r16b-linux-x86_64.zip
export PATH=$PATH:$(pwd)/android-ndk-r16b
export NDK_PROJECT_PATH=$(pwd)/android-ndk-r16b
wget https://gstreamer.freedesktop.org/data/pkg/android/1.14.4/gstreamer-1.0-android-universal-1.14.4.tar.bz2
mkdir gstreamer_android
tar -xjf gstreamer-1.0-android-universal-1.14.4.tar.bz2 -C $(pwd)/gstreamer_android/
export GSTREAMER_ROOT_ANDROID=$(pwd)/gstreamer_android
mkdir gstreamer
# Copy the Application.mk and Android.mk from the documentation above and put it inside $(pwd)/gstreamer
# Enable only one of the following at one time to create the shared object for the targeted ABI
echo "building for armeabi-v7a. libgstreamer_android.so will be placed in $(pwd)/armeabi-v7a"
ndk-build -C $(pwd)/gstreamer "NDK_APPLICATION_MK=Application.mk" APP_ABI=armeabi-v7a NDK_LIBS_OUT=$(pwd)
#echo "building for arm64-v8a. libgstreamer_android.so will be placed in $(pwd)/arm64-v8a"
#ndk-build -C $(pwd)/gstreamer "NDK_APPLICATION_MK=Application.mk" APP_ABI=arm64-v8a NDK_LIBS_OUT=$(pwd)
#echo "building for x86_64. libgstreamer_android.so will be placed in $(pwd)/x86_64"
#ndk-build -C $(pwd)/gstreamer "NDK_APPLICATION_MK=Application.mk" APP_ABI=x86_64 NDK_LIBS_OUT=$(pwd)
#echo "building for x86. libgstreamer_android.so will be placed in $(pwd)/x86"
#ndk-build -C $(pwd)/gstreamer "NDK_APPLICATION_MK=Application.mk" APP_ABI=x86 NDK_LIBS_OUT=$(pwd)
När det delade objektet ( ) har skapats måste programutvecklaren placera det delade objektet i Android-appen så att det libgstreamer_android.so kan läsas in av Speech SDK.
Hantering av komprimerat ljud implementeras med hjälp av GStreamer. Av licensieringsskäl kompileras inte GStreamer-binärfiler och länkas inte med Speech SDK. Utvecklare måste installera flera beroenden och plugin-program. Mer information finns i Installera på Windows eller Installera på Linux. GStreamer-binärfiler måste finnas i systemsökvägen så att Speech SDK kan läsa in binärfilerna under körning. Om speech SDK Windows kan hitta under körning innebär det till exempel att GStreamer-binärfilerna finns i systemsökvägen på en annan libgstreamer-1.0-0.dll plats.
Speech SDK kan använda GStreamer för att hantera komprimerat ljud. Av licensieringsskäl kompileras dock inte GStreamer-binärfiler och länkas till Speech SDK. Utvecklare måste installera flera beroenden och plugin-program. Mer information finns i Installera på Linux. Språket Go stöds endast i Speech SDK på Linux-plattformen. Se Speech SDK för Go för att komma igång med Microsoft Speech SDK i Go.
Exempelkod med codec-komprimerade ljudindata
Om du vill konfigurera Speech SDK för att acceptera komprimerade ljudindata skapar PullAudioInputStream du eller PushAudioInputStream . Skapa sedan en från AudioConfig en instans av din dataströmklass och ange komprimeringsformatet för dataströmmen. Hitta relaterade exempelkodfragment i About the Speech SDK audio input stream API.
Anta att du har en indataströmsklass som heter pullStream och använderGS/OGG. Koden kan se ut så här:
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
// ... omitted for brevity
var speechConfig =
SpeechConfig.FromSubscription(
"YourSubscriptionKey",
"YourServiceRegion");
// Create an audio config specifying the compressed
// audio format and the instance of your input stream class.
var audioFormat =
AudioStreamFormat.GetCompressedFormat(
AudioStreamContainerFormat.OGG_OPUS);
var audioConfig =
AudioConfig.FromStreamInput(
pullStream,
audioFormat);
using var recognizer = new SpeechRecognizer(speechConfig, audioConfig);
var result = await recognizer.RecognizeOnceAsync();
var text = result.Text;
Om du vill konfigurera Speech SDK för att acceptera komprimerade ljudindata skapar PullAudioInputStream du eller PushAudioInputStream . Skapa sedan en från AudioConfig en instans av din dataströmklass och ange komprimeringsformatet för dataströmmen. Hitta relaterad exempelkod i Speech SDK-exempel.
Anta att du har en indataströmsklass med pushStream namnet och använderGS/OGG. Koden kan se ut så här:
using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Audio;
// ... omitted for brevity
auto config =
SpeechConfig::FromSubscription(
"YourSubscriptionKey",
"YourServiceRegion"
);
auto audioFormat =
AudioStreamFormat::GetCompressedFormat(
AudioStreamContainerFormat::OGG_OPUS
);
auto audioConfig =
AudioConfig::FromStreamInput(
pushStream,
audioFormat
);
auto recognizer = SpeechRecognizer::FromConfig(config, audioConfig);
auto result = recognizer->RecognizeOnceAsync().get();
auto text = result->Text;
Om du vill konfigurera Speech SDK för att acceptera komprimerade ljudindata skapar du PullAudioInputStream en eller PushAudioInputStream . Skapa sedan en från AudioConfig en instans av din stream-klass och ange komprimeringsformatet för dataströmmen. Hitta relaterad exempelkod i Speech SDK-exempel.
Anta att du har en indataströmsklass som heter pullStream och använderGS/OGG. Koden kan se ut så här:
import com.microsoft.cognitiveservices.speech.audio.AudioConfig;
import com.microsoft.cognitiveservices.speech.audio.AudioInputStream;
import com.microsoft.cognitiveservices.speech.audio.AudioStreamFormat;
import com.microsoft.cognitiveservices.speech.audio.PullAudioInputStream;
import com.microsoft.cognitiveservices.speech.audio.AudioStreamContainerFormat;
// ... omitted for brevity
SpeechConfig speechConfig =
SpeechConfig.fromSubscription(
"YourSubscriptionKey",
"YourServiceRegion");
// Create an audio config specifying the compressed
// audio format and the instance of your input stream class.
AudioStreamFormat audioFormat =
AudioStreamFormat.getCompressedFormat(
AudioStreamContainerFormat.OGG_OPUS);
AudioConfig audioConfig =
AudioConfig.fromStreamInput(
pullStream,
audioFormat);
SpeechRecognizer recognizer = new SpeechRecognizer(speechConfig, audioConfig);
SpeechRecognitionResult result = recognizer.recognizeOnceAsync().get();
String text = result.getText();
Om du vill konfigurera tal-SDK för att acceptera komprimerade ljud måste du skapa PullAudioInputStream eller PushAudioInputStream . Skapa sedan en AudioConfig från en instans av data ström klassen och ange komprimerings formatet för data strömmen.
Vi antar att ditt användnings fall är att använda PullStream för en MP3 fil. Din kod kan se ut så här:
import azure.cognitiveservices.speech as speechsdk
class BinaryFileReaderCallback(speechsdk.audio.PullAudioInputStreamCallback):
def __init__(self, filename: str):
super().__init__()
self._file_h = open(filename, "rb")
def read(self, buffer: memoryview) -> int:
print('trying to read {} frames'.format(buffer.nbytes))
try:
size = buffer.nbytes
frames = self._file_h.read(size)
buffer[:len(frames)] = frames
print('read {} frames'.format(len(frames)))
return len(frames)
except Exception as ex:
print('Exception in `read`: {}'.format(ex))
raise
def close(self) -> None:
print('closing file')
try:
self._file_h.close()
except Exception as ex:
print('Exception in `close`: {}'.format(ex))
raise
def compressed_stream_helper(compressed_format,
mp3_file_path,
default_speech_auth):
callback = BinaryFileReaderCallback(mp3_file_path)
stream = speechsdk.audio.PullAudioInputStream(stream_format=compressed_format, pull_stream_callback=callback)
speech_config = speechsdk.SpeechConfig(**default_speech_auth)
audio_config = speechsdk.audio.AudioConfig(stream=stream)
speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)
done = False
def stop_cb(evt):
"""callback that signals to stop continuous recognition upon receiving an event `evt`"""
print('CLOSING on {}'.format(evt))
nonlocal done
done = True
# Connect callbacks to the events fired by the speech recognizer
speech_recognizer.recognizing.connect(lambda evt: print('RECOGNIZING: {}'.format(evt)))
speech_recognizer.recognized.connect(lambda evt: print('RECOGNIZED: {}'.format(evt)))
speech_recognizer.session_started.connect(lambda evt: print('SESSION STARTED: {}'.format(evt)))
speech_recognizer.session_stopped.connect(lambda evt: print('SESSION STOPPED {}'.format(evt)))
speech_recognizer.canceled.connect(lambda evt: print('CANCELED {}'.format(evt)))
# stop continuous recognition on either session stopped or canceled events
speech_recognizer.session_stopped.connect(stop_cb)
speech_recognizer.canceled.connect(stop_cb)
# Start continuous speech recognition
speech_recognizer.start_continuous_recognition()
while not done:
time.sleep(.5)
speech_recognizer.stop_continuous_recognition()
# </SpeechContinuousRecognitionWithFile>
def pull_audio_input_stream_compressed_mp3(mp3_file_path: str,
default_speech_auth):
# Create a compressed format
compressed_format = speechsdk.audio.AudioStreamFormat(compressed_stream_format=speechsdk.AudioStreamContainerFormat.MP3)
compressed_stream_helper(compressed_format, mp3_file_path, default_speech_auth)
Om du vill konfigurera Speech SDK för att acceptera komprimerade ljudindata skapar du PullAudioInputStream en eller PushAudioInputStream . Skapa sedan en från AudioConfig en instans av din stream-klass och ange komprimeringsformatet för dataströmmen.
I följande exempel antar vi att ditt användningsfall är att använda PushStream för en komprimerad fil.
package recognizer
import (
"fmt"
"time"
"strings"
"github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
"github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
"github.com/Microsoft/cognitive-services-speech-sdk-go/samples/helpers"
)
func RecognizeOnceFromCompressedFile(subscription string, region string, file string) {
var containerFormat audio.AudioStreamContainerFormat
if strings.Contains(file, ".mulaw") {
containerFormat = audio.MULAW
} else if strings.Contains(file, ".alaw") {
containerFormat = audio.ALAW
} else if strings.Contains(file, ".mp3") {
containerFormat = audio.MP3
} else if strings.Contains(file, ".flac") {
containerFormat = audio.FLAC
} else if strings.Contains(file, ".opus") {
containerFormat = audio.OGGOPUS
} else {
containerFormat = audio.ANY
}
format, err := audio.GetCompressedFormat(containerFormat)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer format.Close()
stream, err := audio.CreatePushAudioInputStreamFromFormat(format)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer stream.Close()
audioConfig, err := audio.NewAudioConfigFromStreamInput(stream)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer audioConfig.Close()
config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer config.Close()
speechRecognizer, err := speech.NewSpeechRecognizerFromConfig(config, audioConfig)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechRecognizer.Close()
speechRecognizer.SessionStarted(func(event speech.SessionEventArgs) {
defer event.Close()
fmt.Println("Session Started (ID=", event.SessionID, ")")
})
speechRecognizer.SessionStopped(func(event speech.SessionEventArgs) {
defer event.Close()
fmt.Println("Session Stopped (ID=", event.SessionID, ")")
})
helpers.PumpFileIntoStream(file, stream)
task := speechRecognizer.RecognizeOnceAsync()
var outcome speech.SpeechRecognitionOutcome
select {
case outcome = <-task:
case <-time.After(40 * time.Second):
fmt.Println("Timed out")
return
}
defer outcome.Close()
if outcome.Error != nil {
fmt.Println("Got an error: ", outcome.Error)
}
fmt.Println("Got a recognition!")
fmt.Println(outcome.Result.Text)
}