Проблемы со звуком Python через сеть - PullRequest
2 голосов
/ 11 октября 2011

Здравствуйте. У меня проблемы с передачей звука по сети.В моей локальной системе без расстояния нет проблем, но всякий раз, когда я тестирую на удаленной системе, есть звук, но это не голосовой ввод, я хочу его прерывистый / медленный и т. Д. Я верю в то, как я справляюсь с отправкой аудио, ноЯ пытался в течение 4 дней и не могу найти решение.

Я опубликую весь соответствующий код и постараюсь объяснить его как можно лучше

это постоянные / глобальные значения


    #initilaize Speex
    speex_enc = speex.Encoder()
    speex_enc.initialize(speex.SPEEX_MODEID_WB)
    speex_dec = speex.Decoder()
    speex_dec.initialize(speex.SPEEX_MODEID_WB)

    #some constant values
    chunk = 320
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 44100

Я обнаружил, что настройка значения частоты дискретизации позволит увеличить шум

Ниже приведен код pyAudio для инициализации аудиоустройства, это также глобально


    #initalize PyAudio
    p = pyaudio.PyAudio()
    stream = p.open(format = FORMAT,
                    channels = CHANNELS,
                    rate = RATE,
                    input = True,
                    output = True,
                    frames_per_buffer = chunk)

Это следующееФункция - это функция нажатия клавиш, которая записывает данные с микрофона и отправляет их с помощью функции клиента. Здесь я считаю, что у меня возникли проблемы.

Я считаю, что проблема заключается в том, как я справляюсь с этим, потому что, если я нажимаю и удерживаю, чтобы получить аудио, он зацикливается и отправляется на каждой итерации.Я не уверен, что делать здесь.(Идеи !!!)


    def keypress(event):
        #chunklist = []
        #RECORD_SECONDS = 5
        if event.keysym == 'Escape':
            root.destroy()
        #x = event.char
        if event.keysym == 'Control_L':   
            #for i in range(0, 44100 / chunk * RECORD_SECONDS):
            try:
                #get data from mic
                data = stream.read(chunk)
            except IOError as ex:
                if ex[1] != pyaudio.paInputOverflowed:
                    raise
                data = '\x00' * chunk
            encdata = speex_enc.encode(data)        #Encode the data.
            #chunklist.append(encdata)
            #send audio
            client(chr(CMD_AUDIO), encrypt_my_audio_message(encdata))

Серверный код для обработки аудио


    ### Server function ###
    def server():
        PORT = 9001
        ### Initialize socket 
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind((socket.gethostbyname(socket.gethostname()), PORT))
        # socket.gethostbyname(socket.gethostname())
        server_socket.listen(5)
        read_list = [server_socket]
        ### Start receive loop
        while True:
            readable, writable, errored = select.select(read_list, [], [])
            for s in readable:
                if s is server_socket:
                    conn, addr = s.accept()
                    read_list.append(conn)
                    print "Connection from ", addr
                else:
                    msg = conn.recv(2048)
                    if msg:                
                        cmd, msg = ord(msg[0]),msg[1:]
                        ## get a text message from GUI
                        if cmd == CMD_MSG:
                            listb1.insert(END, decrypt_my_message(msg).strip() + "\n")
                            listb1.yview(END)
                        ## get an audio message
                        elif cmd == CMD_AUDIO:
                            # make sure length is 16 --- HACK ---
                            if len(msg) % 16 != 0:
                                msg += '\x00' * (16 - len(msg) % 16)
                            #decrypt audio
                            data = decrypt_my_message(msg)
                            decdata = speex_dec.decode(data)
                            #Write the data back out to the speaker
                            stream.write(decdata, chunk)
                    else:
                        s.close()
                        read_list.remove(s)

и для завершения привязки клавиатуры в Tkinter


    root.bind_all('', keypress)

Мы очень ценим любые идеи, как я могу заставить этот метод нажатия клавиш работать по мере необходимости или предлагать лучший способ, или, возможно, я делаю что-то не так в целом

* ура

Обратите внимание, что я проверил его безметоды шифрования тоже и тоже самое: -)

1 Ответ

0 голосов
/ 27 октября 2012

Запускали ли вы ping или ttcp для проверки производительности сети между двумя хостами?

Если у вас есть пики задержки или если отброшены некоторые пакеты, ваш подход к отправке голосового потока сильно пострадает.TCP будет ожидать пропущенного пакета, сообщать о его потере, ждать повторной передачи и т. Д.

Вы должны использовать UDP-соединение с потерями и сжатие звука, которое корректно обрабатывает пропущенные пакеты.Также в этом случае вы должны пометить время отправления исходящих пакетов.

...