KoljaB / RealtimeSTT

A robust, efficient, low-latency speech-to-text library with advanced voice activity detection, wake word activation and instant transcription.
MIT License
1.59k stars 145 forks source link

Porcupine integration on Mac #76

Open bfrisco-raft opened 2 months ago

bfrisco-raft commented 2 months ago

It seems there are two errors happening, where a multiprocess can not be started but stemming from incompatible architecture where there is no other file to default to.

I searched pvporcupine and the dependancies required by they all mentioned containers.

I am only running the test code with the input index changed due to source has 0 as a invalid number of channels.

from RealtimeSTT import AudioToTextRecorder
import logging

if __name__ == '__main__':

    def recording_started():
        print("Speak now...")

    def recording_finished():
        print("Speech end detected... transcribing...")

    with AudioToTextRecorder(spinner=True,
                             language="en", level=logging.DEBUG, model="small.en", wake_words="jarvis",
                             on_wakeword_detected=recording_started, on_recording_stop=recording_finished,
                             input_device_index=1
        ) as recorder:
        print('Say "Jarvis" then speak.')
        print(recorder.text())
        print("Done. Now we should exit.")
RealTimeSTT: root - DEBUG - Explicitly setting the multiprocessing start method to 'spawn'
--- Logging error ---
Traceback (most recent call last):
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 398, in __init__
    mp.set_start_method('spawn')
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/context.py", line 243, in set_start_method
    raise RuntimeError('context has already been set')
RuntimeError: context has already been set

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 1083, in emit
    msg = self.format(record)
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 927, in format
    return fmt.format(record)
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 663, in format
    record.message = record.getMessage()
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 367, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "/Code/RealtimeSTT/tests/wakeword_test.py", line 12, in <module>
    with AudioToTextRecorder(spinner=True,
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 400, in __init__
    logging.debug("Start method has already been set. Details:", e)
Message: 'Start method has already been set. Details:'
Arguments: (RuntimeError('context has already been set'),)
--- Logging error ---
Traceback (most recent call last):
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 398, in __init__
    mp.set_start_method('spawn')
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/context.py", line 243, in set_start_method
    raise RuntimeError('context has already been set')
RuntimeError: context has already been set

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 1083, in emit
    msg = self.format(record)
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 927, in format
    return fmt.format(record)
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 663, in format
    record.message = record.getMessage()
  File "/.pyenv/versions/3.9.19/lib/python3.9/logging/__init__.py", line 367, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "/Code/RealtimeSTT/tests/wakeword_test.py", line 12, in <module>
    with AudioToTextRecorder(spinner=True,
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 400, in __init__
    logging.debug("Start method has already been set. Details:", e)
Message: 'Start method has already been set. Details:'
Arguments: (RuntimeError('context has already been set'),)
RealTimeSTT: root - INFO - Starting RealTimeSTT
RealTimeSTT: root - INFO - Initializing audio recording (creating pyAudio input stream, sample rate: 16000 buffer size: 512
RealTimeSTT: root - ERROR - Error initializing porcupine wake word detection engine: dlopen(/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib, 0x0006): tried: '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (no such file), '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
Traceback (most recent call last):
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 481, in __init__
    self.porcupine = pvporcupine.create(
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/__init__.py", line 64, in create
    return Porcupine(
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/porcupine.py", line 60, in __init__
    library = cdll.LoadLibrary(library_path)
  File "/.pyenv/versions/3.9.19/lib/python3.9/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "/.pyenv/versions/3.9.19/lib/python3.9/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib, 0x0006): tried: '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (no such file), '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
Traceback (most recent call last):
  File "/Code/RealtimeSTT/tests/wakeword_test.py", line 12, in <module>
    with AudioToTextRecorder(spinner=True,
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/RealtimeSTT/audio_recorder.py", line 481, in __init__
    self.porcupine = pvporcupine.create(
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/__init__.py", line 64, in create
    return Porcupine(
  File "/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/porcupine.py", line 60, in __init__
    library = cdll.LoadLibrary(library_path)
  File "/.pyenv/versions/3.9.19/lib/python3.9/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "/.pyenv/versions/3.9.19/lib/python3.9/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib, 0x0006): tried: '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (no such file), '/.pyenv/versions/3.9.19/envs/transcriber/lib/python3.9/site-packages/pvporcupine/lib/mac/x86_64/libpv_porcupine.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/synchronize.py", line 110, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
  File "/.pyenv/versions/3.9.19/lib/python3.9/multiprocessing/synchronize.py", line 110, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
FileNotFoundError: [Errno 2] No such file or directory
bfrisco-raft commented 2 months ago

Multiprocess Issue found here: https://github.com/python/cpython/issues/94765

The above solution involves using fork,

If "spawn" is needed under mp.set_start_method: https://github.com/mherrmann/fbs/issues/87#issuecomment-471489980

However, if pvprocupine can be updated this pay be solved as well with version 3.0.2.