🧊

2015年、Speech synthesisは使えるやつなのか

2015年も終わりですね。
さて、ふと思い立ってコレを調べてます。

去年くらいかな?当初、使えるようでまったく使えないイメージがあったこのAPIですが、
はたして年末になった今、使えるAPIになっているのでしょうか・・・!

Web Speech API - Web APIs | MDN

はじめに

Web Speech APIってのは実は2本柱で構成されます。

  • Speech recogition
  • Speech synthesis

Speech recogitionは、マイクで声を拾ってそれを文字列で扱えるようにするとこまで。
Speech synthesisは文字列を実際に発するところ。

今回調べたのは後者の部分です。

Speech synthesis

ざっくり使い方。

var txt = 'あのイーハトーヴォのすきとおった風';

var uttr = new SpeechSynthesisUtterance(txt);
uttr.lang = 'ja-JP';

speechSynthesis.speak(uttr);

わざわざspeechSynthesis.getVoices()してその中の1つをuttr.voiceに代入しなくても、日本語読んでくれる一見便利なAPIです。

読み上げる文字列はキューされる

speak()すると、それがどんどんキューにpushされて、キューがなくなるまで読み上げ続ける。
これが重要で、Web Audio APIみたく非同期に再生してくれるわけではない。

  • speak: キューに追加
  • cancel: 全キューを削除
  • pause: 一時停止(キューには影響しない)
  • resume: 一時停止の解除

window.speechSynthesisに生えてる↑のメソッドでコントロールする。

読み上げ状態

  • paused
  • pending
  • speaking

window.speechSynthesisに↑ってフラグがある。
このへんはなんかHTML Audioと似た感じ。

SpeechSynthesisUtterance

speakするときに作ったこのインスタンスは、他にもいろいろ設定できる。

var uttr = new SpeechSynthesisUtterance('読みあげたい文字列');

// こっちでもok
uttr.text = "読み上げたい文字列";

// 読み上げ具合
uttr.pitch  = 1;
uttr.rate   = 1;
uttr.volume = 1;

// 言語とか声質とか
uttr.lang  = "ja-JP";
uttr.voice = null;

// コールバック系
uttr.onboundary = null;
uttr.onend      = null;
uttr.onerror    = null;
uttr.onmark     = null;
uttr.onpause    = null;
uttr.onresume   = null;
uttr.onstart    = null;

言語まわりを設定せずに、日本語らしき文字列を読ませようとすると、変な声が出ますw

使えないポイント

そもそも対応ブラウザが

http://caniuse.com/#feat=speech-synthesis

ChromeSafariだけ。
そしてこの組み合わせ、絶対おなじ挙動にならん罠や・・。

長い文字読ませると詰まる(ことがあった

さっそくChromeでだけ発生するやつ。
だいたい70文字以上くらいになると、ぶつっと切れて読み上げが止まる。

そのくせにendのコールバックも呼ばれないしspeakingフラグは立ったまま。
次にspeakしても無視。

cancelしないととダメです。

20160104: あらためて見たらなおってた・・・

日本語はむずかしい

  • 草はえる -> くさ わ える
  • Node.js -> のーど じぇーえす
  • ファンだった方も -> ふぁんだったほうも
  • 都心 -> みやこごころ
  • 36度5分 -> さんじゅうろくど ごふん
  • 骨粗鬆症 -> ほねあらすしょう(Safariのみ)

それなりに賢いが、完璧ではないので目をつぶる決断が必須。

1ブラウザ1コンテキスト?

  • ページAでspeak -> スタート
  • その再生中に、ページB(違うタブ)でspeak
  • ページAの分がspeakし終わったら、ページBでキューにためたヤツが読み上げられる

という感じで1ブラウザで1Synthesisっぽいので、まぁ被ることはないと思うけど注意・・。
あとリロードしても読み上げ止まらなかったりするし、細やかな挙動には期待してはいけない!

英語なら?

たしかに変な読み方はないし、日本語よりは流暢に喋ってくれますが・・。

それでも、

  • イントネーションは決して自然ではない
  • 抑揚が弱くてすっごく聞き取りづらい
  • 日本語と同じで読み方間違ったりする

ので、どこまでを許容するか次第。

おわりに

うーん、惜しい。