优化。
This commit is contained in:
@@ -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 r:
|
||||||
|
chunk = sock.read(chunk_size)
|
||||||
if not chunk:
|
if not chunk:
|
||||||
break
|
break
|
||||||
audio_out.write(chunk)
|
self.audio_out.write(chunk)
|
||||||
|
else:
|
||||||
|
print("读取超时")
|
||||||
|
break
|
||||||
|
|
||||||
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 = {
|
||||||
@@ -118,3 +131,4 @@ class InterphoneHandler:
|
|||||||
}
|
}
|
||||||
print(f"获取播放状态: {status}")
|
print(f"获取播放状态: {status}")
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|||||||
@@ -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}")
|
||||||
|
|||||||
Reference in New Issue
Block a user