Как отправить аудиофайл из front-end в django backend через websockets для обработки на back-end
Я сделал сайт на django, который использует websockets для выполнения определенных задач следующим образом :
- С фронтенда я хочу принимать аудио, используя MediaRecorder в качестве входного api через javascript .
- Я хочу отправить это аудио обратно на бэкэнд для обработки, и эти обработанные данные снова отправить обратно через соединение в реальном времени.
I have tried various things for the purpose but haven't been successful yet. The bytes data that I've been receiving at the backend when I'm converting that into audio then I'm getting the length and size of the audio file but not getting the content of the file. Means the whole audio is silent but the same audio which I'm listening in the frontend is having some sound. but I don't know what's happening at the backend with the file.
Consumer.py :
`import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope["url_route"]["kwargs"]["username"]
self.room_group_name = "realtime_%s" % self.room_name
self.channel_layer.group_add(
self.room_group_name, self.channel_name)
await self.accept()
print("Connected")
async def disconnect(self , close_code):
await self.channel_layer.group_discard(
self.roomGroupName ,
self.channel_layer
)
print("Disconnected")
async def receive(self, bytes_data):
with open('myfile.wav', mode='bx') as f:
f.write(bytes_data)
`
audio.js :
` navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { if (!MediaRecorder.isTypeSupported('audio/webm')) return alert('Браузер не поддерживается')
const mediaRecorder = new MediaRecorder(stream, {
mimeType: 'audio/webm',
})
const socket = new WebSocket('ws://localhost:8000/audio')
socket.onopen = () => {
document.querySelector('#status').textContent = 'Connected'
console.log({ event: 'onopen' })
mediaRecorder.addEventListener('dataavailable', async (event) => {
if (event.data.size > 0 && socket.readyState == 1) {
socket.send(event.data)
}
})
mediaRecorder.start(250)
}
socket.onmessage = (message) => {
const received = message.data
if (received) {
console.log(received)
}
}
socket.onclose = () => {
console.log({ event: 'onclose' })
}
socket.onerror = (error) => {
console.log({ event: 'onerror', error })
}
})
</script>`
Похоже, что проблема связана с байтами_данных, которые вы получаете в методе receive класса ChatConsumer. Событие MediaRecorder.ondataavailable возвращает объект Blob, содержащий записанные аудиоданные, которые необходимо преобразовать в объект bytes, прежде чем записывать в файл.
Вы можете преобразовать объект Blob в байты, используя API FileReader в JavaScript, следующим образом:
mediaRecorder.addEventListener('dataavailable', async (event) => {
if (event.data.size > 0 && socket.readyState == 1) {
const reader = new FileReader();
reader.readAsArrayBuffer(event.data);
reader.onloadend = () => {
const bytes = reader.result;
socket.send(bytes);
}
}
});
В результате объект Blob преобразуется в ArrayBuffer, который затем преобразуется в объект bytes с помощью события onloadend FileReader. Затем вы можете записать этот объект bytes в файл на сервере, используя метод receive в классе ChatConsumer, следующим образом:
async def receive(self, bytes_data):
with open('myfile.wav', mode='bx') as f:
f.write(bytes_data)
Вам также может понадобиться указать правильный MIME-тип (например, 'audio/wav') при записи файла, чтобы он был распознан сервером как правильный аудиофайл.