Met een codec gecomprimeerde audio-invoer gebruiken
De Speech SDK en Speech CLI kunnen gecomprimeerde audio-indelingen accepteren met GStreamer. GStreamer decomprimeert de audio voordat deze als onbewerkte PCM via de kabel naar de Speech-service wordt verzonden.
| Platform | Talen | Ondersteunde GStreamer-versie |
|---|---|---|
| Linux | C++, C#, Java, Python, Go | Ondersteunde Linux-distributies en doelarchitecten |
| Windows (met uitzondering van UWP) | C++, C#, Java, Python | 1.18.3 |
| Android | Java | 1.18.3 |
GStreamer installeren in Linux
Zie Installatie-instructies voor Linux voor meer informatie.
sudo apt install libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly
GStreamer installeren op Windows
Zie de installatie-instructies Windows meer informatie.
- Een map maken c:\gstreamer
- Installatieprogramma downloaden
- Kopieer het installatieprogramma naar c:\gstreamer
- Open PowerShell als beheerder.
- Voer de volgende opdracht uit in PowerShell:
cd c:\gstreamer
msiexec /passive INSTALLLEVEL=1000 INSTALLDIR=C:\gstreamer /i gstreamer-1.0-msvc-x86_64-1.18.3.msi
- Voeg de systeemvariabelen toe GST_PLUGIN_PATH waarde C:\gstreamer\1.0\msvc_x86_64\lib\gstreamer-1.0
- Voeg de systeemvariabelen GSTREAMER_ROOT_X86_64 waarde C:\gstreamer\1.0\msvc_x86_64
- Voeg nog een vermelding toe aan de padvariabele als C:\gstreamer\1.0\msvc_x86_64\bin
- Start de machine opnieuw op
GStreamer gebruiken in Android
Bekijk het bovenstaande Java-tabblad voor meer informatie over het libgstreamer_android.so
Zie Android-installatie-instructies voor meer informatie.
Speech SDK-versie vereist voor gecomprimeerde audio-invoer
- Speech SDK versie 1.10.0 of hoger is vereist voor RHEL 8 en CentOS 8
- Speech SDK versie 1.11.0 of hoger is vereist voor Windows.
- Speech SDK versie 1.16.0 of hoger voor de nieuwste GStreamer op Windows en Android.
De standaardindeling voor audiostreaming is WAV (16 kHz of 8 kHz, 16-bits en mono PCM). Naast WAV/PCM worden de onderstaande gecomprimeerde invoerindelingen ook ondersteund met behulp van GStreamer.
- MP3
- OPUS/OGG
- FLAC
- ALAW in wav-container
- MULAW in wav-container
- ANY (voor het scenario waarin de media-indeling niet bekend is)
GStreamer vereist voor het verwerken van gecomprimeerde audio
Het verwerken van gecomprimeerde audio wordt geïmplementeerd met GStreamer. Om licentieredenen worden binaire GStreamer-bestanden niet gecompileerd en gekoppeld aan de Speech SDK. Ontwikkelaars moeten verschillende afhankelijkheden en invoegingen installeren. Zie Installeren op Windows of Installeren op Linux. Binaire GStreamer-bestanden moeten zich in het systeempad, zodat de Speech SDK de binaire bestanden tijdens runtime kan laden. Als de Speech SDK Windows runtime bijvoorbeeld of (voor de meest recente GStreamer) kan vinden, betekent dit dat de libgstreamer-1.0-0.dll binaire GStreamer-bestanden zich in het systeempad gstreamer-1.0-0.dll zijn.
Het verwerken van gecomprimeerde audio wordt geïmplementeerd met GStreamer. Om licentieredenen worden binaire GStreamer-bestanden niet gecompileerd en gekoppeld aan de Speech SDK. Ontwikkelaars moeten verschillende afhankelijkheden en invoegingen installeren.
Notitie
Zie systeemvereisten en installatie-instructies voor verplichte algemene instellingen inLinux.
sudo apt install libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly
Het verwerken van gecomprimeerde audio wordt geïmplementeerd met GStreamer. Om licentieredenen worden de binaire bestanden van GStreamer niet gecompileerd en gekoppeld aan de Speech-SDK. In plaats daarvan moet u de vooraf gebouwde binaire bestanden voor Android gebruiken. Zie Installeren voor Android-ontwikkeling voor het downloaden van de vooraf gebouwde bibliotheken.
libgstreamer_android.so is vereist. Zorg ervoor dat alle GStreamer-invoegingen (uit Android.mk bestand hieronder) zijn gekoppeld in libgstreamer_android.so . Wanneer u de nieuwste speech-SDK (1.16 en hoger) met GStreamer versie 1.18.3 gebruikt, moet u ook aanwezig zijn vanuit libc++_shared.so android ndk.
GSTREAMER_PLUGINS := coreelements app audioconvert mpg123 \
audioresample audioparsers ogg opusparse \
opus wavparse alaw mulaw flac
Hieronder vindt Android.mk u een voorbeeld en een Application.mk bestand. Volg deze stappen om het gedeelde gstreamer object te maken: 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
U kunt bouwen libgstreamer_android.so met behulp van de volgende opdracht op Ubuntu 18.04 of 20.04. De volgende opdrachtregels zijn alleen getest voor GStreamer Android-versie 1.14.4 met 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)
Zodra het gedeelde object ( ) is gebouwd, moet de ontwikkelaar van de toepassing het gedeelde object in de Android-app plaatsen, zodat het kan worden geladen libgstreamer_android.so door de Speech SDK.
Het verwerken van gecomprimeerde audio wordt geïmplementeerd met GStreamer. Om licentieredenen worden binaire GStreamer-bestanden niet gecompileerd en gekoppeld aan de Speech SDK. Ontwikkelaars moeten verschillende afhankelijkheden en invoegingen installeren. Zie Installeren op Windows of Installeren op Linux. Binaire GStreamer-bestanden moeten zich in het systeempad, zodat de Speech SDK de binaire bestanden tijdens runtime kan laden. Als de Speech SDK Windows runtime kan vinden, betekent dit bijvoorbeeld dat de binaire GStreamer-bestanden zich in het systeempad libgstreamer-1.0-0.dll zijn.
Speech SDK kan GStreamer gebruiken om gecomprimeerde audio te verwerken. Om licentieredenen worden de binaire GStreamer-bestanden echter niet gecompileerd en gekoppeld aan de Speech SDK. Ontwikkelaars moeten verschillende afhankelijkheden en invoegingen installeren. Zie Installeren op Linux. Go-taal wordt alleen ondersteund in speech-SDK op het Linux-platform. Zie Speech SDK voor Go om aan de slag te gaan met de Microsoft Speech SDK in Go.
Voorbeeldcode met behulp van codec gecomprimeerde audio-invoer
Als u de Speech-SDK wilt configureren voor het accepteren van gecomprimeerde audio-invoer, maakt PullAudioInputStream u of PushAudioInputStream . Maak vervolgens een van AudioConfig een exemplaar van uw streamklasse en geef de compressieindeling van de stroom op. Zoek gerelateerde voorbeeldcodefragmenten in About the Speech SDK audio input stream API (Informatie over de audio-invoerstroom-API van de Speech SDK).
Stel dat u een invoerstroomklasse hebt met de naam pullStream en OPUS/OGG gebruikt. Uw code kan er als volgende uitzien:
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;
Als u de Speech-SDK wilt configureren voor het accepteren van gecomprimeerde audio-invoer, maakt PullAudioInputStream u of PushAudioInputStream . Maak vervolgens een van AudioConfig een exemplaar van uw streamklasse en geef de compressieindeling van de stroom op. Zoek gerelateerde voorbeeldcode in speech-SDK-voorbeelden.
Stel dat u een invoerstroomklasse hebt met de naam pushStream en OPUS/OGG gebruikt. Uw code kan er als volgende uitzien:
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;
Als u de Speech-SDK wilt configureren voor het accepteren van gecomprimeerde audio-invoer, maakt u PullAudioInputStream een of PushAudioInputStream . Maak vervolgens een van AudioConfig een exemplaar van uw streamklasse en geef de compressieindeling van de stroom op. Zoek gerelateerde voorbeeldcode in speech-SDK-voorbeelden.
Stel dat u een invoerstroomklasse hebt met de naam pullStream en OPUS/OGG gebruikt. Uw code kan er als volgende uitzien:
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();
Als u de spraak-SDK wilt configureren voor het accepteren van gecomprimeerde audio-invoer, maakt u PullAudioInputStream of PushAudioInputStream . Maak vervolgens een AudioConfig van een exemplaar van uw Stream-klasse, waarbij u de compressie-indeling van de stroom opgeeft.
We gaan ervan uit dat uw use-case moet worden gebruikt PullStream voor een MP3 bestand. Uw code kan er als volgt uitzien:
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)
Als u de Speech-SDK wilt configureren voor het accepteren van gecomprimeerde audio-invoer, maakt u PullAudioInputStream een of PushAudioInputStream . Maak vervolgens een van AudioConfig een exemplaar van uw streamklasse en geef de compressieindeling van de stroom op.
In het volgende voorbeeld gaan we ervan uit dat uw use-case is om te PushStream gebruiken voor een gecomprimeerd bestand.
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)
}