2 |
3 | # Whisper GGML
4 |
5 | _OpenAI Whisper ASR (Automatic Speech Recognition) for Flutter using [Whisper.cpp](https://github.com/ggerganov/whisper.cpp)._
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Supported platforms
17 |
18 |
19 | | Platform | Supported |
20 | |-----------|-----------|
21 | | Android | ✅ |
22 | | iOS | ✅ |
23 | | MacOS | ✅ |
24 |
25 |
26 | ## Features
27 |
28 |
29 |
30 | - Automatic Speech Recognition integration for Flutter apps.
31 |
32 | - Supports automatic model downloading and initialization. Can be configured to work fully offline by using `assets` models (see example folder).
33 |
34 | - Seamless iOS and Android support with optimized performance.
35 |
36 | - Can be configured to use specific language ("en", "fr", "de", etc) or auto-detect ("auto").
37 |
38 | - Utilizes [CORE ML](https://github.com/ggml-org/whisper.cpp/tree/master?tab=readme-ov-file#core-ml-support) for enhanced processing on iOS devices.
39 |
40 |
41 |
42 | ## Installation
43 |
44 |
45 |
46 | To use this library in your Flutter project, follow these steps:
47 |
48 |
49 |
50 | 1. Add the library to your Flutter project's `pubspec.yaml`:
51 |
52 | ```yaml
53 | dependencies:
54 | whisper_ggml: ^1.7.0
55 | ```
56 |
57 | 2. Run `flutter pub get` to install the package.
58 |
59 |
60 |
61 | ## Usage
62 |
63 |
64 |
65 | To integrate Whisper ASR in your Flutter app:
66 |
67 |
68 |
69 | 1. Import the package:
70 |
71 | ```dart
72 | import 'package:whisper_ggml/whisper_ggml.dart';
73 | ```
74 |
75 |
76 |
77 | 2. Pick your model. Smaller models are more performant, but the accuracy may be lower. Recommended models are `tiny` and `small`.
78 |
79 | ```dart
80 | final model = WhisperModel.tiny;
81 | ```
82 |
83 | 3. Declare `WhisperController` and use it for transcription:
84 |
85 | ```dart
86 | final controller = WhisperController();
87 |
88 | final result = await controller.transcribe(
89 | model: model, /// Selected WhisperModel
90 | audioPath: audioPath, /// Path to .wav file
91 | lang: 'en', /// Language to transcribe
92 | );
93 | ```
94 |
95 | 4. Use the `result` variable to access the transcription result:
96 |
97 | ```dart
98 | if (result?.transcription.text != null) {
99 | /// Do something with the transcription
100 | print(result!.transcription.text);
101 | }
102 | ```
103 |
104 |
105 |
106 | ## Notes
107 |
108 |
109 |
110 | Transcription processing time is about `5x` times faster when running in release mode.
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/lib/src/whisper.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:ffi';
3 | import 'dart:isolate';
4 |
5 | import 'package:ffi/ffi.dart';
6 | import 'package:flutter/foundation.dart';
7 | import 'package:universal_io/io.dart';
8 | import 'package:whisper_ggml/src/models/whisper_model.dart';
9 | import 'package:whisper_ggml/src/whisper_audio_convert.dart';
10 |
11 | import 'models/requests/transcribe_request.dart';
12 | import 'models/requests/transcribe_request_dto.dart';
13 | import 'models/requests/version_request.dart';
14 | import 'models/responses/whisper_transcribe_response.dart';
15 | import 'models/responses/whisper_version_response.dart';
16 | import 'models/whisper_dto.dart';
17 |
18 | export 'models/_models.dart';
19 | export 'whisper_audio_convert.dart';
20 |
21 | /// Native request type
22 | typedef WReqNative = Pointer