Pyaudio client end (using microphone user)

We’ve also updated how to work with javascript in python.
And - recently we’ve added a method to help with this type of task. anvil.js.to_media()

To use client side audio/video it’s usually necessary to work with the browser api.
Trying to get a sense of what’s required from MDN examples can help.

Steps:

  1. get the media stream with navigator.mediaDevices.getUserMedia
  2. create a media recorder from the stream
  3. start the media recorder
  4. stop the media recorder
  5. use a python callback - when data (as bytes) is available append it to a list
  6. use a python callback - when you stop recording convert the data to a media object with anvil.js.to_media()

Here’s a clone with a record and stop button that then downloads the audio recorded from the device.
(You could send the media object to the server instead)
https://anvil.works/build#clone:IT3K7PDMJVXPT33R=JUO5SOJ5NG7OR7GGIPKTUTIC

And the code
from anvil.js.window import navigator, MediaRecorder
import anvil.js

class Form1(Form1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    self.stream = self.get_stream()
    self.media_recorder = MediaRecorder(self.stream)
    self.chunks = []
    self.media_recorder.ondataavailable = self.on_data_available
    self.media_recorder.onstop = self.on_stop
    # Any code you write here will run when the form opens.

  def record_button_click(self, **event_args):
    """This method is called when the button is clicked"""
    state = self.media_recorder.state
    print(state)
    
    if state == 'inactive':
      self.media_recorder.start()
      self.record_button.icon = 'fa:stop'
      self.record_button.text = 'Stop'
      self.record_button.role = 'secondary-color'
    else:
      self.media_recorder.stop()
      self.record_button.icon = 'fa:microphone'
      self.record_button.text = 'Record'
      self.record_button.role = 'primary-color'

  def get_stream(self):
    if navigator.mediaDevices and navigator.mediaDevices.getUserMedia:
      print('getUserMedia supported')
      return navigator.mediaDevices.getUserMedia({"audio": True})
    else:
      alert('media recording not supported')
  
  def on_data_available(self, e):
    self.chunks.append(e.data)
  
  def on_stop(self, e):
    media = anvil.js.to_media(self.chunks, name="recording")
    self.chunks = []
    download(media)
6 Likes