2024-08-04 19:00:15 +08:00
|
|
|
from traceback import print_exc
|
2024-08-04 17:34:16 +08:00
|
|
|
import base64
|
2024-08-03 18:22:53 +08:00
|
|
|
from appPublic.log import info, debug, warning, error, exception, critical
|
2024-08-03 19:06:37 +08:00
|
|
|
from appPublic.dictObject import DictObject
|
2024-08-06 15:56:45 +08:00
|
|
|
from appPublic.folderUtils import temp_file
|
2024-08-03 17:27:14 +08:00
|
|
|
from ahserver.serverenv import ServerEnv
|
|
|
|
from aiohttp.web import StreamResponse
|
|
|
|
|
2024-08-06 15:56:45 +08:00
|
|
|
from io import BytesIO
|
|
|
|
import struct
|
|
|
|
|
2024-08-06 16:00:29 +08:00
|
|
|
def audio_dic2list(audio):
|
2024-08-06 16:09:10 +08:00
|
|
|
ks = [k for k in audio.keys()]
|
2024-08-06 15:56:45 +08:00
|
|
|
ks.sort()
|
|
|
|
return [audio[k] for k in ks]
|
|
|
|
|
|
|
|
def float32array_to_wav(samples, sample_rate=16000, num_channels=1):
|
2024-08-06 16:04:06 +08:00
|
|
|
# Calculate the total number of samples
|
|
|
|
num_samples = len(samples)
|
2024-08-06 15:56:45 +08:00
|
|
|
|
2024-08-06 16:04:06 +08:00
|
|
|
# Calculate the byte rate
|
|
|
|
byte_rate = sample_rate * num_channels * 4
|
2024-08-06 15:56:45 +08:00
|
|
|
|
2024-08-06 16:04:06 +08:00
|
|
|
# Calculate the block align
|
|
|
|
block_align = num_channels * 4
|
2024-08-06 15:56:45 +08:00
|
|
|
|
2024-08-06 16:04:06 +08:00
|
|
|
# Create the WAV header
|
|
|
|
header = struct.pack(
|
|
|
|
'<4sI4s4sIHHIIHH4sI',
|
|
|
|
b'RIFF', 36 + num_samples * 4, b'WAVE', b'fmt ', 16, 3, num_channels, sample_rate,
|
|
|
|
byte_rate, block_align, 32, b'data', num_samples * 4
|
|
|
|
)
|
2024-08-06 15:56:45 +08:00
|
|
|
|
2024-08-06 16:20:21 +08:00
|
|
|
info(f'float32array_to_wav({samples[:10]}, ...)')
|
2024-08-06 16:04:06 +08:00
|
|
|
# Convert the Float32Array to bytes
|
|
|
|
data = struct.pack('f' * num_samples, *samples)
|
2024-08-06 15:56:45 +08:00
|
|
|
|
2024-08-06 16:04:06 +08:00
|
|
|
# Write the header and data to a file
|
2024-08-06 15:56:45 +08:00
|
|
|
tmpfile = temp_file(suffix='.wav')
|
2024-08-06 16:14:43 +08:00
|
|
|
with open(tmpfile, 'wb') as f:
|
2024-08-06 15:56:45 +08:00
|
|
|
f.write(header)
|
|
|
|
f.write(data)
|
|
|
|
return tmpfile
|
|
|
|
|
2024-08-03 17:27:14 +08:00
|
|
|
async def generate(request, **kw):
|
2024-08-03 19:18:31 +08:00
|
|
|
params_kw = kw.get('params_kw', DictObject())
|
2024-08-04 08:50:43 +08:00
|
|
|
info(f'{params_kw=}')
|
2024-08-03 19:16:33 +08:00
|
|
|
model = params_kw.model
|
2024-08-05 17:00:39 +08:00
|
|
|
audio = params_kw.audio
|
|
|
|
if audio is None:
|
2024-08-04 17:34:16 +08:00
|
|
|
return {
|
|
|
|
'status':'error',
|
|
|
|
'message':'audio is null'
|
|
|
|
}
|
2024-08-03 19:16:33 +08:00
|
|
|
engine = None
|
|
|
|
g = ServerEnv()
|
|
|
|
if model=='whisper':
|
|
|
|
engine = g.whisper_engine
|
2024-08-03 17:27:14 +08:00
|
|
|
|
2024-08-04 17:34:16 +08:00
|
|
|
if engine is None:
|
2024-08-04 18:43:17 +08:00
|
|
|
return {
|
2024-08-04 17:34:16 +08:00
|
|
|
'status':'error',
|
|
|
|
'message':f'model={model} is not defined'
|
|
|
|
}
|
|
|
|
try:
|
2024-08-06 15:56:45 +08:00
|
|
|
audio = audio_dic2list(audio)
|
|
|
|
fname = float32array_to_wav(audio)
|
|
|
|
txt = await engine.stt(fname)
|
|
|
|
os.remove(fname)
|
2024-08-05 17:00:39 +08:00
|
|
|
info(f'{audio=}, {txt=}')
|
2024-08-04 17:34:16 +08:00
|
|
|
return {
|
2024-08-04 18:42:22 +08:00
|
|
|
"status":"ok",
|
|
|
|
"content":txt
|
2024-08-04 17:34:16 +08:00
|
|
|
}
|
|
|
|
except Exception as e:
|
|
|
|
exception(f'{e}')
|
|
|
|
print_exc()
|
|
|
|
return {
|
|
|
|
'status':'error',
|
|
|
|
'message':f'{e}'
|
|
|
|
}
|
|
|
|
|