pythonwebsocketpython-asynciopyaudio

Start and stop audio streaming using http or mqtt calls - Python


I have a python script that streams audio. It uses websockets, asyncio and pyaudio. I want to start and stop streaming or this complete script with HTTP or MQTT call. Currently what I am doing manually i.e. To Start : python script.py To Stop : Ctrl C

What approach shall I use?

# starts recording
stream = p.open(
   format=FORMAT,
   channels=CHANNELS,
   rate=RATE,
   input=True,
   frames_per_buffer=FRAMES_PER_BUFFER
)

async def send_receive():
   print(f'Connecting websocket to url ${URL}')
   async with websockets.connect(
       URL,
       extra_headers=(("Authorization", auth_key),),
       ping_interval=5,
       ping_timeout=20
   ) as _ws:
       await asyncio.sleep(0.1)
       print("Receiving SessionBegins ...")
       session_begins = await _ws.recv()
       print(session_begins)
       print("Sending messages ...")
       async def send():
           while True:
               try:
                   data = stream.read(FRAMES_PER_BUFFER)
                   data = base64.b64encode(data).decode("utf-8")
                   json_data = json.dumps({"audio_data":str(data)})
                   await _ws.send(json_data)
               except websockets.exceptions.ConnectionClosedError as e:
                   print(e)
                   assert e.code == 4008
                   break
               except Exception as e:
                   assert False, "Not a websocket 4008 error"
               await asyncio.sleep(0.01)

           return True

       async def receive():
           while True:
               try:
                   result_str = await _ws.recv()
                   print(json.loads(result_str)['text'])
               except websockets.exceptions.ConnectionClosedError as e:
                   print(e)
                   assert e.code == 4008
                   break
               except Exception as e:
                   assert False, "Not a websocket 4008 error"

       send_result, receive_result = await asyncio.gather(send(), receive())


asyncio.run(send_receive())

Solution

  • To start and stop a Python script using an HTTP call, you can set up a web server that listens for specific requests to trigger the execution or termination of your script. Here's a basic example using the Flask framework:

    Install Flask:

    pip install flask
    

    Create a new Python file, e.g., script_controller.py, and import the necessary modules:

    from flask import Flask, request
    import subprocess
    
    app = Flask(__name__)
    process = None
    

    Define route handlers for starting and stopping the script:

    @app.route('/start_script', methods=['POST'])
    def start_script():
        global process
        if process is None or process.poll() is not None:
            # Start the script if it's not already running
            process = subprocess.Popen(['python', 'your_script.py'])
            return 'Script started successfully.'
        else:
            return 'Script is already running.'
    
    @app.route('/stop_script', methods=['POST'])
    def stop_script():
        global process
        if process and process.poll() is None:
            # Terminate the script if it's running
            process.terminate()
            return 'Script stopped successfully.'
        else:
            return 'Script is not running.'
    
    if __name__ == '__main__':
        app.run()
    

    Replace 'your_script.py' in the start_script route handler with the filename of the script you want to execute.

    Start the web server by running the script_controller.py file:

    python script_controller.py
    

    Once the server is running, you can send HTTP requests to start or stop the script:

    To start the script:

    POST http://localhost:5000/start_script
    

    To stop the script:

    POST http://localhost:5000/stop_script