turns-00025.parquet:4214
b67db6190b5aac5c3982ffd5
turn 6/8gpt-4o-2024-05-13RussianRussia2344 words
degenerate_repetitionAbsentFinal dense release
USER
Перепиши программу, повышая производительность и улучшая код
import pyaudio
import RPi.GPIO as GPIO
import numpy as np
import json
import multiprocessing
from multiprocessing import Queue, Process
import vosk
import collections.abc
collections.MutableMapping = collections.abc.MutableMapping
import cv2
from cv2 import aruco
import time
import fuzzywuzzy
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import noisereduce as nr
import wave
def forward():
print('едем вперед')
RC1 = 1500
RC3 = 1800
return RC1, RC3
def back():
print('едем назад')
RC1 = 1500
RC3 = 1200
return RC1, RC3
def stop():
print('остановка')
RC1 = 1500
RC3 = 1500
return RC1, RC3
def right():
print('направо')
RC1 = 1900
RC3 = 1500
return RC1, RC3
def left():
print('налево')
RC1 = 1100
RC3 = 1500
return RC1, RC3
def around():
print('кругом')
RC1 = 1100
RC3 = 1500
return RC1, RC3
def faster():
print('быстрее')
RC1 = 1500
RC3 = 2000
return RC1, RC3
def slower():
print('медленее')
RC1 = 1500
RC3 = 1600
return RC1, RC3
def to_me():
print('ко мне')
def convert_command(RC1, RC3):
RTrack = int(max(min(((RC3 - 1500) / 5 + (RC1 - 1500) / 5), 100), -100))
LTrack = int(max(min(((RC3 - 1500) / 5 - (RC1 - 1500) / 5), 100), -100))
return LTrack, RTrack
def send_command(RC1, RC3, pwmOutput_left, pwmOutput_right):
LTrack, RTrack = convert_command(RC1, RC3)
print('LTrack: ', LTrack, 'RTrack: ', RTrack)
# ~ time.sleep(0.1)
if LTrack < 0:
GPIO.output(GPIO_rev_left, GPIO.LOW)
else:
GPIO.output(GPIO_rev_left, GPIO.HIGH)
if RTrack < 0:
GPIO.output(GPIO_rev_right, GPIO.HIGH)
else:
GPIO.output(GPIO_rev_right, GPIO.LOW)
pwmOutput_left.ChangeDutyCycle(abs(LTrack))
pwmOutput_right.ChangeDutyCycle(abs(RTrack))
def find_keywords(sentence, keywords):
# функция распознования ключевых слов
words = sentence.split()
found_keywords = {}
for keyword in keywords:
best_match, score = process.extractOne(keyword, words, scorer=fuzz.ratio)
if score > 60: # Порог схожести, можно настроить
found_keywords[best_match] = keyword
return found_keywords
def mode_selection(*args):
# выбор режима исходя из голосовой команды, формирует RC1, RC3
names = {'юл': 1, 'юр': 2, 'жук': 3, 'жоп': 4, 'жёг': 5, 'жег': 6, 'звук': 7, 'юлить': 8, 'или': 9, 'юле': 10}
mod_word = {'ред': 'ямо', 'рёд': 'ямо', 'отстав': 'сто', 'кам': 'ко', 'ям': 'ямо', 'лева': 'лев', 'лёв': 'лев',
'дело': 'лев'}
funcs = {'ямо': 'forward', 'сто': 'stop', 'зад': 'back', 'прав': 'right',
'лев': 'left', 'быст': 'faster', 'медл': 'slower', 'ко': 'to_me', 'круг': 'around'}
name = args[0][0]
act = args[0][1]
act = mod_word.get(act, act)
if names.get(name) is not None:
return funcs[act]
def calc_distance(cam_mat, dist_coef, marker_corners, i):
MARKER_SIZE = 5
rVec, tVec, _ = aruco.estimatePoseSingleMarkers(marker_corners, MARKER_SIZE, cam_mat, dist_coef)
distance = np.sqrt(tVec[i][0][2] ** 2 + tVec[i][0][0] ** 2 + tVec[i][0][1] ** 2)
return distance
def update_rc_values(width, framecenterx, framecentery, centerx, centery, distance):
znak = 1
k_max_speed = 0.8
k_max_speed_rotate = 0.75
k_width_searc = width / 4
k_speed_cam = 50
ofset_distance = 100
stop_distance = 20
modRC3 = 1500 + int((max(min(distance - ofset_distance, stop_distance), -stop_distance)) * (100 / stop_distance) * (
k_max_speed * 5))
if 1350 < modRC3 < 1650: modRC3 = 1500
if modRC3 >= 1500: znak = -1
modRC1 = 1500 + znak * int(
(max(min(framecenterx - centerx, k_width_searc), -k_width_searc)) * (100 / k_width_searc) * (
k_max_speed_rotate * 5))
if 1400 < modRC1 < 1600: modRC1 = 1500
return modRC1, modRC3
def video(queueVideo, queueFlag):
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 540)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 960)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
marker_dict = aruco.getPredefinedDictionary(aruco.DICT_5X5_50)
param_markers = aruco.DetectorParameters()
detector = aruco.ArucoDetector(dictionary=marker_dict, detectorParams=param_markers)
calib_data_path = r"//home/zhuk/Desktop/CAMERA/zvuk/dist/Distance Estimation/MultiMatrix.npz"
calib_data = np.load(calib_data_path)
cam_mat = calib_data["camMatrix"]
dist_coef = calib_data["distCoef"]
flag_detected_early = False
while True:
print('flag_detected_early = ', flag_detected_early)
_, frame = cap.read()
# ~ frame = cv2.rotate(frame, cv2.ROTATE_180)
grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
grayblurredframe = cv2.GaussianBlur(grayframe, (5, 5), 0)
grayblurredframe = np.expand_dims(grayblurredframe, axis=2)
grayblurredframe = np.append(grayblurredframe, grayblurredframe, axis=2)
grayblurredframe = np.append(grayblurredframe, grayblurredframe, axis=2)
framecenterx = width / 2
framecentery = height / 2
sqrmax = int((width / 5) ** 2)
sqrmin = int((width / 10) ** 2)
cv2.imshow("frame", grayframe)
cv2.waitKey(1)
try:
flag = queueFlag.get()
if flag:
marker_corners, markers_IDs, reject = detector.detectMarkers(grayblurredframe)
if marker_corners:
total_markers = range(0, markers_IDs.size)
for ids, corners, i in zip(markers_IDs, marker_corners, total_markers):
distance = calc_distance(cam_mat, dist_coef, marker_corners, i)
print('distance = ', distance)
if markers_IDs[0][0] == 0:
flag_detected_early = True
centerx = marker_corners[0][0][0][0] + (marker_corners[0][0][2][0] - marker_corners[0][0][0][0]) / 2
centery = marker_corners[0][0][0][1] + (marker_corners[0][0][2][1] - marker_corners[0][0][0][1]) / 2
corners = corners.reshape(4, 2)
corners = corners.astype(int)
top_right = corners[2].ravel()
cv2.polylines(grayframe, [corners.astype(np.int32)], True, (0, 255, 255), 4, cv2.LINE_AA)
cv2.putText(grayframe, f"id: {ids[0]}", top_right, cv2.FONT_HERSHEY_PLAIN, 1.3,
(0, 255, 0), 2, cv2.LINE_AA)
cv2.circle(grayframe, (int(centerx), int(centery)), radius=2, color=(255, 0, 0),
thickness=-1)
print('markers_IDs = ', markers_IDs)
RC1, RC3 = update_rc_values(width, framecenterx, framecentery,
centerx, centery, distance)
else:
if flag_detected_early:
RC1 = 1700
RC3 = 1500
else:
RC1 = 1500
RC3 = 1500
else:
if not flag_detected_early:
RC1 = 1700
RC3 = 1500
else:
RC1 = 1500
RC3 = 1500
else:
if not flag_detected_early:
RC1 = 1700
RC3 = 1500
else:
RC1 = 1500
RC3 = 1500
queueVideo.put([RC1, RC3])
except:
continue
if __name__ == '__main__':
GPIO_PWM_left = 12
GPIO_PWM_right = 13
GPIO_rev_left = 16
GPIO_rev_right = 6
WORK_TIME = 0.1
DUTY_CYCLE = 0 # min - 40
FREQUENCY = 7250
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 8000
model = vosk.Model('./vosk-model-small-ru-0.4')
recognizer = vosk.KaldiRecognizer(model, RATE)
frames = []
input_frames = []
text = 'empty'
action = None
RC1, RC3 = None, None
keywords = ['юл', 'юр', 'юлить', 'юле', 'жук', 'звук', 'жоп', 'жёг', 'жег', 'ямо', 'ред', 'рёд', 'сто', 'отстав', 'прав',
'лев', 'зад', 'быст', 'медл', 'ко', 'кам', 'круг', 'дело', 'или']
funcs = ['forward', 'stop', 'back', 'right', 'left', 'faster', 'slower', 'around']
functions = {'forward': forward, 'stop': stop, 'back': back, 'right': right,
'left': left, 'faster': faster, 'slower': slower, 'around': around}
localFlag = False
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_rev_left, GPIO.OUT)
GPIO.setup(GPIO_rev_right, GPIO.OUT)
GPIO.setup(GPIO_PWM_left, GPIO.OUT)
GPIO.setup(GPIO_PWM_right, GPIO.OUT)
pwmOutput_left = GPIO.PWM(GPIO_PWM_left, FREQUENCY)
pwmOutput_right = GPIO.PWM(GPIO_PWM_right, FREQUENCY)
pwmOutput_left.start(DUTY_CYCLE)
pwmOutput_right.start(DUTY_CYCLE)
# создаем поток видео
queueVideo = multiprocessing.Queue() # можно попробовать задать макс кол-во элементов в очереди
queueFlag = multiprocessing.Queue(1)
video_proc = multiprocessing.Process(target=video, args=(queueVideo, queueFlag,))
video_proc.start()
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
try:
while True:
data = stream.read(CHUNK)
numpy_data = np.frombuffer(data, dtype=np.int16)
input_frames.append(data)
reduced_noise = nr.reduce_noise(y=numpy_data, sr=RATE,
stationary=False,
n_std_thresh_stationary=1.8,
prop_decrease=1)
reduced_noise = reduced_noise.astype(np.int16)
gain_dB = 10
increase_vol_audio = reduced_noise * (10 ** (gain_dB / 20))
increase_vol_audio = np.clip(increase_vol_audio, -32768, 32767) # Ограничение для 16-битного аудио
increase_vol_audio = increase_vol_audio.astype(np.int16)
filtered_data = np.array(increase_vol_audio, dtype=np.int16).tobytes()
frames.append(filtered_data)
if recognizer.AcceptWaveform(filtered_data):
result = recognizer.Result()
result_json = json.loads(result)
print('Распознанный текст:', result_json.get('text', ''))
if result_json['text']:
text = result_json['text']
print('text:', text)
else:
text = 'empty'
else:
partial_result = recognizer.PartialResult()
partial_result_json = json.loads(partial_result)
print('Промежуточный текст:', partial_result_json.get('partial', ''))
if text != 'empty':
try:
result = find_keywords(text, keywords)
words = [k for k in result.values()]
action = mode_selection(words)
except IndexError:
continue
# на данном этапе есть action, str действия
# если режим to_me, то команда должна следовать из очереди.
# если режим иной, то команда формируется здесь
print('action:', action)
if action in funcs:
# здесь через время можно реализовать поворты и крyгом
RC1, RC3 = functions[action]()
print('RC1 = ', RC1, 'RC3 = ', RC3)
action = None
localFlag = False
queueFlag.put(False)
elif action == 'to_me' or localFlag:
# необходимо вытащить из камеры команду
# добавить отправкy команды
queueFlag.put(True)
localFlag = True
print('to_me from if')
print('localFlag: ', localFlag)
tmp = queueVideo.get()
RC1 = tmp[0]
RC3 = tmp[1]
print('RC1 = ', RC1, 'RC3 = ', RC3)
if RC1 != None and RC3 != None:
send_command(RC1, RC3, pwmOutput_left, pwmOutput_right)
RC1, RC3 = None, None
localFlag = False
text = 'empty'
except KeyboardInterrupt:
# Завершение записи при прерывании клавиатурой (Ctrl+C)
print('End voice')
finally:
# ~ print('\n\nCommon cleanup code is here')
pwmOutput_left.stop()
pwmOutput_right.stop()
GPIO.cleanup()
stream.stop_stream()
stream.close()
p.terminate()
video_proc.join()
ASSISTANT
Учитывая обширность и сложность вашей программы, для повышения производительности и улучшения кода мы можем внести следующее:
1. **Разделение логики на функции и классы для улучшения читаемости и управления кодом.**
2. **Оптимизация многозадачности с помощью потоков и процессов, правильно распределяя нагрузку.**
3. **Использование очередей с ограниченным размером для предотвращения переполнения памяти.**
4. **Удаление избыточных операций и улучшение управления состояниями программ.**
Вот обновленная версия вашей программы:
```python
import pyaudio
import RPi.GPIO as GPIO
import numpy as np
import json
import multiprocessing
from multiprocessing import Queue, Process
import vosk
import collections.abc
collections.MutableMapping = collections.abc.MutableMapping
import cv2
from cv2 import aruco
import time
from fuzzywuzzy import fuzz, process
import noisereduce as nr
import wave
class AudioProcessor(Process):
def __init__(self, model_path, audio_queue, result_queue):
super(AudioProcessor, self).__init__()
self.model = vosk.Model(model_path)
self.recognizer = vosk.KaldiRecognizer(self.model, RATE)
self.audio_queue = audio_queue
self.result_queue = result_queue
def run(self):
while True:
data = self.audio_queue.get()
if data is None:
break
numpy_data = np.frombuffer(data, dtype=np.int16)
reduced_noise = nr.reduce_noise(y=numpy_data, sr=RATE,
stationary=False,
n_std_thresh_stationary=1.8,
prop_decrease=1)
reduced_noise = reduced_noise.astype(np.int16)
gain_dB = 10
increase_vol_audio = reduced_noise * (10 ** (gain_dB / 20))
increase_vol_audio = np.clip(increase_vol_audio, -32768, 32767) # Ограничение для 16-битного аудио
increase_vol_audio = increase_vol_audio.astype(np.int16)
filtered_data = increase_vol_audio.tobytes()
if self.recognizer.AcceptWaveform(filtered_data):
result_json = json.loads(self.recognizer.Result())
self.result_queue.put(result_json.get('text', ''))
else:
partial_result_json = json.loads(self.recognizer.PartialResult())
print('Промежуточный текст:', partial_result_json.get('partial', ''))
class VideoProcessor(Process):
def __init__(self, queue_video, queue_flag):
super(VideoProcessor, self).__init__()
self.queue_video = queue_video
self.queue_flag = queue_flag
def run(self):
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 540)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 960)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
marker_dict = aruco.getPredefinedDictionary(aruco.DICT_5X5_50)
param_markers = aruco.DetectorParameters()
detector = aruco.ArucoDetector(dictionary=marker_dict, detectorParams=param_markers)
calib_data_path = "/home/zhuk/Desktop/CAMERA/zvuk/dist/Distance Estimation/MultiMatrix.npz"
calib_data = np.load(calib_data_path)
cam_mat = calib_data["camMatrix"]
dist_coef = calib_data["distCoef"]
flag_detected_early = False
while True:
_, frame = cap.read()
grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
grayblurredframe = cv2.GaussianBlur(grayframe, (5, 5), 0)
framecenterx = width / 2
sqrmax = int((width / 5) ** 2)
sqrmin = int((width / 10) ** 2)
cv2.imshow("frame", grayframe)
cv2.waitKey(1)
try:
flag = self.queue_flag.get()
if flag:
marker_corners, markers_IDs, reject = detector.detectMarkers(grayblurredframe)
if marker_corners:
total_markers = range(0, markers_IDs.size)
for _, corners, i in zip(markers_IDs, marker_corners, total_markers):
distance = self.calc_distance(cam_mat, dist_coef, marker_corners, i)
print('distance = ', distance)
if markers_IDs[0][0] == 0:
flag_detected_early = True
centerx = marker_corners[0][0][0][0] + (marker_corners[0][0][2][0] - marker_corners[0][0][0][0]) / 2
RC1, RC3 = self.update_rc_values(
width, framecenterx, centerx, distance
)
else:
if flag_detected_early:
RC1 = 1700
RC3 = 1500
else:
RC1 = 1500
RC3 = 1500
else:
if not flag_detected_early:
RC1 = 1700
RC3 = 1500
else:
RC1 = 1500
RC3 = 1500
self.queue_video.put([RC1, RC3])
except:
continue
def calc_distance(self, cam_mat, dist_coef, marker_corners, i):
MARKER_SIZE = 5
rVec, tVec, _ = aruco.estimatePoseSingleMarkers(marker_corners, MARKER_SIZE, cam_mat, dist_coef)
return np.sqrt(tVec[i][0][2] ** 2 + tVec[i][0][0] ** 2 + tVec[i][0][1] ** 2)
def update_rc_values(self, width, framecenterx, centerx, distance):
k_max_speed = 0.8
k_max_speed_rotate = 0.75
k_width_searc = width / 4
ofset_distance = 100
stop_distance = 20
modRC3 = 1500 + int((max(min(distance - ofset_distance, stop_distance), -stop_distance)) * (100 / stop_distance) * (
k_max_speed * 5))
if 1350 < modRC3 < 1650:
modRC3 = 1500
if modRC3 >= 1500:
znak = -1
else:
znak = 1
modRC1 = 1500 + znak * int(
(max(min(framecenterx - centerx, k_width_searc), -k_width_searc)) * (100 / k_width_searc) * (
k_max_speed_rotate * 5))
if 1400 < modRC1 < 1600:
modRC1 = 1500
return modRC1, modRC3
def forward():
print('едем вперед')
return 1500, 1800
def back():
print('едем назад')
return 1500, 1200
def stop():
print('остановка')
return 1500, 1500
def right():
print('направо')
return 1900, 1500
def left():
print('налево')
return 1100, 1500
def around():
print('кругом')
return 1100, 1500
def faster():
print('быстрее')
return 1500, 2000
def slower():
print('медленее')
return 1500, 1600
def to_me():
print('ко мне')
def convert_command(RC1, RC3):
RTrack = int(max(min((RC3 - 1500) / 5 + (RC1 - 1500) / 5, 100), -100))
LTrack = int(max(min((RC3 - 1500) / 5 - (RC1 - 1500) / 5, 100), -100))
return LTrack, RTrack
def send_command(RC1, RC3, pwmOutput_left, pwmOutput_right):
LTrack, RTrack = convert_command(RC1, RC3)
print(f'LTrack: {LTrack}, RTrack: {RTrack}')
GPIO.output(GPIO_rev_left, GPIO.LOW if LTrack < 0 else GPIO.HIGH)
GPIO.output(GPIO_rev_right, GPIO.HIGH if RTrack < 0 else GPIO.LOW)
pwmOutput_left.ChangeDutyCycle(abs(LTrack))
pwmOutput_right.ChangeDutyCycle(abs(RTrack))
def find_keywords(sentence, keywords):
# Функция распознования ключевых слов
words = sentence.split()
found_keywords = {}
for keyword in keywords:
best_match, score = process.extractOne(keyword, words, scorer=fuzz.ratio)
if score > 60: # Порог схожести, можно настроить
found_keywords[best_match] = keyword
return found_keywords
def mode_selection(words):
# Выбор режима исходя из голосовой команды
names = {'юл': 1, 'юр': 2, 'жук': 3, 'жоп': 4, 'жёг': 5, 'жег': 6, 'звук': 7, 'юлить': 8, 'или': 9, 'юле': 10}
mod_word = {'ред': 'ямо', 'рёд': 'ямо', 'отстав': 'сто', 'кам': 'ко', 'ям': 'ямо', 'лева': 'лев', 'лёв': 'лев',
'дело': 'лев'}
funcs = {'ямо': 'forward', 'сто': 'stop', 'зад': 'back', 'прав': 'right',
'лев': 'left', 'быст': 'faster', 'медл': 'slower', 'ко': 'to_me', 'круг': 'around'}
name = names.get(words[0], None)
act = mod_word.get(words[1], words[1])
if name is not None:
return funcs.get(act, None)
if __name__ == '__main__':
GPIO_PWM_left = 12
GPIO_PWM_right = 13
GPIO_rev_left = 16
GPIO_rev_right = 6
WORK_TIME = 0.1
DUTY_CYCLE = 0 # min - 40
FREQUENCY = 7250
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 8000
keywords = ['юл', 'юр', 'юлить', 'юле', 'жук', 'звук', 'жоп', 'жёг', 'жег', 'ямо', 'ред', 'рёд', 'сто', 'отстав', 'прав', 'лев', 'зад', 'быст', 'медл', 'ко', 'кам', 'круг', 'дело', 'или']
funcs = ['forward', 'stop', 'back', 'right', 'left', 'faster', 'slower', 'around']
functions = {'forward': forward, 'stop': stop, 'back': back, 'right': right,
'left': left, 'faster': faster, 'slower': slower, 'around': around}
localFlag = False
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_rev_left, GPIO.OUT)
GPIO.setup(GPIO_rev_right, GPIO.OUT)
GPIO.setup(GPIO_PWM_left, GPIO.OUT)
GPIO.setup(GPIO_PWM_right, GPIO.OUT)
pwmOutput_left = GPIO.PWM(GPIO_PWM_left, FREQUENCY)
pwmOutput_right = GPIO.PWM(GPIO_PWM_right, FREQUENCY)
pwmOutput_left.start(DUTY_CYCLE)
pwmOutput_right.start(DUTY_CYCLE)
# создаем поток видео
queue_video = Queue() # можно попробовать задать макс кол-во элементов в очереди
queue_flag = Queue(1)
video_proc = VideoProcessor(queue_video, queue_flag)
video_proc.start()
audio_queue = Queue(maxsize=10)
result_queue = Queue()
audio_proc = AudioProcessor('./vosk-model-small-ru-0.4', audio_queue, result_queue)
audio_proc.start()
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
try:
while True:
data = stream.read(CHUNK)
audio_queue.put(data)
if not result_queue.empty():
text = result_queue.get()
print('Распознанный текст:', text)
if text:
result = find_keywords(text, keywords)
words = [k for k in result.values()]
action = mode_selection(words)
print('action:', action)
if action in funcs:
# здесь через время можно реализовать повороты и крyгом
RC1, RC3 = functions[action]()
print('RC1 = ', RC1, 'RC3 = ', RC3)
action = None
localFlag = False
queue_flag.put(False)
elif action == 'to_me' or localFlag:
# необходимо вытащить из камеры команду
queue_flag.put(True)
localFlag = True
tmp = queue_video.get()
RC1 = tmp[0]
RC3 = tmp[1]
print('RC1 = ', RC1, 'RC3 = ', RC3)
if RC1 is not None and RC3 is not None:
send_command(RC1, RC3, pwmOutput_left, pwmOutput_right)
RC1, RC3 = None, None
localFlag = False
except KeyboardInterrupt:
# Завершение записи при прерывании клавиатурой (Ctrl+C)
print('End voice')
finally:
pwmOutput_left.stop()
pwmOutput_right.stop()
GPIO.cleanup()
stream.stop_stream()
stream.close()
p.terminate()
audio_queue.put(None) # Завершение аудио-процесса
video_proc.terminate()
audio_proc.join()
video_proc.join()
```
### Улучшенная версия:
1. **Разделение кода на классы `AudioProcessor` и `VideoProcessor`.** Это улучшает читаемость и структуру кода.
2. **Использование очередей с ограниченным размером.** Это предотвращает переполнение и помогает лучше управлять памятью.
3. **Обработка аудио и видео в отдельных процессах.** Это повышает производительность и эффективно распределяет нагрузку.
4. **Минимизация глобальных переменных.** Использование локальных переменных и параметров функций улучшает читаемость и тестируемость кода.
Теперь программа должна работать более эффективно, используя всю мощь многопоточности и разделение задач по процессам.