优化。

This commit is contained in:
2025-04-27 17:48:55 +08:00
parent bee45b3876
commit 7c15077674
2 changed files with 45 additions and 32 deletions

View File

@@ -7,6 +7,8 @@ import urequests
from machine import Pin, I2S from machine import Pin, I2S
import ubinascii import ubinascii
import urandom import urandom
import select
import gc
import shared_vars import shared_vars
@@ -21,19 +23,22 @@ def init_i2s():
sd=Pin(shared_vars.SD_PIN), # Serial data output sd=Pin(shared_vars.SD_PIN), # Serial data output
mode=I2S.TX, # 使用发送模式 mode=I2S.TX, # 使用发送模式
bits=shared_vars.BITS_PER_SAMPLE, # 修改为 16 位数据 bits=shared_vars.BITS_PER_SAMPLE, # 修改为 16 位数据
format=I2S.MONO if shared_vars.CHANNELS == 1 else I2S.STEREO, # 修正声道判断逻辑 format=I2S.MONO if shared_vars.CHANNELS == 1 else I2S.STEREO, # 声道判断逻辑
rate=shared_vars.SAMPLE_RATE, # 采样率 rate=shared_vars.SAMPLE_RATE, # 采样率
ibuf=shared_vars.BUFFER_SIZE) # 输入缓冲区大小 ibuf=shared_vars.BUFFER_SIZE) # 输入缓冲区大小
return i2s return i2s
class InterphoneHandler: class InterphoneHandler:
def __init__(self):
self.audio_out = None # 全局 I2S 实例
def play_wav_file(self, data): def play_wav_file(self, data):
try: try:
# 要播放的本地 WAV 文件 # 要播放的本地 WAV 文件
WAV_FILE = data['file'] WAV_FILE = data['file']
# 初始化 I2S 接口 # 初始化 I2S 接口
audio_out = init_i2s() if not self.audio_out:
self.audio_out = init_i2s()
# 打开 WAV 文件 # 打开 WAV 文件
with open(WAV_FILE, 'rb') as f: with open(WAV_FILE, 'rb') as f:
@@ -46,70 +51,78 @@ class InterphoneHandler:
break break
# 将音频数据写入 I2S 接口 # 将音频数据写入 I2S 接口
print('将音频数据写入 I2S 接口') print('将音频数据写入 I2S 接口')
audio_out.write(data) self.audio_out.write(data)
except Exception as e: except Exception as e:
print(f"播放音频时出错: {e}") print(f"播放音频时出错: {e}")
finally: finally:
if 'audio_out' in locals(): if self.audio_out:
audio_out.deinit() self.audio_out.deinit()
self.audio_out = None
def stream_and_play(self, data): def stream_and_play(self, data):
shared_vars.player_name = data['voice_url'] # 停止之前的播放
url = data['voice_url'] # 替换为音频文件的URL self.stop_playing(data)
volume = data.get('volume', 1.0) # 从 data 中读取音量信息,默认值为 1.0(原始音量) gc.collect() # 强制回收内存
shared_vars.player_name = url = data['voice_url']
volume = data.get('volume', 1.0)
print(f"播放音频 URL: {url}, 音量: {volume}") print(f"播放音频 URL: {url}, 音量: {volume}")
time.sleep(1) time.sleep(1)
shared_vars.player_flag = True shared_vars.player_flag = True
try:
print("添加请求头信息")
headers = {
'User-Agent': 'MicroPython v1.0.0'
}
print("发送 HTTP 请求,获取流式响应")
response = urequests.get(url, headers=headers, stream=True)
print("检查响应状态码") try:
headers = {'User-Agent': 'MicroPython v1.0.0'}
print("发送 HTTP 请求,获取流式响应")
response = urequests.get(url, headers=headers, stream=True, timeout=5)
if response.status_code != 200: if response.status_code != 200:
print(f"请求失败,状态码: {response.status_code}") print(f"请求失败,状态码: {response.status_code}")
response.close() response.close()
return return
print("解析 WAV 头部")
header = response.raw.read(44)
header = response.raw.read(44)
if len(header) != 44 or header[0:4] != b'RIFF' or header[8:12] != b'WAVE' or header[12:16] != b'fmt ': if len(header) != 44 or header[0:4] != b'RIFF' or header[8:12] != b'WAVE' or header[12:16] != b'fmt ':
print(header)
raise ValueError("Not a valid WAV file") raise ValueError("Not a valid WAV file")
print("提取采样率、位深、声道数") # 提取采样率、位深、声道数
shared_vars.SAMPLE_RATE = int.from_bytes(header[24:28], 'little') shared_vars.SAMPLE_RATE = int.from_bytes(header[24:28], 'little')
shared_vars.BITS_PER_SAMPLE = int.from_bytes(header[34:36], 'little') shared_vars.BITS_PER_SAMPLE = int.from_bytes(header[34:36], 'little')
shared_vars.CHANNELS = int.from_bytes(header[22:24], 'little') shared_vars.CHANNELS = int.from_bytes(header[22:24], 'little')
# 初始化或重用 I2S 输出
print("初始化 I2S 输出") print("初始化 I2S 输出")
audio_out = init_i2s() self.audio_out = init_i2s()
print("开始流式播放") print("开始流式播放")
chunk_size = 128 chunk_size = 128
sock = response.raw
while shared_vars.player_flag and shared_vars.player_name == data['voice_url']: while shared_vars.player_flag and shared_vars.player_name == data['voice_url']:
chunk = response.raw.read(chunk_size) r, _, _ = select.select([sock], [], [], 5) # 设置超时时间为 5 秒
if not chunk: if r:
chunk = sock.read(chunk_size)
if not chunk:
break
self.audio_out.write(chunk)
else:
print("读取超时")
break break
audio_out.write(chunk)
except Exception as e: except Exception as e:
print("Playback error:", e) print("Playback error:", e)
finally: finally:
if 'audio_out' in locals():
audio_out.deinit()
if 'response' in locals(): if 'response' in locals():
response.close() response.close()
if 'sock' in locals():
sock.close()
shared_vars.player_flag = False shared_vars.player_flag = False
print('音频播放完成') gc.collect()
print('音频播放结束,清理资源')
def stop_playing(self, data): def stop_playing(self, data):
shared_vars.player_flag = False shared_vars.player_flag = False
print("停止播放音频") print("停止播放音频")
pass if self.audio_out:
self.audio_out.deinit()
def get_playing_status(self, data): def get_playing_status(self, data):
status = { status = {
@@ -117,4 +130,5 @@ class InterphoneHandler:
'player_name': shared_vars.player_name 'player_name': shared_vars.player_name
} }
print(f"获取播放状态: {status}") print(f"获取播放状态: {status}")
return status return status

View File

@@ -7,7 +7,7 @@ class SingletonThreadPool:
def __new__(cls): def __new__(cls):
if not cls._instance: if not cls._instance:
pool_size = 2 pool_size = 3
cls._instance = super().__new__(cls) cls._instance = super().__new__(cls)
cls._instance.pool_size = pool_size cls._instance.pool_size = pool_size
cls._instance.task_queue = [] cls._instance.task_queue = []
@@ -24,7 +24,6 @@ class SingletonThreadPool:
task, args = self.task_queue.pop(0) task, args = self.task_queue.pop(0)
self.pool_lock.release() self.pool_lock.release()
try: try:
gc.collect()
task(*args) task(*args)
except Exception as e: except Exception as e:
print(f"Task execution error: {e}") print(f"Task execution error: {e}")