を使用してクライアントブラウザから音声を受信するようにサーバーを設定し、SocketIO
それをGoogle Speech-to-Textで処理して、最後にテキストでクライアントに返信しようとしています。
もともと理想的には、このページのツールのように機能するように設定したかった:https://cloud.google.com/speech-to-text/
を使用getUserMedia
してストリーミングしてみましたがSocketIO-Stream
、「パイプ」する方法がわかりませんでしたMediaStream
。
代わりMediaRecorder
に、クライアント側で使用し、データ全体をblobとして送信することにしました(この例を参照)。
次にtoString('base64')
、blobに適用し、blobでgoogle-cloud / speech'sを呼び出しますclient.recognize()
。
クライアント側(私はVueJSを使用しています):
new Vue({
el: '#app',
data: function () {
return ({
msgs: [],
socket: null,
recorder: null,
: []
})
},
mounted: function () {
this.socket = io.connect('localhost:3000/user');
console.log('Connected!')
this.socket.on('text', function (text) {
this.msgs.push(text)
})
},
methods: {
startRecording: function () {
if (this.recorder && this.recorder.state == 'recording') {
console.log("Stopping!")
this.recorder.stop()
} else {
console.log("Starting!")
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(this.handleSuccess);
}
},
handleSuccess: function (stream) {
this.recorder = new MediaRecorder(stream)
this.recorder.start(10000)
this.recorder.ondataavailable = (e) => {
this.chunks.push(e.data)
console.log(e.data)
}
this.recorder.onstop = (e) => {
const blob = new Blob(this.chunks, { 'type': 'audio/webm; codecs=opus' })
this.socket.emit('audio', blob)
}
}
}
})
サーバ側:
const speech = require('@google-cloud/speech');
const client = new speech.SpeechClient();
const io = require('socket.io').listen(3000)
const ss = require('socket.io-stream')
const encoding = 'LINEAR16';
const sampleRateHertz = 16000;
const languageCode = 'en-US';
const audio = {
content: null
}
const config = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: languageCode,
}
async function main() {
const [response] = await client.recognize({
audio: audio,
config: config
})
const transcription = response.results
.map(result => result.alternatives[0].transcript)
.join('\n');
console.log(`Transcription: ${transcription}`);
}
io.of('/user').on('connection', function (socket) {
console.log('Connection made!')
socket.on('audio', function (data) {
audio.content = data.toString('base64')
main().catch(console.error)
});
});
main()
サーバー側の関数からのログは常に次のとおりです。
「文字起こし:」
-これは空です!
送信された音声からのテキストが含まれている必要があります。前もって感謝します!
nodejsアプリケーションは、'LINEAR16'
16kサンプル/秒(16000
)のレートで16ビット符号付き整数()の配列として記録された生のオーディオデータの処理を要求します。この種のオーディオ表現は、古代の電話の伝承で失われた理由から、パルス符号変調(PCM)として知られています。
しかし、クライアント側のコードから送信するBlobはそうではありません。これは、content-typeを持つメディアオブジェクトaudio/webm; codecs=opus
です。オーディオトラックを使用して圧縮されることを意味するオーパスコーデックと箱入りWEBMに(多重化)(Matroskaは、EBML)コンテナフォーマット。クラウドのテキスト読み上げコードは、それを生の音声データとして解釈しようとしますが、失敗し、手を挙げて、空の文字列を返します。これは、テキストエディタでzipファイルを表示しようとするのと似ています。意味不明です。
テキスト読み上げをメディアオブジェクトで機能させるには、最初にそのオブジェクトからPCMオーディオを抽出する必要があります。これは、サーバーにセットアップする際の首の悪名高い痛みです。ffmpegを使用する必要があります。テキスト読み上げのドキュメントにチュートリアルがあります。チュートリアルでは、ビデオファイルからオーディオをスクレイピングすることに言及しています。Blobは基本的に、ビデオトラックが含まれていないビデオファイルであるため、同じ手法が機能します。
ただし、MediaStreamブラウザのjavascript APIを使用して、最初のアプローチに戻る方がはるかに良いでしょう。特に、ブラウザコードは、Web Audio APIの要素を使用して、生のPCMオーディオデータをインターセプトし、サーバーに送信するか、ブラウザから直接テキスト読み上げに送信する必要があります。
これらすべてを説明することは、StackOverflowの回答の範囲をはるかに超えています。ここにいくつかのヒントがあります。WebオーディオAPIを使用して生のpcmオーディオを取得する方法は?
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加