話している言葉をずっとテキストに起こし続けたかった
そのためにはマイクをずっと動かして声を拾い続けないといけません。SpeechRecognitionは時間が一定経つと自動的に終わってしまいます。その回避策です。
そもそも何故そうしたかったのかというとリアルタイムに声をテキストとして表示する「Zimack」というサイトを作った というので詳細を書いているのですが動画配信用に字幕を出すものが欲しかったためです。それで手ごろだったのがVueでwebページを作ってOBSでキャプチャすることでした。
実装内容
今回の実装はApp.vueにメソッドとして書いています。それを切り抜いて以下のような流れになります。
data: () => ({
speechRecognition: window.SpeechRecognition || window.webkitSpeechRecognition,
isFirstStarted: false,
-----省略------
methods: {
settingRecognition () {
var recognition = new this.speechRecognition()
recognition.lang = 'ja-JP'
recognition.interimResults = true
recognition.continuous = true
// start時のコールバック、フラグを立てる
recognition.addEventListener('start', () => {
this.isFirstStarted = true
})
// テキスト起こしの途中経過が入ってくる
recognition.addEventListener('result', event => {
const stackText = Array.from(event.results).map(x => x[0]).map(x => x.transcript)
this.currentText = stackText.join('。')
})
// end時のコールバック、複数回呼ばれる可能性があるのでフラグが立っていれば再度テキスト起こしを始める
recognition.addEventListener('end', () => {
if (this.isFirstStarted) {
recognition.start()
this.isFirstStarted = false
}
})
recognition.start()
}
},
-----省略------
mounted () {
// SpeechRecognitionが扱えるのであればundefinedにならない
if (!this.speechRecognition) {
alert('ChromeなどのSpeechRecognitionに対応したブラウザをお使いください。')
return
}
this.settingRecognition()
-----省略------
endが複数回呼ばれたりして適切なタイミングで start()
を行わないとエラーが出たりブラウザが重くなったりしていました。
まとめ
サクッと1日くらいで作ったものなので変数名や処理の流れの雑さは否めないのですが自分は躓いたのでメモ書きとして残します。
Youtubeライブとかの配信でも字幕を出せるようになるので意外と面白いです。すこし間違ったテキストになるのもまた好きなのでサクッと実装できるこのようなapiがあることに感謝ァ…