react-native-sherpa-onnx 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -77
- package/SherpaOnnx.podspec +79 -45
- package/android/build.gradle +8 -2
- package/android/prebuilt-download.gradle +70 -16
- package/android/prebuilt-versions.gradle +14 -6
- package/android/src/main/cpp/CMakeLists.txt +2 -0
- package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +202 -328
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +22 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +2 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +96 -142
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +40 -4
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +774 -316
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +208 -122
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect.h +92 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +3 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +14 -2
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-stt.cpp +229 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-stt.h +38 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-tts.cpp +144 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-tts.h +38 -0
- package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +1 -1
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +157 -11
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxPcmCapture.kt +150 -0
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +75 -24
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +52 -1
- package/ios/SherpaOnnx+PcmLiveStream.mm +288 -0
- package/ios/SherpaOnnx+STT.mm +2 -0
- package/ios/SherpaOnnx+TTS.mm +17 -0
- package/ios/SherpaOnnx.mm +27 -3
- package/ios/SherpaOnnxAudioConvert.h +28 -0
- package/ios/SherpaOnnxAudioConvert.mm +698 -0
- package/ios/archive/sherpa-onnx-archive-helper.mm +12 -0
- package/ios/model_detect/sherpa-onnx-model-detect-helper.h +37 -3
- package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +80 -45
- package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +629 -267
- package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +148 -56
- package/ios/model_detect/sherpa-onnx-model-detect.h +72 -0
- package/ios/model_detect/sherpa-onnx-validate-stt.h +38 -0
- package/ios/model_detect/sherpa-onnx-validate-stt.mm +229 -0
- package/ios/model_detect/sherpa-onnx-validate-tts.h +38 -0
- package/ios/model_detect/sherpa-onnx-validate-tts.mm +144 -0
- package/ios/stt/sherpa-onnx-stt-wrapper.mm +4 -0
- package/lib/module/NativeSherpaOnnx.js.map +1 -1
- package/lib/module/audio/index.js +55 -1
- package/lib/module/audio/index.js.map +1 -1
- package/lib/module/download/ModelDownloadManager.js +14 -0
- package/lib/module/download/ModelDownloadManager.js.map +1 -1
- package/lib/module/index.js +10 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/stt/streaming.js +6 -3
- package/lib/module/stt/streaming.js.map +1 -1
- package/lib/module/tts/index.js +13 -1
- package/lib/module/tts/index.js.map +1 -1
- package/lib/typescript/src/NativeSherpaOnnx.d.ts +32 -3
- package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
- package/lib/typescript/src/audio/index.d.ts +20 -1
- package/lib/typescript/src/audio/index.d.ts.map +1 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts +2 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +10 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/stt/streaming.d.ts.map +1 -1
- package/lib/typescript/src/stt/streamingTypes.d.ts +1 -1
- package/lib/typescript/src/stt/streamingTypes.d.ts.map +1 -1
- package/lib/typescript/src/tts/index.d.ts +12 -1
- package/lib/typescript/src/tts/index.d.ts.map +1 -1
- package/package.json +6 -1
- package/scripts/check-model-csvs.sh +72 -0
- package/scripts/setup-ios-framework.sh +272 -191
- package/src/NativeSherpaOnnx.ts +37 -3
- package/src/audio/index.ts +84 -1
- package/src/download/ModelDownloadManager.ts +19 -0
- package/src/index.tsx +15 -0
- package/src/stt/streaming.ts +10 -5
- package/src/stt/streamingTypes.ts +1 -1
- package/src/tts/index.ts +25 -1
- package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -1
- package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -1
- package/ios/scripts/patch-libarchive-includes.sh +0 -61
- package/ios/scripts/setup-ios-libarchive.sh +0 -98
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ React Native SDK for sherpa-onnx – offline and streaming speech processing
|
|
|
14
14
|
[](https://www.android.com/)
|
|
15
15
|
[](https://www.apple.com/ios/)
|
|
16
16
|
|
|
17
|
+
<a href="https://www.buymeacoffee.com/xdcobra" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" width="150" /></a>
|
|
18
|
+
|
|
17
19
|
</div>
|
|
18
20
|
|
|
19
21
|
> **⚠️ SDK 0.3.0 – Breaking changes from 0.2.0**
|
|
@@ -21,16 +23,57 @@ React Native SDK for sherpa-onnx – offline and streaming speech processing
|
|
|
21
23
|
|
|
22
24
|
A React Native TurboModule that provides offline and streaming speech processing capabilities using [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx). The SDK aims to support all functionalities that sherpa-onnx offers, including offline and **online (streaming)** speech-to-text, text-to-speech (batch and streaming), speaker diarization, speech enhancement, source separation, and VAD (Voice Activity Detection).
|
|
23
25
|
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm install react-native-sherpa-onnx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If your project uses Yarn (v3+) or Plug'n'Play, configure Yarn to use the Node Modules linker to avoid postinstall issues:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
# .yarnrc.yml
|
|
36
|
+
nodeLinker: node-modules
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Alternatively, set the environment variable during install:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
YARN_NODE_LINKER=node-modules yarn install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Android
|
|
46
|
+
|
|
47
|
+
No additional setup required. The library automatically handles native dependencies via Gradle. For execution provider support (CPU, NNAPI, XNNPACK, QNN) and optional QNN setup, see [Execution provider support](./docs/execution-providers.md). For building Android native libs yourself, see [sherpa-onnx-prebuilt](third_party/sherpa-onnx-prebuilt/README.md).
|
|
48
|
+
|
|
49
|
+
### iOS
|
|
50
|
+
|
|
51
|
+
The sherpa-onnx **XCFramework is not shipped in the repo or npm** (size ~80MB). It is **downloaded automatically** when you run `pod install`; no manual steps are required. The version used is pinned in `third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG` and the archive is fetched from [GitHub Releases](https://github.com/XDcobra/react-native-sherpa-onnx/releases?q=framework).
|
|
52
|
+
|
|
53
|
+
#### Setup
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
cd your-app/ios
|
|
57
|
+
bundle install
|
|
58
|
+
bundle exec pod install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The podspec runs `scripts/setup-ios-framework.sh`, which downloads the XCFramework (and, if needed, libarchive sources) so the Pod builds correctly. Libarchive is compiled from source as part of the Pod; its version is pinned in `third_party/libarchive_prebuilt/IOS_RELEASE_TAG`.
|
|
62
|
+
|
|
63
|
+
#### Building the iOS framework
|
|
64
|
+
|
|
65
|
+
To build the sherpa-onnx iOS XCFramework yourself (e.g. custom version or patches), see [third_party/sherpa-onnx-prebuilt/README.md](third_party/sherpa-onnx-prebuilt/README.md) and the [build-sherpa-onnx-ios-framework](.github/workflows/build-sherpa-onnx-ios-framework.yml) workflow.
|
|
66
|
+
|
|
24
67
|
## Table of contents
|
|
25
68
|
|
|
69
|
+
- [Installation](#installation)
|
|
70
|
+
- [Android](#android)
|
|
71
|
+
- [iOS](#ios)
|
|
26
72
|
- [Feature Support](#feature-support)
|
|
27
73
|
- [Platform Support Status](#platform-support-status)
|
|
28
74
|
- [Supported Model Types](#supported-model-types)
|
|
29
75
|
- [Speech-to-Text (STT) Models](#speech-to-text-stt-models)
|
|
30
76
|
- [Text-to-Speech (TTS) Models](#text-to-speech-tts-models)
|
|
31
|
-
- [Installation](#installation)
|
|
32
|
-
- [Android](#android)
|
|
33
|
-
- [iOS](#ios)
|
|
34
77
|
- [Documentation](#documentation)
|
|
35
78
|
- [Requirements](#requirements)
|
|
36
79
|
- [Breaking changes (upgrading to 0.3.0)](#breaking-changes-upgrading-to-030)
|
|
@@ -48,12 +91,13 @@ A React Native TurboModule that provides offline and streaming speech processing
|
|
|
48
91
|
| Feature | Status | Notes |
|
|
49
92
|
|---------|--------|-------|
|
|
50
93
|
| Offline Speech-to-Text | ✅ **Supported** | No internet required; multiple model types (Zipformer, Paraformer, Whisper, etc.). See [Supported Model Types](#supported-model-types) and [STT documentation](./docs/stt.md). |
|
|
51
|
-
| Online (streaming) Speech-to-Text | ✅ **Supported** | Real-time recognition from microphone or stream; partial results, endpoint detection. Use streaming-capable models (e.g. transducer, paraformer). See [Streaming STT](./docs/
|
|
94
|
+
| Online (streaming) Speech-to-Text | ✅ **Supported** | Real-time recognition from microphone or stream; partial results, endpoint detection. Use streaming-capable models (e.g. transducer, paraformer). See [Streaming STT](./docs/stt-streaming.md). |
|
|
95
|
+
| Live capture API | ✅ **Supported** | Native microphone capture with resampling for live transcription (use with streaming STT). See [PCM Live Stream](./docs/pcm-live-stream.md). |
|
|
52
96
|
| Text-to-Speech | ✅ **Supported** | Multiple model types (VITS, Matcha, Kokoro, etc.). See [Supported Model Types](#supported-model-types) and [TTS documentation](./docs/tts.md). |
|
|
53
|
-
| Streaming Text-to-Speech | ✅ **Supported** | Incremental speech generation for low time-to-first-byte and playback while generating. See [Streaming TTS](./docs/
|
|
97
|
+
| Streaming Text-to-Speech | ✅ **Supported** | Incremental speech generation for low time-to-first-byte and playback while generating. See [Streaming TTS](./docs/tts-streaming.md). |
|
|
54
98
|
| Execution providers (CPU, NNAPI, XNNPACK, Core ML, QNN) | ✅ **Supported** | See [Execution provider support](./docs/execution-providers.md). |
|
|
55
|
-
| Play Asset Delivery (PAD) | ✅ **Supported** | Android only. See [Model Setup](./docs/
|
|
56
|
-
| Automatic Model type detection | ✅ **Supported** | `detectSttModel()` and `detectTtsModel()` for a path. See [Model Setup: Model type detection](./docs/
|
|
99
|
+
| Play Asset Delivery (PAD) | ✅ **Supported** | Android only. See [Model Setup](./docs/model-setup.md). |
|
|
100
|
+
| Automatic Model type detection | ✅ **Supported** | `detectSttModel()` and `detectTtsModel()` for a path. See [Model Setup: Model type detection](./docs/model-setup.md#model-detection). |
|
|
57
101
|
| Model quantization | ✅ **Supported** | Automatic detection and preference for quantized (int8) models. |
|
|
58
102
|
| Flexible model loading | ✅ **Supported** | Asset models, file system models, or auto-detection. |
|
|
59
103
|
| TypeScript | ✅ **Supported** | Full type definitions included. |
|
|
@@ -75,95 +119,57 @@ A React Native TurboModule that provides offline and streaming speech processing
|
|
|
75
119
|
|
|
76
120
|
| Model Type | `modelType` Value | Description | Download Links |
|
|
77
121
|
| ------------------------ | ----------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
78
|
-
| **Zipformer/Transducer** | `'transducer'` |
|
|
79
|
-
| **
|
|
80
|
-
| **
|
|
81
|
-
| **
|
|
82
|
-
| **
|
|
83
|
-
| **
|
|
84
|
-
| **
|
|
85
|
-
| **
|
|
86
|
-
|
|
87
|
-
|
|
122
|
+
| **Zipformer/Transducer** | `'transducer'` | Encoder–decoder–joiner (e.g. icefall). Good balance of speed and accuracy. Folder name should contain **zipformer** or **transducer** for auto-detection. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-transducer/index.html) |
|
|
123
|
+
| **LSTM Transducer** | `'transducer'` | Same layout as Zipformer (encoder–decoder–joiner). LSTM-based streaming ASR; detected as transducer. Folder name may contain **lstm**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/lstm-transducer-models.html) |
|
|
124
|
+
| **Paraformer** | `'paraformer'` | Single-model non-autoregressive ASR; fast and accurate. Detected by `model.onnx`; no folder token required. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-paraformer/index.html) |
|
|
125
|
+
| **NeMo CTC** | `'nemo_ctc'` | NeMo CTC; good for English and streaming. Folder name should contain **nemo** or **parakeet**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-ctc/nemo/index.html) |
|
|
126
|
+
| **Whisper** | `'whisper'` | Multilingual, encoder–decoder; strong zero-shot. Detected by encoder+decoder (no joiner); folder token optional. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/whisper/index.html) |
|
|
127
|
+
| **WeNet CTC** | `'wenet_ctc'` | CTC from WeNet; compact. Folder name should contain **wenet**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-ctc/wenet/index.html) |
|
|
128
|
+
| **SenseVoice** | `'sense_voice'` | Multilingual with emotion/punctuation. Folder name should contain **sense** or **sensevoice**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/sense-voice/index.html) |
|
|
129
|
+
| **FunASR Nano** | `'funasr_nano'` | Lightweight LLM-based ASR. Folder name should contain **funasr** or **funasr-nano**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/funasr-nano/index.html) |
|
|
130
|
+
| **Moonshine (v1)** | `'moonshine'` | Four-part streaming-capable ASR (preprocess, encode, uncached/cached decode). Folder name should contain **moonshine**. | [Download](https://k2-fsa.github.io/sherpa/onnx/moonshine/index.html) |
|
|
131
|
+
| **Moonshine (v2)** | `'moonshine_v2'` | Two-part Moonshine (encoder + merged decoder); `.onnx` or `.ort`. Folder name should contain **moonshine** (v2 preferred if both layouts present). | [Download](https://k2-fsa.github.io/sherpa/onnx/moonshine/index.html) |
|
|
132
|
+
| **Fire Red ASR** | `'fire_red_asr'` | Fire Red encoder–decoder ASR. Folder name should contain **fire_red** or **fire-red**. | [Download](https://k2-fsa.github.io/sherpa/onnx/FireRedAsr/index.html) |
|
|
133
|
+
| **Dolphin** | `'dolphin'` | Single-model CTC. Folder name should contain **dolphin**. | [Download](https://k2-fsa.github.io/sherpa/onnx/Dolphin/index.html) |
|
|
134
|
+
| **Canary** | `'canary'` | NeMo Canary multilingual. Folder name should contain **canary**. | [Download](https://k2-fsa.github.io/sherpa/onnx/nemo/canary.html) |
|
|
135
|
+
| **Omnilingual** | `'omnilingual'` | Omnilingual CTC. Folder name should contain **omnilingual**. | [Download](https://k2-fsa.github.io/sherpa/onnx/omnilingual-asr/index.html) |
|
|
136
|
+
| **MedASR** | `'medasr'` | Medical ASR CTC. Folder name should contain **medasr**. | [Download](https://github.com/k2-fsa/sherpa-onnx) |
|
|
137
|
+
| **Telespeech CTC** | `'telespeech_ctc'`| Telespeech CTC. Folder name should contain **telespeech**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/telespeech/index.html) |
|
|
138
|
+
| **Tone CTC (t-one)** | `'tone_ctc'` | Lightweight streaming CTC (e.g. t-one). Folder name should contain **t-one**, **t_one**, or **tone** (as word). | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-ctc/index.html) |
|
|
139
|
+
|
|
140
|
+
For **real-time (streaming) recognition** from a microphone or audio stream, use streaming-capable model types: `transducer`, `paraformer`, `zipformer2_ctc`, `nemo_ctc`, or `tone_ctc`. See [Streaming (Online) Speech-to-Text](./docs/stt-streaming.md).
|
|
88
141
|
|
|
89
142
|
### Text-to-Speech (TTS) Models
|
|
90
143
|
|
|
91
144
|
| Model Type | `modelType` Value | Description | Download Links |
|
|
92
145
|
| ---------------- | ----------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
93
|
-
| **VITS** | `'vits'` | Fast, high-quality TTS
|
|
94
|
-
| **Matcha** | `'matcha'` | High-quality acoustic model + vocoder.
|
|
95
|
-
| **Kokoro** | `'kokoro'` | Multi-speaker, multi-language.
|
|
96
|
-
| **KittenTTS** | `'kitten'` | Lightweight, multi-speaker.
|
|
97
|
-
| **Zipvoice** | `'zipvoice'` | Voice cloning
|
|
98
|
-
| **Pocket** | `'pocket'` | Flow-matching TTS.
|
|
99
|
-
|
|
100
|
-
For **streaming TTS** (incremental generation, low latency), use `createStreamingTTS()` with supported model types. See [Streaming Text-to-Speech](./docs/tts_streaming.md).
|
|
101
|
-
|
|
102
|
-
## Installation
|
|
103
|
-
|
|
104
|
-
```sh
|
|
105
|
-
npm install react-native-sherpa-onnx
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
If your project uses Yarn (v3+) or Plug'n'Play, configure Yarn to use the Node Modules linker to avoid postinstall issues:
|
|
109
|
-
|
|
110
|
-
```yaml
|
|
111
|
-
# .yarnrc.yml
|
|
112
|
-
nodeLinker: node-modules
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Alternatively, set the environment variable during install:
|
|
116
|
-
|
|
117
|
-
```sh
|
|
118
|
-
YARN_NODE_LINKER=node-modules yarn install
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Android
|
|
122
|
-
|
|
123
|
-
No additional setup required. The library automatically handles native dependencies via Gradle. For execution provider support (CPU, NNAPI, XNNPACK, QNN) and optional QNN setup, see [Execution provider support](./docs/execution-providers.md). For building Android native libs yourself, see [sherpa-onnx-prebuilt](third_party/sherpa-onnx-prebuilt/README.md).
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
### iOS
|
|
127
|
-
|
|
128
|
-
The sherpa-onnx **XCFramework is not shipped in the repo or npm** (size ~80MB). It is **downloaded automatically** when you run `pod install`; no manual steps are required. The version used is pinned in `third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG` and the archive is fetched from [GitHub Releases](https://github.com/XDcobra/react-native-sherpa-onnx/releases?q=framework).
|
|
129
|
-
|
|
130
|
-
#### Setup
|
|
131
|
-
|
|
132
|
-
```sh
|
|
133
|
-
cd your-app/ios
|
|
134
|
-
bundle install
|
|
135
|
-
bundle exec pod install
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
The podspec runs `scripts/setup-ios-framework.sh`, which downloads the XCFramework (and, if needed, libarchive sources) so the Pod builds correctly. Libarchive is compiled from source as part of the Pod; its version is pinned in `third_party/libarchive_prebuilt/IOS_RELEASE_TAG`.
|
|
139
|
-
|
|
140
|
-
#### For Advanced Users: Building the Framework Locally
|
|
141
|
-
#### Advanced: Building the iOS framework yourself
|
|
142
|
-
|
|
143
|
-
If you need a custom sherpa-onnx build (e.g. different version or patches), you can build the XCFramework and place it in `ios/Frameworks/` before running `pod install`. The repo does not include an iOS build script; use one of:
|
|
144
|
-
|
|
145
|
-
- **This repo's CI:** The [build-sherpa-onnx-ios-framework](.github/workflows/build-sherpa-onnx-ios-framework.yml) workflow produces the XCFramework and publishes it as a GitHub Release. You can run equivalent steps locally or inspect the workflow for the exact build and merge steps (including `libsherpa-onnx-cxx-api.a` and libarchive).
|
|
146
|
-
- **Version and layout:** Pinned version and release layout are documented in [third_party/sherpa-onnx-prebuilt](third_party/sherpa-onnx-prebuilt/README.md) (Android focus; for iOS, see `IOS_RELEASE_TAG` and the [iOS framework workflow](.github/workflows/build-sherpa-onnx-ios-framework.yml)).
|
|
146
|
+
| **VITS** | `'vits'` | Fast, high-quality TTS (Piper, Coqui, MeloTTS, MMS). Folder name should contain **vits** if used with other voice models. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
|
|
147
|
+
| **Matcha** | `'matcha'` | High-quality acoustic model + vocoder. Detected by acoustic_model + vocoder; no folder token required. | [Download](https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/matcha.html) |
|
|
148
|
+
| **Kokoro** | `'kokoro'` | Multi-speaker, multi-language. Folder name should contain **kokoro** (not kitten) for auto-detection. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
|
|
149
|
+
| **KittenTTS** | `'kitten'` | Lightweight, multi-speaker. Folder name should contain **kitten** (not kokoro) for auto-detection. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
|
|
150
|
+
| **Zipvoice** | `'zipvoice'` | Voice cloning (encoder + decoder + vocoder). Detected by file layout; folder token optional. | [Download](https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/zipvoice.html) |
|
|
151
|
+
| **Pocket** | `'pocket'` | Flow-matching TTS. Detected by lm_flow, lm_main, text_conditioner, vocab/token_scores; no folder token required. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
|
|
147
152
|
|
|
148
|
-
|
|
153
|
+
For **streaming TTS** (incremental generation, low latency), use `createStreamingTTS()` with supported model types. See [Streaming Text-to-Speech](./docs/tts-streaming.md).
|
|
149
154
|
|
|
150
155
|
## Documentation
|
|
151
156
|
|
|
152
157
|
- [Speech-to-Text (STT)](./docs/stt.md) – Offline transcription (file or samples)
|
|
153
|
-
- [Streaming (Online) Speech-to-Text](./docs/
|
|
158
|
+
- [Streaming (Online) Speech-to-Text](./docs/stt-streaming.md) – Real-time recognition, partial results, endpoint detection
|
|
159
|
+
- [PCM Live Stream](./docs/pcm-live-stream.md) – Native microphone capture with resampling for live transcription (use with streaming STT)
|
|
154
160
|
- [Text-to-Speech (TTS)](./docs/tts.md) – Offline and streaming generation
|
|
155
|
-
- [Streaming Text-to-Speech](./docs/
|
|
161
|
+
- [Streaming Text-to-Speech](./docs/tts-streaming.md) – Incremental TTS (createStreamingTTS)
|
|
156
162
|
- [Execution provider support (QNN, NNAPI, XNNPACK, Core ML)](./docs/execution-providers.md) – Checking and using acceleration backends
|
|
157
163
|
- [Voice Activity Detection (VAD)](./docs/vad.md)
|
|
158
164
|
- [Speaker Diarization](./docs/diarization.md)
|
|
159
165
|
- [Speech Enhancement](./docs/enhancement.md)
|
|
160
166
|
- [Source Separation](./docs/separation.md)
|
|
161
|
-
- [Model Setup](./docs/
|
|
167
|
+
- [Model Setup](./docs/model-setup.md) – Bundled assets, Play Asset Delivery (PAD), model discovery APIs, and troubleshooting
|
|
162
168
|
- [Model Download Manager](./docs/download-manager.md)
|
|
163
169
|
- [Disable FFMPEG](./docs/disable-ffmpeg.md)
|
|
164
170
|
- [Disable LIBARCHIVE](./docs/disable-libarchive.md)
|
|
165
171
|
|
|
166
|
-
Note: For when to use `listAssetModels()` vs `listModelsAtPath()` and how to combine bundled and PAD/file-based models, see [Model Setup](./docs/
|
|
172
|
+
Note: For when to use `listAssetModels()` vs `listModelsAtPath()` and how to combine bundled and PAD/file-based models, see [Model Setup](./docs/model-setup.md).
|
|
167
173
|
|
|
168
174
|
## Requirements
|
|
169
175
|
|
|
@@ -179,7 +185,7 @@ We provide example applications to help you get started with `react-native-sherp
|
|
|
179
185
|
|
|
180
186
|
The example app included in this repository demonstrates audio-to-text transcription, text-to-speech, and streaming features. It includes:
|
|
181
187
|
|
|
182
|
-
- Multiple model type support (Zipformer, Paraformer, NeMo CTC, Whisper, WeNet CTC, SenseVoice, FunASR Nano)
|
|
188
|
+
- Multiple model type support (Zipformer, Paraformer, NeMo CTC, Whisper, WeNet CTC, SenseVoice, FunASR Nano, Moonshine, and more)
|
|
183
189
|
- Model selection and configuration
|
|
184
190
|
- **Offline** audio file transcription
|
|
185
191
|
- **Online (streaming) STT** – live transcription from the microphone with partial results
|
|
@@ -202,6 +208,7 @@ yarn android # or yarn ios
|
|
|
202
208
|
<td><img src="./docs/images/example_stt_2.png" alt="Transcribe cantonese audio" width="240" /></td>
|
|
203
209
|
</tr>
|
|
204
210
|
<tr>
|
|
211
|
+
<td><img src="./docs/images/example_streaming.png" alt="Text to speech generation" width="240" /></td>
|
|
205
212
|
<td><img src="./docs/images/example_tts.png" alt="Text to speech generation" width="240" /></td>
|
|
206
213
|
<td><img src="./docs/images/example_provider.png" alt="Text to speech generation" width="240" /></td>
|
|
207
214
|
</tr>
|
package/SherpaOnnx.podspec
CHANGED
|
@@ -2,39 +2,17 @@ require "json"
|
|
|
2
2
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
4
|
pod_root = __dir__
|
|
5
|
-
# Prefer libarchive_prebuilt layout (output of third_party/libarchive_prebuilt/build_libarchive_ios.sh).
|
|
6
|
-
# Fallback: download via setup-ios-libarchive.sh to ios/Downloads/libarchive (e.g. when using SDK from npm).
|
|
7
|
-
libarchive_prebuilt = File.join(pod_root, "third_party", "libarchive_prebuilt", "libarchive-ios-layout")
|
|
8
|
-
libarchive_downloads = File.join(pod_root, "ios", "Downloads", "libarchive")
|
|
9
|
-
unless File.directory?(libarchive_prebuilt) && Dir.glob(File.join(libarchive_prebuilt, "*.c")).any?
|
|
10
|
-
libarchive_script = File.join(pod_root, "ios", "scripts", "setup-ios-libarchive.sh")
|
|
11
|
-
if File.exist?(libarchive_script)
|
|
12
|
-
unless system("bash", libarchive_script)
|
|
13
|
-
abort("[SherpaOnnx] setup-ios-libarchive.sh failed. Check that third_party/libarchive_prebuilt/IOS_RELEASE_TAG exists and the release is available (network). Run the script manually: bash #{libarchive_script}")
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
libarchive_dir = (File.directory?(libarchive_prebuilt) && Dir.glob(File.join(libarchive_prebuilt, "*.c")).any?) ? libarchive_prebuilt : libarchive_downloads
|
|
18
|
-
# Patch libarchive .c files (copy to ios/patched_libarchive with stdio.h/unistd.h added) so we don't modify the submodule.
|
|
19
|
-
patched_dir = File.join(pod_root, "ios", "patched_libarchive")
|
|
20
|
-
patch_script = File.join(pod_root, "ios", "scripts", "patch-libarchive-includes.sh")
|
|
21
|
-
if File.directory?(libarchive_dir) && File.exist?(patch_script)
|
|
22
|
-
unless system("bash", patch_script, libarchive_dir)
|
|
23
|
-
abort("[SherpaOnnx] patch-libarchive-includes.sh failed. Check that #{libarchive_dir} contains libarchive .c/.h files.")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
# Libarchive C sources: use patched copies (same exclude as before: test, windows, linux, sunos, freebsd).
|
|
27
|
-
libarchive_sources = if File.directory?(patched_dir)
|
|
28
|
-
Dir.glob(File.join(patched_dir, "*.c")).reject { |f|
|
|
29
|
-
base = File.basename(f, ".c")
|
|
30
|
-
File.basename(f) =~ /^test\./ || base.include?("windows") || base.include?("linux") || base.include?("sunos") || base.include?("freebsd")
|
|
31
|
-
}.map { |f| Pathname.new(f).relative_path_from(Pathname.new(pod_root)).to_s.gsub("\\", "/") }
|
|
32
|
-
else
|
|
33
|
-
[]
|
|
34
|
-
end
|
|
35
5
|
|
|
36
|
-
|
|
37
|
-
|
|
6
|
+
# Run iOS framework setup when podspec is loaded (works for :path pods).
|
|
7
|
+
setup_script = File.join(pod_root, "scripts", "setup-ios-framework.sh")
|
|
8
|
+
if File.exist?(setup_script)
|
|
9
|
+
prev = ENV["SHERPA_ONNX_PROJECT_ROOT"]
|
|
10
|
+
ENV["SHERPA_ONNX_PROJECT_ROOT"] = pod_root
|
|
11
|
+
unless system("bash", setup_script)
|
|
12
|
+
ENV["SHERPA_ONNX_PROJECT_ROOT"] = prev
|
|
13
|
+
abort("[SherpaOnnx] setup-ios-framework.sh failed. Check IOS_RELEASE_TAG files (sherpa-onnx-prebuilt, ffmpeg_prebuilt, libarchive_prebuilt) and network. Run manually: bash #{setup_script}")
|
|
14
|
+
end
|
|
15
|
+
ENV["SHERPA_ONNX_PROJECT_ROOT"] = prev
|
|
38
16
|
end
|
|
39
17
|
|
|
40
18
|
Pod::Spec.new do |s|
|
|
@@ -48,15 +26,31 @@ Pod::Spec.new do |s|
|
|
|
48
26
|
s.platforms = { :ios => min_ios_version_supported }
|
|
49
27
|
s.source = { :git => "https://github.com/XDcobra/react-native-sherpa-onnx.git", :tag => "#{s.version}" }
|
|
50
28
|
|
|
51
|
-
|
|
52
|
-
setup_script = File.join(pod_root, "scripts", "setup-ios-framework.sh")
|
|
53
|
-
s.prepare_command = "bash \"#{setup_script}\""
|
|
54
|
-
|
|
55
|
-
s.source_files = ["ios/**/*.{h,m,mm,swift,cpp}", *libarchive_sources]
|
|
29
|
+
s.source_files = ["ios/**/*.{h,m,mm,swift,cpp}"]
|
|
56
30
|
s.private_header_files = "ios/**/*.h"
|
|
57
31
|
|
|
58
|
-
s.frameworks = "Foundation", "Accelerate", "CoreML"
|
|
59
|
-
|
|
32
|
+
s.frameworks = "Foundation", "Accelerate", "CoreML", "AVFoundation", "AudioToolbox"
|
|
33
|
+
|
|
34
|
+
ffmpeg_xcframework = File.join(pod_root, "ios", "Frameworks", "FFmpeg.xcframework")
|
|
35
|
+
libarchive_xcframework = File.join(pod_root, "ios", "Frameworks", "libarchive.xcframework")
|
|
36
|
+
|
|
37
|
+
has_ffmpeg = false
|
|
38
|
+
disable_ffmpeg = ENV['SHERPA_ONNX_DISABLE_FFMPEG']
|
|
39
|
+
if (!disable_ffmpeg || disable_ffmpeg == '0' || disable_ffmpeg == 'false') && File.exist?(ffmpeg_xcframework)
|
|
40
|
+
has_ffmpeg = true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
has_libarchive = false
|
|
44
|
+
disable_libarchive = ENV['SHERPA_ONNX_DISABLE_LIBARCHIVE']
|
|
45
|
+
if (!disable_libarchive || disable_libarchive == '0' || disable_libarchive == 'false') && File.exist?(libarchive_xcframework)
|
|
46
|
+
has_libarchive = true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
vendored = ["ios/Frameworks/sherpa_onnx.xcframework"]
|
|
50
|
+
vendored << "ios/Frameworks/FFmpeg.xcframework" if has_ffmpeg
|
|
51
|
+
vendored << "ios/Frameworks/libarchive.xcframework" if has_libarchive
|
|
52
|
+
|
|
53
|
+
s.vendored_frameworks = vendored
|
|
60
54
|
# Absolute paths so headers are found regardless of PODS_TARGET_SRCROOT (e.g. when building via React Native CLI).
|
|
61
55
|
xcframework_root = File.join(pod_root, "ios", "Frameworks", "sherpa_onnx.xcframework")
|
|
62
56
|
simulator_headers = File.join(xcframework_root, "ios-arm64_x86_64-simulator", "Headers")
|
|
@@ -64,14 +58,54 @@ Pod::Spec.new do |s|
|
|
|
64
58
|
simulator_slice = File.join(xcframework_root, "ios-arm64_x86_64-simulator")
|
|
65
59
|
device_slice = File.join(xcframework_root, "ios-arm64")
|
|
66
60
|
|
|
61
|
+
libarchive_xcframework_root = File.join(pod_root, "ios", "Frameworks", "libarchive.xcframework")
|
|
62
|
+
libarchive_simulator_headers = File.join(libarchive_xcframework_root, "ios-arm64_x86_64-simulator", "Headers")
|
|
63
|
+
libarchive_device_headers = File.join(libarchive_xcframework_root, "ios-arm64", "Headers")
|
|
64
|
+
|
|
65
|
+
ffmpeg_simulator_headers = File.join(ffmpeg_xcframework, "ios-arm64_x86_64-simulator", "Headers")
|
|
66
|
+
ffmpeg_device_headers = File.join(ffmpeg_xcframework, "ios-arm64", "Headers")
|
|
67
|
+
|
|
68
|
+
gcc_defs = '$(inherited) PLATFORM_CONFIG_H=\\"libarchive_darwin_config.h\\"'
|
|
69
|
+
gcc_defs += ' HAVE_FFMPEG=1' if has_ffmpeg
|
|
70
|
+
gcc_defs += ' HAVE_LIBARCHIVE=1' if has_libarchive
|
|
71
|
+
|
|
72
|
+
ld_flags = '$(inherited) -lsherpa-onnx'
|
|
73
|
+
if has_ffmpeg
|
|
74
|
+
ld_flags += ' -lffmpeg -liconv -lbz2'
|
|
75
|
+
end
|
|
76
|
+
if has_libarchive
|
|
77
|
+
ld_flags += ' -larchive'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
header_search_paths = [
|
|
81
|
+
"$(inherited)",
|
|
82
|
+
"\"#{pod_root}/ios\"",
|
|
83
|
+
"\"#{pod_root}/ios/archive\"",
|
|
84
|
+
"\"#{pod_root}/ios/model_detect\"",
|
|
85
|
+
"\"#{pod_root}/ios/stt\"",
|
|
86
|
+
"\"#{pod_root}/ios/tts\"",
|
|
87
|
+
"\"#{pod_root}/ios/online_stt\"",
|
|
88
|
+
"\"#{device_headers}\"",
|
|
89
|
+
"\"#{simulator_headers}\""
|
|
90
|
+
]
|
|
91
|
+
if has_libarchive
|
|
92
|
+
header_search_paths << "\"#{libarchive_device_headers}\""
|
|
93
|
+
header_search_paths << "\"#{libarchive_simulator_headers}\""
|
|
94
|
+
end
|
|
95
|
+
if has_ffmpeg
|
|
96
|
+
header_search_paths << "\"#{ffmpeg_device_headers}\""
|
|
97
|
+
header_search_paths << "\"#{ffmpeg_simulator_headers}\""
|
|
98
|
+
end
|
|
99
|
+
|
|
67
100
|
s.pod_target_xcconfig = {
|
|
68
|
-
"HEADER_SEARCH_PATHS" =>
|
|
69
|
-
"GCC_PREPROCESSOR_DEFINITIONS" =>
|
|
101
|
+
"HEADER_SEARCH_PATHS" => header_search_paths.join(" "),
|
|
102
|
+
"GCC_PREPROCESSOR_DEFINITIONS" => gcc_defs,
|
|
70
103
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
|
71
104
|
"CLANG_CXX_LIBRARY" => "libc++",
|
|
105
|
+
"OTHER_CPLUSPLUSFLAGS" => "$(inherited)",
|
|
72
106
|
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" => "$(inherited) \"#{device_slice}\"",
|
|
73
107
|
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" => "$(inherited) \"#{simulator_slice}\"",
|
|
74
|
-
"OTHER_LDFLAGS" =>
|
|
108
|
+
"OTHER_LDFLAGS" => ld_flags
|
|
75
109
|
}
|
|
76
110
|
|
|
77
111
|
s.user_target_xcconfig = {
|
|
@@ -79,10 +113,10 @@ Pod::Spec.new do |s|
|
|
|
79
113
|
"CLANG_CXX_LIBRARY" => "libc++",
|
|
80
114
|
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" => "$(inherited) \"#{device_slice}\"",
|
|
81
115
|
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" => "$(inherited) \"#{simulator_slice}\"",
|
|
82
|
-
"OTHER_LDFLAGS" =>
|
|
116
|
+
"OTHER_LDFLAGS" => ld_flags
|
|
83
117
|
}
|
|
84
118
|
|
|
85
|
-
s.libraries = "c++", "z"
|
|
119
|
+
s.libraries = "c++", "z", "iconv", "bz2"
|
|
86
120
|
|
|
87
121
|
install_modules_dependencies(s)
|
|
88
|
-
end
|
|
122
|
+
end
|
package/android/build.gradle
CHANGED
|
@@ -103,7 +103,7 @@ android {
|
|
|
103
103
|
jniLibs {
|
|
104
104
|
excludes += [
|
|
105
105
|
"**/libavcodec.so", "**/libavformat.so", "**/libavutil.so",
|
|
106
|
-
"**/libavfilter.so", "**/libswresample.so", "**/libshine.so"
|
|
106
|
+
"**/libavfilter.so", "**/libswresample.so", "**/libshine.so", "**/libopus.so"
|
|
107
107
|
]
|
|
108
108
|
}
|
|
109
109
|
}
|
|
@@ -132,10 +132,16 @@ android {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// Resolve com.xdcobra.sherpa only from this repo (never from JitPack or other app repos).
|
|
135
136
|
repositories {
|
|
137
|
+
exclusiveContent {
|
|
138
|
+
forRepository { maven { url "https://xdcobra.github.io/maven" } }
|
|
139
|
+
filter {
|
|
140
|
+
includeGroup "com.xdcobra.sherpa"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
136
143
|
mavenCentral()
|
|
137
144
|
google()
|
|
138
|
-
maven { url "https://xdcobra.github.io/maven" }
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
// Configurations used by prebuilt-download.gradle: downloadNativeLibsIfNeeded (AAR --> jniLibs + headers),
|
|
@@ -99,12 +99,38 @@ def readReleaseTag = { File tagFile ->
|
|
|
99
99
|
project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
100
100
|
doLast {
|
|
101
101
|
def downloadDir = file("${project.buildDir}/prebuilt-downloads")
|
|
102
|
+
def currentSherpaVersion = project.ext.sherpaOnnxVersion
|
|
103
|
+
def sherpaVersionFile = new File(downloadDir, "sherpa-onnx-version.txt")
|
|
104
|
+
def storedSherpaVersion = (sherpaVersionFile.exists() ? sherpaVersionFile.text.trim() : null)
|
|
105
|
+
def sherpaNeedsUpdate = !hasAllSherpaLibs() || !hasSherpaHeaders() || storedSherpaVersion == null || storedSherpaVersion != currentSherpaVersion
|
|
102
106
|
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
def currentFfmpegVersion = project.ext.ffmpegVersion
|
|
108
|
+
def ffmpegVersionFile = new File(downloadDir, "ffmpeg-version.txt")
|
|
109
|
+
def storedFfmpegVersion = (ffmpegVersionFile.exists() ? ffmpegVersionFile.text.trim() : null)
|
|
110
|
+
def ffmpegNeedsUpdate = !hasAllFfmpegLibs() || !hasFfmpegHeaders() || storedFfmpegVersion == null || storedFfmpegVersion != currentFfmpegVersion
|
|
111
|
+
|
|
112
|
+
def currentLibarchiveVersion = project.ext.libarchiveVersion
|
|
113
|
+
def libarchiveVersionFile = new File(downloadDir, "libarchive-version.txt")
|
|
114
|
+
def storedLibarchiveVersion = (libarchiveVersionFile.exists() ? libarchiveVersionFile.text.trim() : null)
|
|
115
|
+
def libarchiveNeedsUpdate = !hasAllLibarchiveLibs() || !hasLibarchiveHeaders() || storedLibarchiveVersion == null || storedLibarchiveVersion != currentLibarchiveVersion
|
|
116
|
+
|
|
117
|
+
if (hasAllSherpaLibs() && hasSherpaHeaders() && !sherpaNeedsUpdate) {
|
|
118
|
+
println "[sherpa-onnx] Native libs + headers: (1) already present, version ${currentSherpaVersion}"
|
|
119
|
+
}
|
|
120
|
+
if (sherpaNeedsUpdate && storedSherpaVersion != null && storedSherpaVersion != currentSherpaVersion) {
|
|
121
|
+
println "[sherpa-onnx] Version change detected (${storedSherpaVersion} -> ${currentSherpaVersion}), refreshing libs and headers"
|
|
122
|
+
}
|
|
123
|
+
if (ffmpegNeedsUpdate && storedFfmpegVersion != null && storedFfmpegVersion != currentFfmpegVersion) {
|
|
124
|
+
println "[FFmpeg] Version change detected (${storedFfmpegVersion} -> ${currentFfmpegVersion}), refreshing libs and headers"
|
|
125
|
+
}
|
|
126
|
+
if (libarchiveNeedsUpdate && storedLibarchiveVersion != null && storedLibarchiveVersion != currentLibarchiveVersion) {
|
|
127
|
+
println "[libarchive] Version change detected (${storedLibarchiveVersion} -> ${currentLibarchiveVersion}), refreshing libs and headers"
|
|
105
128
|
}
|
|
106
129
|
|
|
107
|
-
|
|
130
|
+
def sherpaUpdatedFromAar = [false]
|
|
131
|
+
def ffmpegUpdatedFromAar = [false]
|
|
132
|
+
def libarchiveUpdatedFromAar = [false]
|
|
133
|
+
if (sherpaNeedsUpdate) {
|
|
108
134
|
try {
|
|
109
135
|
def aarFiles = project.configurations.sherpaOnnxAar.files
|
|
110
136
|
if (!aarFiles.isEmpty()) {
|
|
@@ -127,6 +153,9 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
127
153
|
copy { from fileTree(aarExtractDir) { include 'c-api/**' }; into includeSherpaDir }
|
|
128
154
|
println "Extracted sherpa-onnx C-API headers from Maven AAR"
|
|
129
155
|
}
|
|
156
|
+
downloadDir.mkdirs()
|
|
157
|
+
sherpaVersionFile.text = currentSherpaVersion
|
|
158
|
+
sherpaUpdatedFromAar[0] = true
|
|
130
159
|
println "[sherpa-onnx] Native libs + headers: (2) Maven AAR (${aar.name})"
|
|
131
160
|
}
|
|
132
161
|
} catch (Exception e) {
|
|
@@ -134,7 +163,7 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
134
163
|
}
|
|
135
164
|
}
|
|
136
165
|
|
|
137
|
-
if (!sherpaOnnxDisableFfmpeg &&
|
|
166
|
+
if (!sherpaOnnxDisableFfmpeg && ffmpegNeedsUpdate) {
|
|
138
167
|
try {
|
|
139
168
|
def aarFiles = project.configurations.ffmpegAar.files
|
|
140
169
|
if (!aarFiles.isEmpty()) {
|
|
@@ -157,6 +186,9 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
157
186
|
copy { from aarIncludeDir; into ffmpegIncludeDir }
|
|
158
187
|
println "Extracted FFmpeg headers from Maven AAR"
|
|
159
188
|
}
|
|
189
|
+
downloadDir.mkdirs()
|
|
190
|
+
ffmpegVersionFile.text = currentFfmpegVersion
|
|
191
|
+
ffmpegUpdatedFromAar[0] = true
|
|
160
192
|
println "[FFmpeg] Native libs + headers: (2) Maven AAR (${aar.name})"
|
|
161
193
|
}
|
|
162
194
|
} catch (Exception e) {
|
|
@@ -164,7 +196,7 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
164
196
|
}
|
|
165
197
|
}
|
|
166
198
|
|
|
167
|
-
if (!sherpaOnnxDisableLibarchive &&
|
|
199
|
+
if (!sherpaOnnxDisableLibarchive && libarchiveNeedsUpdate) {
|
|
168
200
|
try {
|
|
169
201
|
def aarFiles = project.configurations.libarchiveAar.files
|
|
170
202
|
if (!aarFiles.isEmpty()) {
|
|
@@ -187,6 +219,9 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
187
219
|
copy { from aarIncludeDir; into libarchiveIncludeDir }
|
|
188
220
|
println "Extracted libarchive headers from Maven AAR"
|
|
189
221
|
}
|
|
222
|
+
downloadDir.mkdirs()
|
|
223
|
+
libarchiveVersionFile.text = currentLibarchiveVersion
|
|
224
|
+
libarchiveUpdatedFromAar[0] = true
|
|
190
225
|
println "[libarchive] Native libs + headers: (2) Maven AAR (${aar.name})"
|
|
191
226
|
}
|
|
192
227
|
} catch (Exception e) {
|
|
@@ -226,14 +261,27 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
226
261
|
|
|
227
262
|
def repo = project.findProperty('prebuiltGitHubRepo') ?: getGitHubRepo()
|
|
228
263
|
if (!repo) {
|
|
229
|
-
def needFfmpeg = !sherpaOnnxDisableFfmpeg &&
|
|
230
|
-
def needLibarchive = !sherpaOnnxDisableLibarchive &&
|
|
231
|
-
|
|
264
|
+
def needFfmpeg = !sherpaOnnxDisableFfmpeg && ffmpegNeedsUpdate && !ffmpegUpdatedFromAar[0]
|
|
265
|
+
def needLibarchive = !sherpaOnnxDisableLibarchive && libarchiveNeedsUpdate && !libarchiveUpdatedFromAar[0]
|
|
266
|
+
def needSherpa = sherpaNeedsUpdate && !sherpaUpdatedFromAar[0]
|
|
267
|
+
if (needFfmpeg || needLibarchive || needSherpa) {
|
|
268
|
+
def diag = [
|
|
269
|
+
"prebuiltGitHubRepo=${project.findProperty('prebuiltGitHubRepo') ?: '(not set)'}",
|
|
270
|
+
"git remote origin=${getGitHubRepo() ?: '(not a GitHub URL or git unavailable)'}",
|
|
271
|
+
"sherpaOnnxDisableFfmpeg=${sherpaOnnxDisableFfmpeg}",
|
|
272
|
+
"sherpaOnnxDisableLibarchive=${sherpaOnnxDisableLibarchive}",
|
|
273
|
+
"sherpaNeedsUpdate=${sherpaNeedsUpdate} sherpaUpdatedFromAar=${sherpaUpdatedFromAar[0]}",
|
|
274
|
+
"ffmpegNeedsUpdate=${ffmpegNeedsUpdate} ffmpegUpdatedFromAar=${ffmpegUpdatedFromAar[0]}",
|
|
275
|
+
"libarchiveNeedsUpdate=${libarchiveNeedsUpdate} libarchiveUpdatedFromAar=${libarchiveUpdatedFromAar[0]}",
|
|
276
|
+
"needFfmpeg=${needFfmpeg} needLibarchive=${needLibarchive} needSherpa=${needSherpa}"
|
|
277
|
+
].join(", ")
|
|
232
278
|
throw new RuntimeException(
|
|
233
|
-
"Native libs/headers still missing and GitHub repo unknown.
|
|
279
|
+
"Native libs/headers still missing and GitHub repo unknown. " +
|
|
280
|
+
"Set -PprebuiltGitHubRepo=owner/repo or ensure git remote origin is a GitHub URL. " +
|
|
234
281
|
"Alternatively run third_party/ffmpeg_prebuilt/copy_prebuilts_to_sdk.js, third_party/sherpa-onnx-prebuilt/copy_prebuilts_to_sdk.js, third_party/libarchive_prebuilt/copy_prebuilts_to_sdk.js, or use Maven (com.xdcobra.sherpa:ffmpeg / sherpa-onnx / libarchive), or ensure ANDROID_RELEASE_TAG releases exist. " +
|
|
235
282
|
(sherpaOnnxDisableFfmpeg ? "(FFmpeg disabled via sherpaOnnxDisableFfmpeg=true.) " : "") +
|
|
236
|
-
(sherpaOnnxDisableLibarchive ? "(libarchive disabled via sherpaOnnxDisableLibarchive=true.)" : "")
|
|
283
|
+
(sherpaOnnxDisableLibarchive ? "(libarchive disabled via sherpaOnnxDisableLibarchive=true.) " : "") +
|
|
284
|
+
"Diagnostics: [${diag}]"
|
|
237
285
|
)
|
|
238
286
|
}
|
|
239
287
|
return
|
|
@@ -241,13 +289,13 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
241
289
|
def baseUrl = "https://github.com/${repo}/releases/download"
|
|
242
290
|
downloadDir.mkdirs()
|
|
243
291
|
|
|
244
|
-
if (!sherpaOnnxDisableFfmpeg &&
|
|
292
|
+
if (!sherpaOnnxDisableFfmpeg && ffmpegNeedsUpdate && !ffmpegUpdatedFromAar[0]) {
|
|
245
293
|
def tagFile = file("${project.projectDir.parent}/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG")
|
|
246
294
|
def tag = readReleaseTag(tagFile)
|
|
247
295
|
if (!tag) throw new RuntimeException("Missing or empty third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG")
|
|
248
296
|
def zipFile = new File(downloadDir, "ffmpeg-android.zip")
|
|
249
297
|
def url = "${baseUrl}/${tag}/ffmpeg-android.zip"
|
|
250
|
-
exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
298
|
+
project.exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
251
299
|
if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
|
|
252
300
|
def ffmpegExtractDir = new File(downloadDir, "ffmpeg-extract")
|
|
253
301
|
if (ffmpegExtractDir.exists()) ffmpegExtractDir.deleteDir()
|
|
@@ -262,16 +310,18 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
262
310
|
if (ffmpegIncludeInZip.exists()) {
|
|
263
311
|
copy { from fileTree(ffmpegIncludeInZip); into ffmpegIncludeDir }
|
|
264
312
|
}
|
|
313
|
+
downloadDir.mkdirs()
|
|
314
|
+
ffmpegVersionFile.text = currentFfmpegVersion
|
|
265
315
|
println "Downloaded and extracted FFmpeg prebuilts (libs + include) from ${tag}"
|
|
266
316
|
}
|
|
267
317
|
|
|
268
|
-
if (!sherpaOnnxDisableLibarchive &&
|
|
318
|
+
if (!sherpaOnnxDisableLibarchive && libarchiveNeedsUpdate && !libarchiveUpdatedFromAar[0]) {
|
|
269
319
|
def tagFile = file("${project.projectDir.parent}/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG")
|
|
270
320
|
def tag = readReleaseTag(tagFile)
|
|
271
321
|
if (!tag) throw new RuntimeException("Missing or empty third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG")
|
|
272
322
|
def zipFile = new File(downloadDir, "libarchive-android.zip")
|
|
273
323
|
def url = "${baseUrl}/${tag}/libarchive-android.zip"
|
|
274
|
-
exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
324
|
+
project.exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
275
325
|
if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
|
|
276
326
|
def libarchiveExtractDir = new File(downloadDir, "libarchive-extract")
|
|
277
327
|
if (libarchiveExtractDir.exists()) libarchiveExtractDir.deleteDir()
|
|
@@ -287,16 +337,18 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
287
337
|
libarchiveIncludeDir.mkdirs()
|
|
288
338
|
copy { from libarchiveIncludeInZip; into libarchiveIncludeDir }
|
|
289
339
|
}
|
|
340
|
+
downloadDir.mkdirs()
|
|
341
|
+
libarchiveVersionFile.text = currentLibarchiveVersion
|
|
290
342
|
println "Downloaded and extracted libarchive prebuilts (libs + include) from ${tag}"
|
|
291
343
|
}
|
|
292
344
|
|
|
293
|
-
if (
|
|
345
|
+
if (sherpaNeedsUpdate && !sherpaUpdatedFromAar[0]) {
|
|
294
346
|
def tagFile = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG")
|
|
295
347
|
def tag = readReleaseTag(tagFile)
|
|
296
348
|
if (!tag) throw new RuntimeException("Missing or empty third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG")
|
|
297
349
|
def zipFile = new File(downloadDir, "sherpa-onnx-android.zip")
|
|
298
350
|
def url = "${baseUrl}/${tag}/sherpa-onnx-android.zip"
|
|
299
|
-
exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
351
|
+
project.exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
|
|
300
352
|
if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
|
|
301
353
|
def sherpaExtractDir = new File(downloadDir, "sherpa-onnx-extract")
|
|
302
354
|
if (sherpaExtractDir.exists()) sherpaExtractDir.deleteDir()
|
|
@@ -319,6 +371,8 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
|
|
|
319
371
|
sherpaOnnxClassesDir.mkdirs()
|
|
320
372
|
copy { from sherpaJavaJar; into sherpaOnnxClassesDir }
|
|
321
373
|
}
|
|
374
|
+
downloadDir.mkdirs()
|
|
375
|
+
sherpaVersionFile.text = currentSherpaVersion
|
|
322
376
|
println "[sherpa-onnx] Native libs + headers: (3) GitHub release (${tag})"
|
|
323
377
|
} else {
|
|
324
378
|
def sherpaClassesJar = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/android/java/classes.jar")
|