SoFunction
Updated on 2024-11-07

Example of python recording system sound

environmental preparation

python

  • wave
  • pyaudio

wave can be installed directly via pip. When installing pyaudio, direct installation via normal pip install was always in the error stage, then I thought I could install it directly via wheel.

There is a corresponding installer in the pypi package, note that not only the difference between python2 and python3, but also the minor version of python3 is a bit different. But what I have is python3.8 installed in my computer, and then I thought there is a website where I can install pythonlibs, so I found the corresponding version and downloaded it. Install it directly in the directory where the file is located, or in the directory specified in the installation.

pip install /c/Users/root/Downloads/PyAudio-0.2.11-cp38-cp38-win_amd64.whl

Code and Run

def audio_record(out_file, rec_time):
  CHUNK = 1024
  FORMAT = pyaudio.paInt16 # 16bit encoding format
  CHANNELS = 1 # Mono
  RATE = 16000 # 16000 sampling frequency
  p = ()
  # Create audio streams
  dev_idx = findInternalRecordingDevice(p)
  stream = (format=FORMAT, # Audio streaming wav format
          channels=CHANNELS, # Mono
          rate=RATE, # Sampling rate 16000
          input=True,
          input_device_index=dev_idx, # Specify the id of the internal recording device, you can leave it out, use win's default recording device
          frames_per_buffer=CHUNK)
  print("Start Recording...")
  frames = [] # Recorded audio streams
  # Record audio data
  for i in range(0, int(RATE / CHUNK * rec_time)): # Control the recording time
    data = (CHUNK)
    (data)
  # Recording is complete
  stream.stop_stream()
  ()
  ()
  print("Recording Done...")
  # Save audio files
  wf = (out_file, 'wb')
  (CHANNELS)
  (p.get_sample_size(FORMAT))
  (RATE)
  (b''.join(frames))
  ()

When I was using the default recording device, I realized that it was microphone recording, which wasn't working too well, so I checked to see if I could record directly to the system.

def findInternalRecordingDevice(p):
  # Keywords in the name of the device to be searched for
  target = 'Stereo Mixing'
  # Find sound devices one by one
  for i in range(p.get_device_count()):
    devInfo = p.get_device_info_by_index(i)
    print(devInfo)
    if devInfo['name'].find(target) >= 0 and devInfo['hostApi'] == 0:
      # print('Internal recording device found, serial number is ',i)
      return i
  print('Unable to find internal recording device!')
  return -1

You can use p.get_device_info_by_index() to see the system devices related to sound, and you can record the system sound by setting it to stereo mixing.

Save sound

def save(fileName):
  # Create the pyAudio object
  p = ()
  # Open the file used to save the data
  wf = (fileName, 'wb')
  # Setting audio parameters
  (CHANNELS)
  (p.get_sample_size(FORMAT))
  (RATE)
  # Write data
  (b''.join(_frames))
  # Close the file
  ()
  # End pyaudio
  ()

Saving the sound is done with the above code, where _frames is a list that is added to every chunk (data stream chunk) that is recorded.

Then it's just a matter of recreating the PyAudio object, converting the list to a byte string and saving it to a file

concern

The above generally allows you to record the system sound, but when performing it, you find that it doesn't.

Reason: Stereo mixing is not configured in Win's input devices

Setup Steps:

  • Right click on Win's Sound Adjustment to open Sound Settings.
  • Find Manage Sound Devices
  • Enable stereo mixing at the input device

This completes the need to record the system's sound.

take note of

With the above operation, it can be played externally and 3.5mm headphones can be plugged in, but the system is muted and the sound cannot be recorded when tpye-c headphones are plugged in

Full Code

import os
import pyaudio
import threading
import wave
import time
from datetime import datetime

# Requires the system to turn on stereo mixing

# Recording class
class Recorder():
  def __init__(self, chunk=1024, channels=2, rate=44100):
     = chunk
     = pyaudio.paInt16
     = channels
     = rate
    self._running = True
    self._frames = []

  # Get the serial number of the internal recording device, tested on windows operating system, hostAPI = 0 indicates that it is an MME device.
  def findInternalRecordingDevice(self, p):
    # Keywords in the name of the device to be searched for
    target = 'Stereo Mixing'
    # Find sound devices one by one
    for i in range(p.get_device_count()):
      devInfo = p.get_device_info_by_index(i)
      # print(devInfo)
      if devInfo['name'].find(target) >= 0 and devInfo['hostApi'] == 0:
        # print('Internal recording device found, serial number is ',i)
        return i
    print('Unable to find internal recording device!')
    return -1

  # Start recording, open a new thread for recording operations
  def start(self):
    threading._start_new_thread(self.__record, ())

  # Threaded functions that perform recordings
  def __record(self):
    self._running = True
    self._frames = []

    p = ()
    # Find internal recording devices
    dev_idx = (p)
    if dev_idx < 0:
      return
    # Specify the input device when opening an input stream
    stream = (input_device_index=dev_idx,
            format=,
            channels=,
            rate=,
            input=True,
            frames_per_buffer=)
    # Loop through the input stream
    while (self._running):
      data = ()
      self._frames.append(data)

    # Stop reading the input stream
    stream.stop_stream()
    # Close the input stream
    ()
    # End pyaudio
    ()
    return

  # Stop recording
  def stop(self):
    self._running = False

  # Save to file
  def save(self, fileName):
    # Create the pyAudio object
    p = ()
    # Open the file used to save the data
    wf = (fileName, 'wb')
    # Setting audio parameters
    ()
    (p.get_sample_size())
    ()
    # Write data
    (b''.join(self._frames))
    # Close the file
    ()
    # End pyaudio
    ()


if __name__ == "__main__":

  # Detect if there is a record subdirectory in the current directory
  if not ('record'):
    ('record')

  print("\npython recorder .... \n")
  print("Hint: Press r and enter to start recording\n")

  i = input('Please enter the operation code:')
  if i == 'r':
    rec = Recorder()
    begin = ()

    print("\n Start recording, press s and enter to stop recording, auto save to record subdirectory\n")
    ()

    running = True
    while running:
      i = input("Please enter the operation code:")
      if i == 's':
        running = False
        print("Recording has stopped.")
        ()
        t = () - begin
        print('Recording time is %ds' % t)
        # Save wav file with current time as keyword
        ("record/rec_" + ().strftime("%Y-%m-%d_%H-%M-%S") + ".wav")

The above is the details of python record system sound example, more information about python record system sound please pay attention to my other related articles!