我在尝试读取 PyAudio 的 Stream 时遇到了问题。
它因退出代码而崩溃
-1073740940
这是一个 Windows 堆损坏错误
0xC0000374
它发生在我从 PyAudio 流读取的行中,如下所示:
stream.read(chunk_size)
我也看到它崩溃了
-1073741819 ACCESS_VIOLATION_EXCEPTION
,但我无法复制它。
这是我试图发送垃圾邮件的两个视频调用崩溃的记录键:
- 无错误(静默崩溃): https://imgur.com/VQqbbBR
- 有错误: https://imgur.com/Bg5r07I|| |不,这不仅仅发生在我向它发送垃圾邮件时。它是随机发生的,但是当我向它发送垃圾邮件时,它会增加崩溃的可能性。有时在最初的几次尝试,有时超过 100 次尝试。
我尝试使用
这个 stackoverflow 问题的解决方案 无济于事 如果有人想复制这个,这里是代码:
永久 Pastebin 链接 (
https://pastebin.com/uDeBtGgv ) 错误如下所示:
# pip install wave keyboard requests pyaudio sounddevice
import sys
import traceback
import wave
from pathlib import Path
from time import sleep
import keyboard
import requests
import pyaudio
import sounddevice as sd
from threading import Thread
import faulthandler
BASE_DIR = Path(__file__).resolve().parent
sys.path.append(str(BASE_DIR))
# The key to record audio with
MIC_RECORD_KEY = "prtscn"
CANCEL_REQUEST_KEY = "delete"
def find_device_index(query: callable):
query_results = list(
filter(
query,
list(sd.query_devices())
)
)
if not len(query_results): return None
else: return query_results[0]['index']
# Change this to your mic name first for this to work. Use `sd.query_devices()` to see all device names.
MIC = find_device_index( lambda x: x['max_output_channels'] == 0 and 'Jack Mic (Realtek(R) Audio)' in x['name'] )
''' Functions '''
def on_press_key(_=None):
try:
global frames, recording, stream
if recording: return
print('Listening...')
print('Recording has started.')
frames = []
recording = True
stream = p.open(format=FORMAT,
channels=MIC_CHANNELS,
rate=MIC_SAMPLING_RATE,
input=True,
frames_per_buffer=CHUNK,
input_device_index=MIC,)
print('opened stream')
return print('finished press key process')
except: traceback.print_exc()
def on_release_key(_=None):
try:
print('Stopped listening.')
global recording, stream
recording = False
stream.stop_stream()
stream.close()
stream = None
# if key not held down for long enough
if not frames or len(frames) < 20:
print('No audio file to transcribe detected. Hold down the key for a longer time.')
return
print('Writing audio to file...')
# write microphone audio to file
# This is usually a uniquely generated path, simplified for now.
audio_path = str(BASE_DIR / "output.mp3" )
with wave.open(audio_path, 'wb') as wf:
wf.setnchannels(MIC_CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(MIC_SAMPLING_RATE)
wf.writeframes(b''.join(frames))
print("Temporarily saved to " + audio_path)
try: Thread( target=send_audio_to_server, args=[audio_path] ).start()
except: traceback.print_exc()
return
except: traceback.print_exc()
def send_audio_to_server(audio_file):
url = 'http://127.0.0.1:5000/process_audio'
settings = None
#try: settings = json.load( open('settings.json') )
#except OSError:
#return print("Could not open settings.json! Possibly occupied. Disregarding this request.")
data = {
'audio_file': audio_file,
"device_ids": [],
"author": "listener"
}
print("Sending speech request to server...")
try: response = requests.post(url, json=data, timeout=40)
except requests.exceptions.ConnectionError: return # Dont worry about actually connecting to the server.
except: traceback.print_exc()
print('retrieved response. attempting to jsonify.')
# Rest of the code is not relevant.
''' Main process '''
if __name__ == '__main__':
faulthandler.enable()
while True:
CHUNK = 1024
FORMAT = pyaudio.paInt16
p = pyaudio.PyAudio()
if MIC is None:
MIC = p.get_default_input_device_info()['index']
SPEAKER = p.get_default_output_device_info()['index']
# get channels and sampling rate of mic
mic_info = p.get_device_info_by_index(MIC)
MIC_CHANNELS = mic_info['maxInputChannels']
MIC_SAMPLING_RATE = 40000
print('Local listener is booting up...')
frames = []
recording = False
stream = None
try:
keyboard.on_press_key(MIC_RECORD_KEY, on_press_key)
keyboard.on_release_key(MIC_RECORD_KEY, on_release_key)
print('Local listener is ready')
while True:
try:
if recording and stream:
data = stream.read(CHUNK)
frames.append(data)
else:
sleep(0.2)
except:
traceback.print_exc()
exit(1)
except:
traceback.print_exc()
exit(1)
我可能在这里做错了什么吗? 希望得到一些指导。
Windows fatal exception: code 0xc0000374
Thread 0x00005934 (most recent call first):
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\connection.py", line 73 in create_connection
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 196 in _new_conn
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 236 in connect
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 975 in send
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 1037 in _send_output
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 1277 in endheaders
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 398 in request
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 495 in _make_request
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 789 in urlopen
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 667 in send
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 703 in send
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 589 in request
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 59 in request
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 115 in post
File "C:\Users\Dhruv\Desktop\py\AudioProcessorWhisper\test.py", line 119 in send_audio_to_server (Referring to "try: response = requests.post(url, json=data, timeout=40)")
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap
Thread 0x00006464 (most recent call first):
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 320 in wait
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\queue.py", line 171 in get
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\keyboard\_generic.py", line 57 in process
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap
Thread 0x00000b54 (most recent call first):
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\keyboard\_winkeyboard.py", line 563 in listen
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\keyboard\__init__.py", line 294 in listen
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap
Current thread 0x00006be4 (most recent call first):
File "C:\Users\Dhruv\AppData\Local\Programs\Python\Python310\lib\site-packages\pyaudio\__init__.py", line 570 in read
File "C:\Users\Dhruv\Desktop\py\AudioProcessorWhisper\test.py", line 165 in <module> (Referring to "data = stream.read(CHUNK)")
Could I be doing something wrong here? Would appreciate some guidance.
错误代码
-1073740940 (0xC0000374)
表示 Windows 堆损坏,这意味着你的程序错误地管理了内存,并且破坏了 Python 解释器用来管理堆内存的内部数据结构。这类错误难以调试,因为崩溃的症状可能出现在与实际损坏发生的地方很远的地方。
在你的情况下,错误发生在调用
stream.read(chunk_size)
时,但这并不一定意味着 PyAudio 模块本身存在问题。这更有可能是你的代码中的其他地方导致了堆损坏,并且 PyAudio 恰好是第一个遇到问题的模块。
以下是你的代码中可能导致堆损坏的一些潜在原因:
-
线程问题:
你正在使用线程将音频数据发送到服务器。如果多个线程同时或以不安全的方式访问或修改共享资源(例如
frames
列表或stream
对象),则可能会导致堆损坏。 - 音频库中的错误: 虽然可能性较小,但 PyAudio 或 PortAudio(PyAudio 所基于的底层库)中可能存在错误导致堆损坏。
- 驱动程序问题: 音频驱动程序中的错误也可能导致此类问题。尝试更新或重新安装音频驱动程序以查看是否有帮助。
为了解决此问题,你可以尝试以下操作:
-
同步线程:
确保在访问或修改共享资源(例如
frames
列表或stream
对象)时使用锁或其他同步机制来保护对它们的访问。这将防止多个线程同时写入内存的同一区域。 - 简化代码: 尝试通过移除不必要的代码(例如发送到服务器的部分)来简化代码,以查看问题是否仍然存在。如果问题消失,则逐渐添加功能,直到找到导致问题的代码为止。
- 使用调试工具: 使用调试工具(例如 Python 调试器或 gdb)来逐步执行代码并检查内存以查找损坏发生的位置。
- 更新或回滚库: 尝试更新到 PyAudio 和 PortAudio 的最新版本,或者尝试回滚到旧版本以查看问题是否仍然存在。
- 寻求社区帮助: 如果问题仍然存在,请在 PyAudio 论坛或 Stack Overflow 等论坛上寻求帮助,提供你的代码、错误消息和重现该问题的步骤的详细说明。
请记住,堆损坏问题可能难以调试,可能需要进行一些试验和错误才能找到根本原因。
标签:python,pyaudio,portaudio From: 78805348