mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-26 00:53:54 +08:00
update: 更改to_tts保存临时文件判断
This commit is contained in:
@@ -29,5 +29,31 @@ def decode_opus_from_file(input_file):
|
||||
total_frames += 1
|
||||
|
||||
# 计算总时长
|
||||
total_duration = (total_frames * frame_duration_ms) / 1000.0
|
||||
return opus_datas, total_duration
|
||||
|
||||
def decode_opus_from_bytes(input_bytes):
|
||||
"""
|
||||
从p3二进制数据中解码 Opus 数据,并返回一个 Opus 数据包的列表以及总时长。
|
||||
"""
|
||||
import io
|
||||
opus_datas = []
|
||||
total_frames = 0
|
||||
sample_rate = 16000 # 文件采样率
|
||||
frame_duration_ms = 60 # 帧时长
|
||||
frame_size = int(sample_rate * frame_duration_ms / 1000)
|
||||
|
||||
f = io.BytesIO(input_bytes)
|
||||
while True:
|
||||
header = f.read(4)
|
||||
if not header:
|
||||
break
|
||||
_, _, data_len = struct.unpack('>BBH', header)
|
||||
opus_data = f.read(data_len)
|
||||
if len(opus_data) != data_len:
|
||||
raise ValueError(f"Data length({len(opus_data)}) mismatch({data_len}) in the bytes.")
|
||||
opus_datas.append(opus_data)
|
||||
total_frames += 1
|
||||
|
||||
total_duration = (total_frames * frame_duration_ms) / 1000.0
|
||||
return opus_datas, total_duration
|
||||
@@ -3,6 +3,9 @@ import socket
|
||||
import subprocess
|
||||
import re
|
||||
import os
|
||||
import wave
|
||||
from io import BytesIO
|
||||
from core.utils import p3
|
||||
import numpy as np
|
||||
import requests
|
||||
import opuslib_next
|
||||
@@ -773,6 +776,22 @@ def audio_to_data(audio_file_path, is_opus=True):
|
||||
return pcm_to_data(raw_data, is_opus), duration
|
||||
|
||||
|
||||
def audio_bytes_to_data(audio_bytes, file_type, is_opus=True):
|
||||
"""
|
||||
直接用音频二进制数据转为opus/pcm数据,支持wav、mp3、p3
|
||||
"""
|
||||
if file_type == "p3":
|
||||
# 直接用p3解码
|
||||
return p3.decode_opus_from_bytes(audio_bytes)
|
||||
else:
|
||||
# 其他格式用pydub
|
||||
audio = AudioSegment.from_file(BytesIO(audio_bytes), format=file_type, parameters=["-nostdin"])
|
||||
audio = audio.set_channels(1).set_frame_rate(16000).set_sample_width(2)
|
||||
duration = len(audio) / 1000.0
|
||||
raw_data = audio.raw_data
|
||||
return pcm_to_data(raw_data, is_opus), duration
|
||||
|
||||
|
||||
def pcm_to_data(raw_data, is_opus=True):
|
||||
# 初始化Opus编码器
|
||||
encoder = opuslib_next.Encoder(16000, 1, opuslib_next.APPLICATION_AUDIO)
|
||||
@@ -804,6 +823,33 @@ def pcm_to_data(raw_data, is_opus=True):
|
||||
return datas
|
||||
|
||||
|
||||
def opus_datas_to_wav_bytes(opus_datas, sample_rate=16000, channels=1):
|
||||
"""
|
||||
将opus帧列表解码为wav字节流
|
||||
"""
|
||||
decoder = opuslib_next.Decoder(sample_rate, channels)
|
||||
pcm_datas = []
|
||||
|
||||
frame_duration = 60 # ms
|
||||
frame_size = int(sample_rate * frame_duration / 1000) # 960
|
||||
|
||||
for opus_frame in opus_datas:
|
||||
# 解码为PCM(返回bytes,2字节/采样点)
|
||||
pcm = decoder.decode(opus_frame, frame_size)
|
||||
pcm_datas.append(pcm)
|
||||
|
||||
pcm_bytes = b''.join(pcm_datas)
|
||||
|
||||
# 写入wav字节流
|
||||
wav_buffer = BytesIO()
|
||||
with wave.open(wav_buffer, 'wb') as wf:
|
||||
wf.setnchannels(channels)
|
||||
wf.setsampwidth(2) # 16bit
|
||||
wf.setframerate(sample_rate)
|
||||
wf.writeframes(pcm_bytes)
|
||||
return wav_buffer.getvalue()
|
||||
|
||||
|
||||
def check_vad_update(before_config, new_config):
|
||||
if (
|
||||
new_config.get("selected_module") is None
|
||||
|
||||
Reference in New Issue
Block a user