質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

589閲覧

AndroidのTTSでSSML対応はしていますか?

maeta

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2018/07/20 09:07

編集2018/07/21 08:31

前提・実現したいこと

AndroidのTTSをimportしてテキストを読み上げていて
その時にSSMLで読み方を指定したい。
どうすればSSMLが効いてくるのでしょうか?

発生している問題・エラーメッセージ

<speak><sub alias="げつまつ">月末</sub>まであと10日</speak>
と指定しても
発声する内容は
つきまつまであとじゅうにち
となってしまう。

TTSクラス

Java

1import android.content.Context; 2import android.speech.tts.TextToSpeech; 3import android.speech.tts.UtteranceProgressListener; 4 5public class TTS { 6 7 private static TextToSpeech textToSpeech; 8 private static boolean chkSpeak = false; 9 10 public static void init(final Context context) { 11 if (textToSpeech == null) { 12 textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() { 13 @Override 14 public void onInit(int i) { 15 chkSpeak = true; 16 } 17 }); 18 } 19 } 20 21 public static void speak(final String text, final String utteranceld) { 22 textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceld); 23 } 24 25 public static boolean isSpeaking() { 26 return textToSpeech.isSpeaking(); 27 } 28 29 public static void killSpeaking(){ 30 textToSpeech.stop(); 31 } 32 33 public static void setOnUtteranceProgressListener(UtteranceProgressListener l) { 34 textToSpeech.setOnUtteranceProgressListener(l); 35 } 36}

MainActivity.java

Java

1 2 // TextToSpeechの初期化処理を行う。 3 TTS.init(getApplicationContext()); 4 5 // TextToSpeechの読み上げ終了検知イベントリスナーを設定 6 TTS.setOnUtteranceProgressListener(new UtteranceProgressListener() { 7 @Override 8 public void onDone(String utteranceId) { 9 MainActivity.this.onTtsDone(); 10 } 11 12 @Override 13 public void onError(String utteranceId) {} 14 15 @Override 16 public void onStart(String utteranceId) {} 17 }); 18 19 String ssmlText = "<speak><sub alias=\"げつまつ\">月末</sub>まであと10日</speak>"; 20 21 TTS.speak(ssmlText, this.hashCode() + ""); 22

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

AndroidのTextToSpeechに関してはEngineによって処理が違うようです。
私のためした端末ではそもそもSSMLに対応しておらず、タグがそのまま読まれました。
EngineによってSSMLをサポートしているしていない、サポートしているタグが限定されていると言った感じだと思われます。

Does Android TTS support Speech Synthesis Markup Language?

下記のようにすると入っているエンジンがわかり、かつnew TextToSpeech()の第三引数でエンジンが指定できるようです。(複数入っていることもある?私の試したものは1個しか入っていませんでした。

PackageManager pm = getPackageManager(); Intent intent = new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE); List<ResolveInfo> resolveInfos = pm.queryIntentServices(intent,PackageManager.MATCH_DEFAULT_ONLY); if (resolveInfos != null) { for (ResolveInfo resolveInfo : resolveInfos) { ServiceInfo service = resolveInfo.serviceInfo; if (service != null) { // ここでTTSエンジンの情報を集める Log.d("engine", service.toString()); // service.packageName の値がTTSエンジンのパッケージ名 } } }

Android TextToSpeechの初期化について

なので、現在のところは端末とTTSのエンジン次第と言った回答になると思います。

投稿2018/07/26 09:54

razuma

総合スコア1313

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maeta

2018/07/27 00:07

回答ありがとうございます。 TTSのエンジンがキモになるのですね、よくわかりました。 実際に私も試してみたのですがエンジンは1つしか入っていませんでした。 初期化についてのリンクも貼っていただきありがとうございます。 いただいた回答で調査の先に進むことができそうです。 今後どのエンジンを使うかを検討します。 ありがとうございました。
razuma

2018/07/27 01:46

SSML対応とは少し観点が違うかもしれませんが。 読み仮名を指定したいと言うだけの目的だけであれば、自前でパースするようなものを作ってしまうと言う対応でも良いかもしれません。 <speak><sub alias=\"げつまつ\">月末</sub>まであと10日</speak> こうきたら <speak>げつまつまであと10日</speak> こう変換してあげて読み込ませる subのタグを見つけてひらがなの方だけで置き換えてしまう感じでしょうか。 まあ、それだと元々ひらがなで書けよって感じもしますし、どう言う用途で使用するかがわからないのでご参考までに。 あくまでsubの対応だけしかできないので、SSML対応と言う意味では微妙ですね。
maeta

2018/07/27 07:12 編集

ありがとうございます。 実は現在その方法で対応しておりました。 少しイントネーションがおかしくなるので、とりあえずとして使用しております import Foundation class SSML { func getSubReplace(ssmlText: String, displayText: String) -> String { var ssmlSubAry = [[String]]() var ssmlTextWork = ssmlText var displayTextWork = displayText var newSsmlText = "" while let startSubRange = ssmlTextWork.range(of: "<sub alias=\"") { let endSubRange = ssmlTextWork.range(of: "</sub>")! let startIndex = startSubRange.upperBound let endIndex = endSubRange.lowerBound let nextIndex = endSubRange.upperBound let subAryWork = String(ssmlTextWork[startIndex..<endIndex]) let subAry = subAryWork.components(separatedBy: "\">") ssmlSubAry.append(subAry) ssmlTextWork = String(ssmlTextWork[nextIndex...]) } for subAry in ssmlSubAry { let repSource = subAry[1] let repDes = subAry[0] let repRange = displayTextWork.range(of: repSource)! let repEndIndex = repRange.upperBound var repWork = String(displayTextWork[..<repEndIndex]) if let repRangeWork = repWork.range(of: repSource) { repWork.replaceSubrange(repRangeWork, with: repDes) newSsmlText += repWork } displayTextWork = String(displayTextWork[repEndIndex...]) } newSsmlText += displayTextWork while let repRange = newSsmlText.range(of: " \n") { newSsmlText.replaceSubrange(repRange, with: "、") } return newSsmlText } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問