Edited at
DartDay 9

Text To Speech for Flutter

More than 1 year has passed since last update.

Flutterで、Text To Speechをするために Pluginを作成したお話。



What is Flutter


  • マテリアルデザインアプリを簡単に作成できるSDK

  • AndroidとiOSの両方でビルド

  • Googleによって開発されたオープンソースのツール

  • 開発ツール(CLI)、使いやすい言語(Dart)、豊富なウィジェット(UI)、優れたIDEサポート(IntelliJ)を提供



Flutter Widget Framework



Using Packages & Developing Plugins


  • すでに多くのパッケージが公開されている。httpやデバイス向けAPI(バッテリー)など

  • cf.Dart Packages

  • 自らパッケージを開発することもできる

  • cf.Developing Packages & Plugins



Custom platform-specific code with platform channels


  • プラットフォームのコードを実行したい場合は、プラットフォームチャネルを使用する。



Plugin at Flutter


  • 任意の名前を指定して、MethodChannelを作成し、invokeMethodを定義する。

  • invokeMethodには、プラットフォーム側に渡すメッセージと引数を定義。

class TtsPlugin {

// ttsのチャンネルを定義
static const MethodChannel _channel = const MethodChannel('net.granoeste.flutter.plugin/tts_plugin');

    // speechメソッドが呼ばれたら、invokeMethodでプラットフォームへメッセージ通知
static Future speech(String text) => _channel.invokeMethod("speech", text);

static Future stop() => _channel.invokeMethod("stop");

static Future language(String language) => _channel.invokeMethod("language", language);

}



Implement Platform Code (Android)

プラグインの登録

public class TtsPlugin implements MethodCallHandler {

/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel methodChannel = new MethodChannel(registrar.messenger(), "net.granoeste.flutter.plugin/tts_plugin");

TtsPlugin ttsPlugin = new TtsPlugin(registrar.activity(), methodChannel);

methodChannel.setMethodCallHandler(ttsPlugin);
}

private TtsPlugin(Activity activity, MethodChannel channel) {
this.activity = activity;
}

メッセージ受け取り時の実装

    @Override

public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("speech")) {
String speechText = call.arguments.toString();
// TODO: speech
result.success(true);
} else if (call.method.equals("stop")) {
// TODO: stopSpeech
result.success(true);
} else if (call.method.equals("language")) {
// TODO: set language
} else {
result.notImplemented();
}
}



App use plugin

基本的には、Pluginのメソッドを呼び出し、メッセージをプラットフォームへ伝えるだけ。


Future _textToSpeech() async {
final res = await TtsPlugin.speech("Hello world");
}

Future _language() async {
final res = await TtsPlugin.language("en");
}

プラグインの登録自体は、自動生成されたJavaのクラスのGeneratedPluginRegistrantで行ってくれます。

/**

* Generated file. Do not edit.
*/

public final class GeneratedPluginRegistrant {
public static void registerWith(PluginRegistry registry) {
TtsPlugin.registerWith(registry.registrarFor("net.granoeste.ttsplugin.TtsPlugin"));
}
}



Summary

Text To Speech をFlutterでやりたかったので実装してみましたが、MethodChannelを使用してプラットフォームにメッセージの送信してネイティブのコードを実行する実装だけ行い、ネイティブコードとFlutterとの連携なぎ込みなどはツールがよしなにやってくれたので割りと簡単に作成することができました。

作成したPluginはGitHubに公開中

granoeste/tts_plugin at develop