KeywordRecognizer | Python | macOS: stop_recognition_async() does not work
See original GitHub issueDescribe the bug
Calling stop_recognition_async()
after recognize_once_async()
does not appear to work correctly.
- It takes about 10 seconds to do whatever it is it does.
- The
canceled
callback do not run as a result of invoking it. get()
on theResultFuture
returned byrecognize_once_async()
blocks forever.
To Reproduce Steps to reproduce the behavior:
- Run the below proof of concept
import azure.cognitiveservices.speech as speechsdk
import time
def speech_recognize_keyword_locally_from_microphone():
"""runs keyword spotting locally, with direct access to the result audio"""
# Creates an instance of a keyword recognition model. Update this to
# point to the location of your keyword recognition model.
model = speechsdk.KeywordRecognitionModel("YourKeywordRecognitionModelFile.table")
# The phrase your keyword recognition model triggers on.
keyword = "YourKeyword"
# Create a local keyword recognizer with the default microphone device for input.
keyword_recognizer = speechsdk.KeywordRecognizer()
done = False
def recognized_cb(evt):
# Only a keyword phrase is recognized. The result cannot be 'NoMatch'
# and there is no timeout. The recognizer runs until a keyword phrase
# is detected or recognition is canceled (by stop_recognition_async()
# or due to the end of an input file or stream).
result = evt.result
if result.reason == speechsdk.ResultReason.RecognizedKeyword:
print("RECOGNIZED KEYWORD: {}".format(result.text))
nonlocal done
done = True
def canceled_cb(evt):
result = evt.result
if result.reason == speechsdk.ResultReason.Canceled:
print("CANCELED: {}".format(result.cancellation_details.reason))
nonlocal done
done = True
# Connect callbacks to the events fired by the keyword recognizer.
keyword_recognizer.recognized.connect(recognized_cb)
keyword_recognizer.canceled.connect(canceled_cb)
# Start keyword recognition.
result_future = keyword_recognizer.recognize_once_async(model)
print(
'Say something starting with "{}" followed by whatever you want...'.format(
keyword
)
)
# If active keyword recognition needs to be stopped before results, it can be done with
#
stop_future = keyword_recognizer.stop_recognition_async()
print(f"{time.monotonic()} Stopping...")
stopped = stop_future.get()
print(f"{time.monotonic()} Stopped")
result = result_future.get()
print(f"{time.monotonic()} Done")
# Read result audio (incl. the keyword).
if result.reason == speechsdk.ResultReason.RecognizedKeyword:
time.sleep(2) # give some time so the stream is filled
result_stream = speechsdk.AudioDataStream(result)
result_stream.detach_input() # stop any more data from input getting to the stream
save_future = result_stream.save_to_wav_file_async(
"AudioFromRecognizedKeyword.wav"
)
print("Saving file...")
saved = save_future.get()
else:
result_stream = speechsdk.AudioDataStream(result)
result_stream.detach_input()
if __name__ == "__main__":
speech_recognize_keyword_locally_from_microphone()
Expected behavior
The canceled
callbacks are called, get()
on the future returned by recognize_once_async()
returns a result indicating cancellation, and get()
on the future returned by stop_recognition_async()
returns almost immediately.
Version of the Cognitive Services Speech SDK 1.16.0
Platform, Operating System, and Programming Language
- OS: macOS Big Sur 11.2.3.
- Hardware: x64
- Programming language: Python
- Browser: N/A
Additional context
I’m assuming that get()
on the future returned by recognize_once_async()
should still return after stopping because the documentation says “A future that is fulfilled once recognition has been initialized.” “Initialized” doesn’t seem to require successful recognition, which leads me to infer that it should still return on cancellation.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (5 by maintainers)
Top GitHub Comments
reopening and labeling it as accepted so @CtrlZvi gets notified when we resolve this after we fix this bug.
Closed as the Speech SDK 1.24.0 has been released.