I can't seem to get my code to work. I would like to be able to live stream sound with python to another computer, and my code just quits on windows. How would I be able to fix this?
dev box: Linux Mint 20 64-bit
test computer: Windows 10
I am using pyaudio to record sound and while it is recording, send it to another computer. I am getting no audio output and both windows & linux will just randomly stall the application.
Linux errors:
starting
IP address: 192.168.0.11
Port: 65535
Send IP: 192.168.0.10
Send Port: 65535
threads starting
--- starting stream ---
sending data to: 192.168.0.10:65534
--- starting receive ---
--- THREAD RECEIVE:
got connection from: 192.168.0.10
---
ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/home/henrik/PycharmProjects/AudioChat/main.py", line 51, in play
data = ps.recv(64 * 2 * 2) # var #1: chunk; var #2: channels; var #3: just to have a safe overhead
OSError: [Errno 107] Transport endpoint is not connected
Alsa errors I think are fine, don't they just point to no mic?
windows errors:
starting
IP address: 192.168.0.10
Port: 65534
Send IP: 192.168.0.11
Send Port: 65535
threads starting
--- starting stream ---
sending data to: 192.168.0.11:65535
--- starting receive ---
Exception in thread Thread-1:
Traceback (most recent call last):
File "E:\installers&apps\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "E:\installers&apps\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "E:\main.py", line 35, in record
rs.send(data) # send the sound to the send_to_ip
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
from the errors it seems that the code connected to Linux, but connection was aborted, while Linux tried connecting to windows and timed out. Linux also thinks that the connection was aborted. why would that be?
my code:
#!/usr/bin/python3
# Python Audio Server for realtime audio.
import threading, socket, pyaudio, time # import all needed codes
from tkinter import *
def startThreads(send_ip, send_to_ip, kill_event): # function to start threads
print("IP address:\t"+send_ip[0]+"\nPort:\t\t"+str(send_ip[1])) # print ip address and port
print("Send IP:\t"+send_to_ip[0]+"\nSend Port:\t"+str(send_ip[1])+"\n") # print the second address set
print("threads starting")
r_thread = threading.Thread(target=record, args=(send_to_ip, kill_event)) # create threads
p_thread = threading.Thread(target=play, args=(send_ip, kill_event))
r_thread.start() # start threads
p_thread.start()
def record(send_to_ip, kill_event): # the r_thread function
print("--- starting stream ---")
print("sending data to: "+send_to_ip[0]+":"+str(send_to_ip[1])) # print ip address and port yet again
rs = socket.socket() # start socket
rs.connect((send_to_ip[0], int(send_to_ip[1])))
# todo: figure out why linux times out connecting to windows & windows aborts connecting to linux
# I believe below code will work?
rp = pyaudio.PyAudio() # start pyaudio
chunk = 64 # pyaudio config
sample_format = pyaudio.paInt16
channels = 2
fs = 44100
rtime = 3600
while not kill_event.wait(0):
rstream = rp.open(format=sample_format, channels=channels, rate=fs, frames_per_buffer=chunk, input=True) # start recording
for i in range(0, int(fs / chunk * rtime)): # record sounds
data = rstream.read(chunk) # read sound data
rs.send(data) # send the sound to the send_to_ip
rstream.stop_stream() # stop recording, then loop
rstream.close()
rp.terminate()
def play(send_ip, kill_event): # the p_thread function
print("--- starting receive ---") # working client code
ps = socket.socket()
ps.bind((send_ip[0], int(send_ip[1]))) # todo: figure out why linux times out connecting to windows & windows aborts connecting to linux
ps.listen(1)
connection, addr = ps.accept()
print("--- THREAD RECEIVE:\n\tgot connection from: "+addr[0]+"\n---")
pp = pyaudio.PyAudio() # start pyaudio
stream = pp.open(format=pyaudio.paInt16, channels=2, rate=44100, frames_per_buffer=64, output=True) # open play sound
while not kill_event.wait(0):
data = ps.recv(64 * 2 * 2) # var #1: chunk; var #2: channels; var #3: just to have a safe overhead
stream.write(data, 64)
if __name__ == "__main__":
print("starting")
kill_event = threading.Event()
UI = Tk() # creating UI
UI.title("Audio Connect") # set window title
UI.configure(bg="#FFF") # set window color
UI.resizable(False, False) # stop window from being able to resize
# this block of code is the title and IP field
TitleLabel = Label(UI, text="Audio Connect", bg="white").grid(column=0, columnspan=2, padx=1, pady=1) # the title label
Label(UI, text="IP: ", bg="white", bd=1).grid(row=1, column=0, padx=1, pady=1) # IP fields
IPField = Entry(UI, bd=1) # IP entry
IPField.grid(row=1, column=1, padx=1, pady=1) # write the ip entry to the screen
# this block of code is the Port field
Label(UI, text="PORT: ", bg="white", bd=1).grid(row=2, column=0, padx=1, pady=1) # port fields
PortField = Entry(UI, text="65535", bd=1) # port entry
PortField.grid(row=2, column=1, padx=1, pady=1) # draw the port entry
# this is the connect to section, IP
Label(UI, text="Send To IP: ", bg="white", bd=1).grid(row=3, column=0, padx=1, pady=1)
SendIP = Entry(UI, bd=1)
SendIP.grid(row=3, column=1, padx=1, pady=1)
# connect to port
Label(UI, text="Port: ", bg="white", bd=1).grid(row=4, column=0, padx=1, pady=1)
SendPort = Entry(UI, bd=1)
SendPort.grid(row=4, column=1, padx=1, pady=1)
# this block of code is the connect button and the scripts for that
lambdafunc = lambda: startThreads((IPField.get(), int(PortField.get())), (SendIP.get(), SendPort.get()), kill_event) # the function to run when ConnectButton is pressed
ConnectButton = Button(UI, text="connect", bg="white", bd=1, relief="solid", command=lambdafunc)\
.grid(row=5, column=0, columnspan=2, sticky="EW", padx=1, pady=1)
UI.mainloop()
kill_event.set()
time.sleep(1)
exit(0)
Feel free to play around with it! Also, am I sending the audio correctly?
summary:
trying to send audio from one computer to another:
windows connects to linux. Connection gets aborted????
linux tries connecting to windows... connection timed out???
There wasn't any problem with the connection getting aborted, but rather a problem with how I was receiving sound.
In my play thread, in the while loop, I changed my first line of code from data = ps.recv(64 * 2 *2)
I needed to put data = connection.recv(64 * 2 * 2)
instead. That fixed my problem, and now I just need to learn some more audio coding, because now I get "alsa underrun" errors.