flutter_baidu_speech_tts 1.0.0
flutter_baidu_speech_tts: ^1.0.0 copied to clipboard
Baidu TTS plugin for Flutter: online, offline and mixed speech synthesis on Android, iOS and HarmonyOS.
flutter_baidu_speech_tts #
A Flutter plugin for Baidu Text-to-Speech (TTS) that supports online, offline and mixed (MIX) synthesis.
Platform support:
- Android: online / offline / mixed synthesis. Supports
accessToken,apiKey + secretKeyandiamKeyauthentication. - iOS: online / offline / mixed synthesis. Supports
accessToken,apiKey + secretKeyandiamKeyauthentication. Physical devices only (the SDK static library ships an arm64 device slice only; simulator architectures are excluded in the podspec). - OHOS (HarmonyOS): online / offline / mixed synthesis. Supports
accessTokenandapiKey + secretKey.iamKeyandofflineOverwriteAssetsdo not apply; if passed, they are listed underignoredParamsin theinitializereturn value. Offline models are loaded directly from the path undercontext.resourceDirthat maps toresources/resfile/, with no copy.
Quick start #
final tts = FlutterBaiduTts();
// typedEvents is a broadcast stream; subscribers cancel on their own.
final sub = tts.typedEvents.listen((BaiduTtsEvent e) {
debugPrint('$e');
// Synthesized data chunk: e.event == 'SYNTHESIZE_DATA_ARRIVED', PCM in e.audioData
});
final init = await tts.initializeWithConfig(const BaiduTtsConfig(
apiKey: 'ak',
secretKey: 'sk',
));
if (init.isSuccess) {
await tts.speakText('Hello, Baidu speech synthesis');
}
// On page dispose
await sub.cancel();
await tts.releaseTts();
Error handling contract #
Every method returns a result of the form {code, message, ...}. On failure
code != 0; no PlatformException is thrown, so callers must check code
(or use BaiduTtsResult.isSuccess). Reserved negative codes:
-1: general error (missing parameter, not initialized, SDK threw, etc.)-2:initializealready in progress (concurrent call)
All other non-zero values come from the Baidu SDK error codes (Android:
getDetailCode(), iOS: NSError.code). When initialize fails, the return
value also carries offlineCode / offlineMessage (offline engine load
result) and paramErrors (details for individual parameters the SDK rejected).
For the raw Map return value, use FlutterBaiduTtsPlatform.instance directly.
Offline models (provided by the integrator) #
Offline models (.dat, 8-16MB each, ~56MB in total) are Baidu proprietary
licensed files. They are not shipped with the plugin and are not
redistributed by it. Offline synthesis requires the integrator to obtain the
models from the Baidu AI Speech platform,
place them in the corresponding native resource directory of their own project,
and reference them by file name (not path) via offlineTextModelAsset /
offlineSpeechModelAsset:
await tts.initializeWithConfig(BaiduTtsConfig(
apiKey: 'ak',
secretKey: 'sk',
appId: 'appId',
authSn: 'authSn',
enableOffline: true,
offlineTextModelAsset: 'bd_etts_common_text_txt_all_mand_eng_middle_big_v6.0.0_20240731.dat',
offlineSpeechModelAsset:
'bd_etts_common_speech_duxiaoyu_mand_eng_high_am-tac-csubgan16k_v4.9.0_20240918_20251031153737.dat',
));
The placement directory is consistent across all three platforms (see each platform's "Integration" section below):
- Android:
android/app/src/main/assets/(copied tofilesDiron the plugin's firstinitialize) - iOS: added to the Xcode Runner target (goes into
Bundle.main) - OHOS:
entry/src/main/resources/resfile/(resolved tocontext.resourceDir, not copied)
You can also download the models to disk yourself and pass absolute paths via
offlineTextModelPath / offlineSpeechModelPath, which take precedence over
the asset name.
Android integration #
The plugin's manifest declares INTERNET and ACCESS_NETWORK_STATE (the SDK
queries network state before sending requests). No other permissions are
declared on your behalf; add them to your host app's manifest when needed:
<!-- The SDK can use it to generate a more stable cuid; Android 10+ can no
longer obtain the IMEI, so declare it only if you want to. -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Only needed when offline models live outside the app sandbox -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
Proguard rules are shipped with the AAR via consumerProguardFiles
(android/consumer-rules.pro), so no extra configuration is needed when the
host enables minifyEnabled.
The Baidu Android SDK is unpacked and bundled inside the plugin: jars live in
android/libs/ and .so files in android/src/main/jniLibs/ (arm64-v8a,
armeabi-v7a, x86, x86_64). Integrators therefore do not need to declare any
extra repositories in their own build.gradle; depending on the plugin is
enough.
Offline model files #
The plugin does not bundle offline models (8-16MB each, ~56MB in total; shipping them would force the weight onto every integrator's app). Offline synthesis requires the integrator to provide the text model and the acoustic model:
- Place them in the host app's
android/app/src/main/assets/and pass the file names viaofflineTextModelAsset/offlineSpeechModelAsset. The plugin copies them tofilesDiron the firstinitialize(offlineOverwriteAssets: trueforces an overwrite); or - Download them to disk yourself and pass absolute paths via
offlineTextModelPath/offlineSpeechModelPath. If a path does not exist,initializereturns failure directly and does not silently fall back.
The example project's models live in example/android/app/src/main/assets/ for
reference.
Offline synthesis also requires appId and authSn.
iOS integration #
SDK static library #
libBDSpeechTTSBaseKit.a is about 239MB. It is not tracked in version
control and not shipped with the plugin. During pod install, the podspec
downloads it automatically to ios/Libs/ when missing (see the default URL
at the top of the podspec; override it with the FLUTTER_BAIDU_TTS_IOS_LIB_URL
environment variable). If the download fails or you want to manage it manually,
copy BDSClientLib/libBDSpeechTTSBaseKit.a from the Baidu iOS TTS SDK package
(BDSpeechClientSDK_TTS) into ios/Libs/. The library has an arm64 device
slice only; the podspec excludes simulators via
EXCLUDED_ARCHS[sdk=iphonesimulator*], so iOS runs on physical devices
only.
Offline model files #
Also not shipped with the plugin. When file names are passed via
offlineTextModelAsset / offlineSpeechModelAsset, the plugin resolves the
absolute path in the following order:
offlineTextModelPath/offlineSpeechModelPath(explicit absolute path, highest priority);Bundle.main-- i.e. add the model files to the Runner target's Resources (the example project reuses the.datfiles underexample/android/app/src/main/assets/to avoid duplicating repo weight);- The sandbox
Documents/-- if you download models to disk yourself, put them here and reference them by absolute path.
When a model cannot be found, or loadOfflineEngine fails, initialize returns
failure with offlineCode / offlineMessage. It does not silently downgrade to
online.
The audio session is managed by the SDK itself (the plugin sets the category to
playback). If the host needs to manage AVAudioSession, override it after
initialize.
OHOS (HarmonyOS) integration #
The HarmonyOS implementation is provided as a HAR. The HAR's module.json5 is
not part of the final build, and the permissions it declares are not merged into
the host app. The integrator must therefore declare the network permission in
their own entry module (or the corresponding HAP/HSP):
// entry/src/main/module.json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
Without this permission, the online authentication during TTS initialization
(PARAM_LICENSE_URL) fails and synthesis becomes unavailable. If your test
module (ohosTest) also has cases that need networking, declare it there too.
Place offline models under the entry module's resources/resfile/ and pass the
relative file name via offlineTextModelAsset / offlineSpeechModelAsset (it
resolves to a path under context.resourceDir, with no copy).
As with Android / iOS, the plugin itself bundles no offline models (8-16MB
each; shipping them would exceed pub.dev's 100MB package limit). To run the OHOS
offline example, copy the .dat models into
example/ohos/entry/src/main/resources/resfile/ yourself (you can reuse the
same files under example/android/app/src/main/assets/).
Running the example #
The example's credentials are centralized in
example/lib/utils/tts_config.dart (TtsConfig), split into Android / iOS /
OHOS groups by platform. Before running, replace apiKey / secretKey /
appId / authSn with your own credentials from the Baidu AI Speech platform:
cd example
flutter run # Android
flutter run -d <device> # iOS, simulator not supported
Note: these credentials are currently plain-text constants, only for running the example locally. Do not commit real credentials to a public repo.
Known limitations #
- The iOS static library is 239MB, exceeding pub.dev's 100MB per-package limit,
so it is not shipped with the package and is downloaded automatically during
pod install(see the podspec for the URL; override withFLUTTER_BAIDU_TTS_IOS_LIB_URL). - iOS supports physical devices only (the static library has no simulator slice).
- When upgrading the native SDK, re-check its transitive dependencies: after
unpacking on Android there is no dependency metadata, so the OkHttp used
internally by the SDK is declared explicitly in
android/build.gradle. - The OHOS offline license URL is currently fixed at
https://upl.baidu.com/authand is not configurable. - On Android the SDK's
loadAudioPlayer()is not called; playback uses the SDK's default player.