Ceci est un mémo du résultat de diverses investigations pour voir s'il est possible d'envoyer facilement de l'audio au serveur à partir du microphone connecté au PC.
C'est pour un petit outil à usage interne, c'est donc une spécification qui "utilise simplement la dernière version de Google Chrome pour le moment".
C'est presque mon propre mémorandum et j'ai peu de connaissances en JavaScript. Python est souvent utilisé côté serveur et pour l'analyse des données.
Il existe peut-être une bonne bibliothèque JS pour la communication vocale, et le travail décrit ci-dessous peut être réalisé en un seul coup. Si vous le savez, faites-le nous savoir dans les commentaires!
Il s'agit de l'article de Google destiné aux développeurs WEB "Obtenir les données audio des utilisateurs" A été utile.
<script>
var handleSuccess = function(stream) {
var context = new AudioContext();
var input = context.createMediaStreamSource(stream)
var processor = context.createScriptProcessor(1024, 1, 1);
//Connexion WebSocket
var connection = new WebSocket('wss://hogehoge.com:8000/websocket');
input.connect(processor);
processor.connect(context.destination);
processor.onaudioprocess = function(e) {
var voice = e.inputBuffer.getChannelData(0);
connection.send(voice.buffer); //Envoyer par web socket
};
};
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(handleSuccess)
</script>
Il semble y avoir trois façons d'envoyer de l'audio au serveur:
Ici, vous pouvez lire l'article de Qiita "Technologie d'envoi du serveur au client - Focusing on WebSocket" et "Présentation de la technologie pour WebSocket / WebRTC »a été utile.
«Ce n'est pas bon de l'envoyer fréquemment par communication http, et il semble lourd d'utiliser WebRTC même si la communication vocale bidirectionnelle n'est pas nécessaire», j'ai donc décidé de continuer à envoyer le tampon vocal avec websocket pour le moment. fait. WebSocket semble être capable d'envoyer et de recevoir des binaires ou des chaînes.
Pour plus d'informations, veuillez lire ce document.
La taille du tampon en unités de cadres d'échantillonnage. S'il est spécifié, il doit s'agir de l'une des valeurs suivantes: 256, 512, 1024, 2048, 4096, 8192, 16384. S'il n'est pas spécifié ou si 0 est spécifié, la valeur optimale pour l'environnement est définie. Cette valeur sera utilisée tant que le nœud survit, et sa valeur est 2 ci-dessus.
Cette valeur détermine la fréquence à laquelle les événements de processus audio se produisent et la taille de la trame d'échantillonnage transmise pour chaque événement. La spécification d'une petite valeur entraîne une faible latence et la spécification d'une valeur élevée évite la corruption audio et les problèmes. Il est recommandé de ne pas décider vous-même de cette valeur, mais de laisser l'implémentation la décider en termes de délai et de qualité.
Je ne connais pas la signification exacte du mot "autoriser l'implémentation à choisir une bonne taille de tampon", mais dois-je le définir sur 0?
Il est également abordé dans This Stack Overflow (2013).
Lisez également la Documentation. Nous avons affaire à un son monophonique ici, et si vous avez besoin d'un son stéréo, il semble que vous deviez le concevoir.
L'appel de buffer renverra des données audio de type Float32Array, c'est-à-dire des nombres réels compris entre -1 et + 1. Il convient de noter que dans les fichiers WAV (bien qu'il semble y avoir plusieurs formats), ils sont représentés par des entiers signés 16 bits, c'est-à-dire des valeurs comprises entre -32768 et 32767.
J'ai utilisé Python 3.6, auquel je suis habitué.
J'ai utilisé Tornado, un framework WEB léger qui est bon pour le traitement asynchrone de Python.
import tornado.ioloop
import tornado.web
import tornado.websocket
import wave
import numpy as np
SAMPLE_SIZE = 2
SAMPLE_RATE = 48000
PATH = '/path/to/output.wav'
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
self.voice = []
print("opened")
def on_message(self, message):
self.voice.append(np.frombuffer(message, dtype='float32'))
def on_close(self):
v = np.array(self.voice)
v.flatten()
#Convertir en binaire en entier 16 bits et enregistrer
arr = (v * 32767).astype(np.int16)
with wave.open(PATH, 'wb') as wf:
wf.setnchannels(1)
wf.setsampwidth(SAMPLE_SIZE)
wf.setframerate(SAMPLE_RATE)
wf.writeframes(arr.tobytes('C'))
self.voice.clear()
print("closed")
app = tornado.web.Application([
(r"/websocket", WebSocketHandler)
])
if __name__ == "__main__":
app.listen(8000)
tornado.ioloop.IOLoop.instance().start()
La documentation du serveur WebSocket utilisant Tornado est ici.
D'autres frameworks tels que Flask, Bottle et Django sont célèbres, mais Tornado a été adopté car il est bon pour le traitement asynchrone comme node.js. De plus, il semblait y avoir beaucoup de code qui pourrait être utilisé comme référence par rapport à d'autres frameworks.
En utilisant numpy, une bibliothèque de calcul numérique en Python, vous pouvez facilement lire les données transmises et les lire comme un tableau de numpy.
Pour plus d'informations, lisez Numpy.frombuffer Reference.
Il convient de noter que dans les fichiers WAV (bien qu'il semble y avoir plusieurs formats), ils sont représentés par des entiers signés 16 bits, c'est-à-dire des valeurs comprises entre -32768 et 32767.
De plus, la valeur du taux d'échantillonnage (48000) dépend de l'implémentation du côté JavaScript, vérifiez donc AudioContext.sampleRate. ..
J'avais des problèmes parce que je ne comprenais pas les spécifications de la structure de données WAV, mais "Programmation sonore commençant en langage C-Traitement du signal des effets sonores" J'ai étudié en lisant l'explication du chapitre 1.
Eh bien, après tout, j'ai réussi à utiliser la bibliothèque Python standard wave.
c'est tout.
À partir de là, vous pouvez envoyer à l'API vocale de divers services cloud, effectuer un traitement vocal avec Python, etc. De plus, je n'ai fait aucune certification, donc je dois le faire correctement.
La raison d'utiliser WebSocket est qu'il serait intéressant de pouvoir pousser du serveur vers le client (navigateur) et renvoyer les résultats de l'API d'analyse vocale et du traitement vocal en temps réel.
Recommended Posts