python-sounddevice
python-sounddevice copied to clipboard
sounddevice.PortAudioError : Error opening Stream : Device unavailable [PaErrorCode -9985]
I am trying to run a python script on boot using a systemd service on a Raspberry Pi4. The python script runs fine via the terminal, but flags a few errors (see attached image) when run via systemd. The python script opens an audio stream using the sounddevice library. I noticed that the device indexes are different when the python script is run via the terminal and via systemd. So I tried hardcoding the device index for the input stream, but that has not worked.
import sounddevice as sd
import numpy as np
import time
from pvrecorder import PvRecorder
import wave
import struct
import pydub
import requests
import uuid_utils as uuid
speaking_status = False
end = time.time() +10
start = time.time()
length = 0
timer = 0
Audio_file = "YOW.wav"
sound_threshold = 10
audio_timeout = 3
IATA_Code = "YOW"
devices = PvRecorder.get_available_devices()
print
for i in range(len(devices)):
print("index : %d, device name: %s" % (i, devices[i]))
sd.default.device = 2,1
print("SoundDevice Indexes:" + str(sd.query_devices()))
#print("SoundDevice Default Device:" + str(sd.default()))
recorder = PvRecorder(device_index = 12, frame_length=512)
print("Selected device:" + recorder.selected_device)
audio = []
def print_sound(indata, outdata, frames, t, status):
global start
global end
global length
global timer
global speaking_status
global Audio_file
global sound_threshold
global audio_timeout
i = 0
volume_norm = np.linalg.norm(indata)*10
#print(volume_norm)
if (volume_norm > sound_threshold and speaking_status==False):
print("Recording")
start = time.time()
speaking_status=True
recorder.start()
elif (volume_norm > sound_threshold and speaking_status==True):
start = time.time()
frame = recorder.read()
audio.extend(frame)
print("Volume:" + str(volume_norm))
else:
end = time.time()
timer = end-start
if (timer > audio_timeout and speaking_status==True):
recorder.stop()
speaking_status=False
print("Stop Recording Audio")
volume_norm = 0
headers = {
'Content-Type': 'application/json; charset=utf-8',
}
content_type = {
'Content-Type': 'audio/mpeg',
}
json_data = {
'query': {
'filename': Audio_mp3,
},
}
try:
with open(Audio_mp3, "rb") as file_data:
print("Uploading Audio File to AWS S3 Bucket")
put_response = requests.put(received_upload_link, data=file_data, headers=content_type)
print("HTTP Response:" + str(put_response.status_code))
except Exception as e:
print("An exception occured:", e)
with sd.Stream(callback=print_sound):
while True:
sd.sleep(1000)
Is it possible that PvRecorder takes over the input device and therefore makes it unavailable?
Could you try it with an OutputStream instead of a Stream?
Issue was the input devices do not have the same device index when the python script is running in the terminal or when it is running with systemd. A few print statements showed the differences in device indexes. Another approach that worked for me was to get the specific device ID for the device name and plug that into the PvRecorder initiation.