From b38c7fdc8dfba09e43286b937f922817d9ce05bc Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Thu, 23 Nov 2023 16:59:30 -0800 Subject: [PATCH] v2.0 flutter (#303) --- binding/flutter/CHANGELOG.md | 4 + binding/flutter/README.md | 2 +- binding/flutter/android/build.gradle | 10 +- .../flutter/leopard/LeopardPlugin.java | 7 +- .../ios/Classes/SwiftLeopardPlugin.swift | 9 +- binding/flutter/ios/leopard_flutter.podspec | 6 +- binding/flutter/lib/leopard.dart | 20 +- binding/flutter/lib/leopard_transcript.dart | 3 +- binding/flutter/pubspec.yaml | 2 +- demo/flutter/android/build.gradle | 6 + demo/flutter/integration_test/app_test.dart | 230 +++++++++--------- demo/flutter/ios/Podfile | 4 +- demo/flutter/ios/Podfile.lock | 52 ---- demo/flutter/lib/main.dart | 14 +- demo/flutter/pubspec.lock | 60 ++--- demo/flutter/pubspec.yaml | 3 +- demo/flutter/scripts/prepare_demo.dart | 2 +- 17 files changed, 213 insertions(+), 221 deletions(-) delete mode 100644 demo/flutter/ios/Podfile.lock diff --git a/binding/flutter/CHANGELOG.md b/binding/flutter/CHANGELOG.md index ca716676..151d54c7 100644 --- a/binding/flutter/CHANGELOG.md +++ b/binding/flutter/CHANGELOG.md @@ -18,3 +18,7 @@ ## [1.2.1] - 2023-08-25 * Native packages updated + +## [2.0.0] - 2023-11-15 +* Engine improvements +* Improved error reporting diff --git a/binding/flutter/README.md b/binding/flutter/README.md index 8e4b333b..2924e4d0 100644 --- a/binding/flutter/README.md +++ b/binding/flutter/README.md @@ -20,7 +20,7 @@ Leopard is an on-device speech-to-text engine. Leopard is: This binding is for running Leopard on **Flutter 2.8.1+** on the following platforms: - Android 5.0+ (API 21+) -- iOS 11.0+ +- iOS 13.0+ ## Installation diff --git a/binding/flutter/android/build.gradle b/binding/flutter/android/build.gradle index 149a7da0..8e507959 100644 --- a/binding/flutter/android/build.gradle +++ b/binding/flutter/android/build.gradle @@ -1,10 +1,13 @@ group 'ai.picovoice.flutter.leopard' -version '1.2.1' +version '2.0.0' buildscript { repositories { google() mavenCentral() + maven { + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1299/' + } } dependencies { @@ -16,6 +19,9 @@ rootProject.allprojects { repositories { google() mavenCentral() + maven { + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1305/' + } } } @@ -33,5 +39,5 @@ android { } dependencies { - implementation 'ai.picovoice:leopard-android:1.2.1' + implementation 'ai.picovoice:leopard-android:2.0.0' } diff --git a/binding/flutter/android/src/main/java/ai/picovoice/flutter/leopard/LeopardPlugin.java b/binding/flutter/android/src/main/java/ai/picovoice/flutter/leopard/LeopardPlugin.java index 68c3159a..e0f73c9a 100644 --- a/binding/flutter/android/src/main/java/ai/picovoice/flutter/leopard/LeopardPlugin.java +++ b/binding/flutter/android/src/main/java/ai/picovoice/flutter/leopard/LeopardPlugin.java @@ -44,6 +44,8 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBindin flutterContext = flutterPluginBinding.getApplicationContext(); channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "leopard"); channel.setMethodCallHandler(this); + + Leopard.setSdk("flutter"); } @Override @@ -90,11 +92,13 @@ private void leopardCreate(@NonNull MethodCall call, @NonNull Result result) { String accessKey = call.argument("accessKey"); String modelPath = call.argument("modelPath"); boolean enableAutomaticPunctuation = call.argument("enableAutomaticPunctuation"); + boolean enableDiarization = call.argument("enableDiarization"); Leopard.Builder leopardBuilder = new Leopard.Builder() .setAccessKey(accessKey) .setModelPath(modelPath) - .setEnableAutomaticPunctuation(enableAutomaticPunctuation); + .setEnableAutomaticPunctuation(enableAutomaticPunctuation) + .setEnableDiarization(enableDiarization); Leopard leopard = leopardBuilder.build(flutterContext); leopardPool.put(String.valueOf(System.identityHashCode(leopard)), leopard); @@ -217,6 +221,7 @@ private Map leopardTranscriptToMap(LeopardTranscript result) { wordMap.put("confidence", word.getConfidence()); wordMap.put("startSec", word.getStartSec()); wordMap.put("endSec", word.getEndSec()); + wordMap.put("speakerTag", word.getSpeakerTag()); words.add(wordMap); } resultMap.put("words", words); diff --git a/binding/flutter/ios/Classes/SwiftLeopardPlugin.swift b/binding/flutter/ios/Classes/SwiftLeopardPlugin.swift index be9ce35d..116c0e77 100644 --- a/binding/flutter/ios/Classes/SwiftLeopardPlugin.swift +++ b/binding/flutter/ios/Classes/SwiftLeopardPlugin.swift @@ -1,5 +1,5 @@ // -// Copyright 2022 Picovoice Inc. +// Copyright 2022-2023 Picovoice Inc. // // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. @@ -28,6 +28,8 @@ public class SwiftLeopardPlugin: NSObject, FlutterPlugin { let methodChannel = FlutterMethodChannel(name: "leopard", binaryMessenger: registrar.messenger()) registrar.addMethodCallDelegate(instance, channel: methodChannel) + + Leopard.setSdk(sdk: "flutter") } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { @@ -44,11 +46,13 @@ public class SwiftLeopardPlugin: NSObject, FlutterPlugin { if let accessKey = args["accessKey"] as? String, let modelPath = args["modelPath"] as? String { let enableAutomaticPunctuation = args["enableAutomaticPunctuation"] as? Bool + let enableDiarization = args["enableDiarization"] as? Bool let leopard = try Leopard( accessKey: accessKey, modelPath: modelPath, - enableAutomaticPunctuation: enableAutomaticPunctuation ?? false + enableAutomaticPunctuation: enableAutomaticPunctuation ?? false, + enableDiarization: enableDiarization ?? false ) let handle: String = String(describing: leopard) @@ -137,6 +141,7 @@ public class SwiftLeopardPlugin: NSObject, FlutterPlugin { wordMap["confidence"] = wordMeta.confidence wordMap["startSec"] = wordMeta.startSec wordMap["endSec"] = wordMeta.endSec + wordMap["speakerTag"] = wordMeta.speakerTag wordMapArray.append(wordMap) } resultDictionary["words"] = wordMapArray diff --git a/binding/flutter/ios/leopard_flutter.podspec b/binding/flutter/ios/leopard_flutter.podspec index a072c251..fbdd542c 100644 --- a/binding/flutter/ios/leopard_flutter.podspec +++ b/binding/flutter/ios/leopard_flutter.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'leopard_flutter' - s.version = '1.2.1' + s.version = '2.0.0' s.summary = 'A Flutter package plugin for Picovoice\'s Leopard Speech-to-Text engine' s.description = <<-DESC A Flutter package plugin for Picovoice\'s Leopard Speech-to-Text engine @@ -10,9 +10,9 @@ Pod::Spec.new do |s| s.author = { 'Picovoice' => 'hello@picovoice.ai' } s.source = { :git => "https://github.com/Picovoice/leopard.git" } s.source_files = 'Classes/**/*' - s.platform = :ios, '11.0' + s.platform = :ios, '13.0' s.dependency 'Flutter' - s.dependency 'Leopard-iOS', '~> 1.2.0' + s.dependency 'Leopard-iOS', '~> 2.0.0' s.swift_version = '5.0' end diff --git a/binding/flutter/lib/leopard.dart b/binding/flutter/lib/leopard.dart index 7e3ae686..8890310c 100644 --- a/binding/flutter/lib/leopard.dart +++ b/binding/flutter/lib/leopard.dart @@ -1,5 +1,5 @@ // -// Copyright 2022 Picovoice Inc. +// Copyright 2022-2023 Picovoice Inc. // // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. @@ -38,11 +38,18 @@ class Leopard { /// /// [enableAutomaticPunctuation] (Optional) Set to `true` to enable automatic punctuation insertion. /// + /// [enableDiarization] (Optional) Set to `true` to enable speaker diarization, which allows Leopard to + /// differentiate speakers as part of the transcription process. Word + /// metadata will include a `speaker_tag` to identify unique speakers. + /// /// Throws a `LeopardException` if not initialized correctly /// /// returns an instance of the Leopard Speech-to-Text engine static Future create(String accessKey, String modelPath, - {enableAutomaticPunctuation = false}) async { + { + enableAutomaticPunctuation = false, + enableDiarization = false + }) async { modelPath = await _tryExtractFlutterAsset(modelPath); try { @@ -50,7 +57,8 @@ class Leopard { Map.from(await _channel.invokeMethod('create', { 'accessKey': accessKey, 'modelPath': modelPath, - 'enableAutomaticPunctuation': enableAutomaticPunctuation + 'enableAutomaticPunctuation': enableAutomaticPunctuation, + 'enableDiarization': enableDiarization })); return Leopard._( @@ -129,7 +137,11 @@ class Leopard { List words = []; for (dynamic word in result['words']) { words.add(LeopardWord( - word['word'], word['startSec'], word['endSec'], word['confidence'])); + word['word'], + word['startSec'], + word['endSec'], + word['confidence'], + word['speakerTag'])); } return LeopardTranscript(transcript, words); } diff --git a/binding/flutter/lib/leopard_transcript.dart b/binding/flutter/lib/leopard_transcript.dart index 1b69053a..c8ea598f 100644 --- a/binding/flutter/lib/leopard_transcript.dart +++ b/binding/flutter/lib/leopard_transcript.dart @@ -26,8 +26,9 @@ class LeopardWord { final double startSec; final double endSec; final double confidence; + final int speakerTag; - LeopardWord(this._word, this.startSec, this.endSec, this.confidence); + LeopardWord(this._word, this.startSec, this.endSec, this.confidence, this.speakerTag); String get word => _word ?? ""; } diff --git a/binding/flutter/pubspec.yaml b/binding/flutter/pubspec.yaml index 8ca91fb5..fc9d3395 100644 --- a/binding/flutter/pubspec.yaml +++ b/binding/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: leopard_flutter description: A Flutter plugin for Picovoice's Leopard Speech-to-Text engine -version: 1.2.1 +version: 2.0.0 homepage: https://picovoice.ai/ repository: https://github.com/Picovoice/leopard/ documentation: https://picovoice.ai/docs/leopard/ diff --git a/demo/flutter/android/build.gradle b/demo/flutter/android/build.gradle index fab3c2e1..9a44c7db 100644 --- a/demo/flutter/android/build.gradle +++ b/demo/flutter/android/build.gradle @@ -2,6 +2,9 @@ buildscript { repositories { google() jcenter() + maven { + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1305/' + } } dependencies { @@ -13,6 +16,9 @@ allprojects { repositories { google() jcenter() + maven { + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1305/' + } } } diff --git a/demo/flutter/integration_test/app_test.dart b/demo/flutter/integration_test/app_test.dart index 064e698b..140ae40e 100644 --- a/demo/flutter/integration_test/app_test.dart +++ b/demo/flutter/integration_test/app_test.dart @@ -95,21 +95,20 @@ void main() { } Future validateMetadata( - List words, String transcript, double audioLength) async { - String normTranscript = transcript.toUpperCase(); + List words, + List expectedWords, + bool enableDiarization) async { + expect(words.length, expectedWords.length); for (var i = 0; i < words.length; i++) { - LeopardWord word = words[i]; - expect(normTranscript, contains(word.word.toUpperCase())); - expect(word.startSec, greaterThan(0)); - expect(word.startSec, lessThanOrEqualTo(word.endSec)); - if (i < (words.length - 1)) { - LeopardWord nextWord = words[i + 1]; - expect(word.endSec, lessThanOrEqualTo(nextWord.startSec)); + expect(words[i].word, expectedWords[i]["word"]); + expect(words[i].startSec, closeTo(expectedWords[i]["start_sec"], 0.01)); + expect(words[i].endSec, closeTo(expectedWords[i]["end_sec"], 0.01)); + expect(words[i].confidence, closeTo(expectedWords[i]["confidence"], 0.01)); + if (enableDiarization) { + expect(words[i].speakerTag, expectedWords[i]["speaker_tag"]); + } else { + expect(words[i].speakerTag, -1); } - expect(word.endSec, lessThanOrEqualTo(audioLength)); - - expect(word.confidence, greaterThanOrEqualTo(0)); - expect(word.confidence, lessThanOrEqualTo(1)); } } @@ -124,143 +123,142 @@ void main() { Future runLeopardProcess( String language, - String transcript, - List punctuations, - bool testPunctuations, + String expectedTranscript, + List expectedWords, double errorRate, - String audioFile) async { + String audioFile, + { + bool asFile = false, + bool enableAutomaticPunctuation = false, + bool enableDiarization = false + }) async { String modelPath = getModelPath(language); - String normTranscript = transcript; - if (!testPunctuations) { - for (var p in punctuations) { - normTranscript = normTranscript.replaceAll(p, ""); - } - } - Leopard leopard; try { - leopard = await Leopard.create(accessKey, modelPath, - enableAutomaticPunctuation: testPunctuations); + leopard = await Leopard.create(accessKey, + modelPath, + enableAutomaticPunctuation: enableAutomaticPunctuation, + enableDiarization: enableDiarization + ); } on LeopardException catch (ex) { expect(ex, equals(null), - reason: "Failed to initialize Leopard for $language: $ex"); + reason: "Failed to initialize Leopard for $language: ${ex.message}"); return; } - List pcm = await loadAudioFile(audioFile); - LeopardTranscript res = await leopard.process(pcm); - - leopard.delete(); - - expect(characterErrorRate(res.transcript, normTranscript), - lessThanOrEqualTo(errorRate), - reason: "Character error rate for $language was incorrect"); - await validateMetadata( - res.words, res.transcript, pcm.length / leopard.sampleRate); - } - - Future runLeopardProcessFile( - String language, - String transcript, - List punctuations, - bool testPunctuations, - double errorRate, - String audioFile) async { - String modelPath = getModelPath(language); - - String normTranscript = transcript; - if (!testPunctuations) { - for (var p in punctuations) { - normTranscript = normTranscript.replaceAll(p, ""); - } + LeopardTranscript res; + if (asFile) { + String audioPath = await extractAudioFile(audioFile); + res = await leopard.processFile(audioPath); + } else { + List pcm = await loadAudioFile(audioFile); + res = await leopard.process(pcm); } - Leopard leopard; - try { - leopard = await Leopard.create(accessKey, modelPath, - enableAutomaticPunctuation: testPunctuations); - } on LeopardException catch (ex) { - expect(ex, equals(null), - reason: "Failed to initialize Leopard for $language: $ex"); - return; - } - - String audioPath = await extractAudioFile(audioFile); - LeopardTranscript res = await leopard.processFile(audioPath); - leopard.delete(); - List pcm = await loadAudioFile(audioFile); - expect(characterErrorRate(res.transcript, normTranscript), + expect(characterErrorRate(res.transcript, expectedTranscript), lessThanOrEqualTo(errorRate), reason: "Character error rate for $language was incorrect"); - await validateMetadata( - res.words, res.transcript, pcm.length / leopard.sampleRate); + await validateMetadata(res.words, expectedWords, enableDiarization); } testWidgets('Test process all languages', (tester) async { - for (int t = 0; t < testData['tests']['parameters'].length; t++) { - String language = testData['tests']['parameters'][t]['language']; - String transcript = testData['tests']['parameters'][t]['transcript']; - List punctuationsRaw = - testData['tests']['parameters'][t]['punctuations']; - List punctuations = - punctuationsRaw.map((p) => p.toString()).toList(); - double errorRate = testData['tests']['parameters'][t]['error_rate']; - String audioFile = testData['tests']['parameters'][t]['audio_file']; + for (int t = 0; t < testData['tests']['language_tests'].length; t++) { + String language = testData['tests']['language_tests'][t]['language']; + String transcript = testData['tests']['language_tests'][t]['transcript']; + List expectedWords = testData['tests']['language_tests'][t]['words']; + double errorRate = testData['tests']['language_tests'][t]['error_rate']; + String audioFile = testData['tests']['language_tests'][t]['audio_file']; await runLeopardProcess( - language, transcript, punctuations, false, errorRate, audioFile); + language, transcript, expectedWords, errorRate, audioFile); } }); testWidgets('Test process all languages with punctuation', (tester) async { - for (int t = 0; t < testData['tests']['parameters'].length; t++) { - String language = testData['tests']['parameters'][t]['language']; - String transcript = testData['tests']['parameters'][t]['transcript']; - List punctuationsRaw = - testData['tests']['parameters'][t]['punctuations']; - List punctuations = - punctuationsRaw.map((p) => p.toString()).toList(); - double errorRate = testData['tests']['parameters'][t]['error_rate']; - String audioFile = testData['tests']['parameters'][t]['audio_file']; + for (int t = 0; t < testData['tests']['language_tests'].length; t++) { + String language = testData['tests']['language_tests'][t]['language']; + String transcriptWithPunctuation = testData['tests']['language_tests'][t]['transcript_with_punctuation']; + List expectedWords = testData['tests']['language_tests'][t]['words']; + double errorRate = testData['tests']['language_tests'][t]['error_rate']; + String audioFile = testData['tests']['language_tests'][t]['audio_file']; await runLeopardProcess( - language, transcript, punctuations, true, errorRate, audioFile); + language, + transcriptWithPunctuation, + expectedWords, + errorRate, + audioFile, + enableAutomaticPunctuation: true); } }); testWidgets('Test process file all languages', (tester) async { - for (int t = 0; t < testData['tests']['parameters'].length; t++) { - String language = testData['tests']['parameters'][t]['language']; - String transcript = testData['tests']['parameters'][t]['transcript']; - List punctuationsRaw = - testData['tests']['parameters'][t]['punctuations']; - List punctuations = - punctuationsRaw.map((p) => p.toString()).toList(); - double errorRate = testData['tests']['parameters'][t]['error_rate']; - String audioFile = testData['tests']['parameters'][t]['audio_file']; - - await runLeopardProcessFile( - language, transcript, punctuations, false, errorRate, audioFile); + for (int t = 0; t < testData['tests']['language_tests'].length; t++) { + String language = testData['tests']['language_tests'][t]['language']; + String transcript = testData['tests']['language_tests'][t]['transcript']; + List expectedWords = testData['tests']['language_tests'][t]['words']; + double errorRate = testData['tests']['language_tests'][t]['error_rate']; + String audioFile = testData['tests']['language_tests'][t]['audio_file']; + + await runLeopardProcess( + language, + transcript, + expectedWords, + errorRate, + audioFile, + asFile: true); } }); - testWidgets('Test process file all languages with punctuation', - (tester) async { - for (int t = 0; t < testData['tests']['parameters'].length; t++) { - String language = testData['tests']['parameters'][t]['language']; - String transcript = testData['tests']['parameters'][t]['transcript']; - List punctuationsRaw = - testData['tests']['parameters'][t]['punctuations']; - List punctuations = - punctuationsRaw.map((p) => p.toString()).toList(); - double errorRate = testData['tests']['parameters'][t]['error_rate']; - String audioFile = testData['tests']['parameters'][t]['audio_file']; - - await runLeopardProcessFile( - language, transcript, punctuations, true, errorRate, audioFile); + testWidgets('Test process file all languages with diarization', (tester) async { + for (int t = 0; t < testData['tests']['language_tests'].length; t++) { + String language = testData['tests']['language_tests'][t]['language']; + String transcript = testData['tests']['language_tests'][t]['transcript']; + List expectedWords = testData['tests']['language_tests'][t]['words']; + double errorRate = testData['tests']['language_tests'][t]['error_rate']; + String audioFile = testData['tests']['language_tests'][t]['audio_file']; + + await runLeopardProcess( + language, + transcript, + expectedWords, + errorRate, + audioFile, + enableDiarization: true); + } + }); + + testWidgets('Test diarization with multiple speakers', (tester) async { + for (int t = 0; t < testData['tests']['diarization_tests'].length; t++) { + String language = testData['tests']['diarization_tests'][t]['language']; + List expectedWords = testData['tests']['diarization_tests'][t]['words']; + String audioFile = testData['tests']['diarization_tests'][t]['audio_file']; + + String modelPath = getModelPath(language); + Leopard leopard; + try { + leopard = await Leopard.create(accessKey, + modelPath, + enableDiarization: true + ); + } on LeopardException catch (ex) { + expect(ex, equals(null), + reason: "Failed to initialize Leopard for $language: ${ex.message}"); + return; + } + + String audioPath = await extractAudioFile(audioFile); + LeopardTranscript res = await leopard.processFile(audioPath); + leopard.delete(); + + expect(res.words.length, expectedWords.length); + for (var i = 0; i < res.words.length; i++) { + expect(res.words[i].word, expectedWords[i]["word"]); + expect(res.words[i].speakerTag, expectedWords[i]["speaker_tag"]); + } } }); }); diff --git a/demo/flutter/ios/Podfile b/demo/flutter/ios/Podfile index 313ea4a1..f579b75e 100644 --- a/demo/flutter/ios/Podfile +++ b/demo/flutter/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -28,6 +28,8 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe flutter_ios_podfile_setup target 'Runner' do + pod 'Leopard-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/leopard/v2.0/binding/ios/Leopard-iOS.podspec' + use_frameworks! use_modular_headers! diff --git a/demo/flutter/ios/Podfile.lock b/demo/flutter/ios/Podfile.lock deleted file mode 100644 index fbd788bc..00000000 --- a/demo/flutter/ios/Podfile.lock +++ /dev/null @@ -1,52 +0,0 @@ -PODS: - - Flutter (1.0.0) - - flutter_voice_processor (1.1.0): - - Flutter - - ios-voice-processor (~> 1.1.0) - - integration_test (0.0.1): - - Flutter - - ios-voice-processor (1.1.0) - - Leopard-iOS (1.2.0) - - leopard_flutter (1.2.1): - - Flutter - - Leopard-iOS (~> 1.2.0) - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - -DEPENDENCIES: - - Flutter (from `Flutter`) - - flutter_voice_processor (from `.symlinks/plugins/flutter_voice_processor/ios`) - - integration_test (from `.symlinks/plugins/integration_test/ios`) - - leopard_flutter (from `.symlinks/plugins/leopard_flutter/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - -SPEC REPOS: - trunk: - - ios-voice-processor - - Leopard-iOS - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - flutter_voice_processor: - :path: ".symlinks/plugins/flutter_voice_processor/ios" - integration_test: - :path: ".symlinks/plugins/integration_test/ios" - leopard_flutter: - :path: ".symlinks/plugins/leopard_flutter/ios" - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/ios" - -SPEC CHECKSUMS: - Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - flutter_voice_processor: 53afbf59ad3feb82f4a379fea9ed8dc98495210f - integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5 - ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 - Leopard-iOS: 993bdc6fbdaabfdaa0ddc5def9bd4405abb59bef - leopard_flutter: ff034f74398123f3ac16ea21cd4b77dc81b92341 - path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 - -PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d - -COCOAPODS: 1.11.3 diff --git a/demo/flutter/lib/main.dart b/demo/flutter/lib/main.dart index e3bd3f23..bf50d7e9 100644 --- a/demo/flutter/lib/main.dart +++ b/demo/flutter/lib/main.dart @@ -81,8 +81,10 @@ class _MyAppState extends State { final String modelPath = "assets/models/leopard_params$suffix.pv"; try { - _leopard = await Leopard.create(accessKey, modelPath, - enableAutomaticPunctuation: true); + _leopard = await Leopard.create(accessKey, + modelPath, + enableAutomaticPunctuation: true, + enableDiarization: true); _micRecorder = await MicRecorder.create( _leopard!.sampleRate, recordedCallback, errorCallback); setState(() { @@ -90,9 +92,6 @@ class _MyAppState extends State { "Press START to start recording some audio to transcribe"; isButtonDisabled = false; }); - } on LeopardInvalidArgumentException catch (ex) { - errorCallback(LeopardInvalidArgumentException( - "${ex.message}\nEnsure your accessKey '$accessKey' is a valid access key.")); } on LeopardActivationException { errorCallback(LeopardActivationException("AccessKey activation error.")); } on LeopardActivationLimitException { @@ -276,6 +275,10 @@ class _MyAppState extends State { Text('${(leopardWord.confidence * 100).toStringAsFixed(0)}%', style: TextStyle(color: Colors.white)) ]), + Column(children: [ + Text('${leopardWord.speakerTag}', + style: TextStyle(color: Colors.white)) + ]), ]); }).toList(); @@ -295,6 +298,7 @@ class _MyAppState extends State { Column(children: [Text("Start")]), Column(children: [Text("End")]), Column(children: [Text("Confidence")]), + Column(children: [Text("Tag")]), ]) ])), Flexible( diff --git a/demo/flutter/pubspec.lock b/demo/flutter/pubspec.lock index 8b7a3bc2..4d147828 100644 --- a/demo/flutter/pubspec.lock +++ b/demo/flutter/pubspec.lock @@ -7,7 +7,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.11" + version: "3.1.6" async: dependency: transitive description: @@ -49,7 +49,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.16.0" + version: "1.15.0" crypto: dependency: transitive description: @@ -63,14 +63,14 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.2.0" ffi: dependency: transitive description: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.2.1" file: dependency: transitive description: @@ -113,10 +113,10 @@ packages: leopard_flutter: dependency: "direct main" description: - name: leopard_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" + path: "../../binding/flutter" + relative: true + source: path + version: "2.0.0" lints: dependency: "direct dev" description: @@ -131,13 +131,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" meta: dependency: transitive description: @@ -151,28 +144,28 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.0" path_provider: dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.14" + version: "2.0.11" path_provider_android: dependency: transitive description: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.16" - path_provider_foundation: + version: "2.0.20" + path_provider_ios: dependency: transitive description: - name: path_provider_foundation + name: path_provider_ios url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.0.11" path_provider_linux: dependency: transitive description: @@ -180,6 +173,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" path_provider_platform_interface: dependency: transitive description: @@ -193,14 +193,14 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.0.7" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "3.0.2" plugin_platform_interface: dependency: transitive description: @@ -226,7 +226,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.8.1" stack_trace: dependency: transitive description: @@ -268,7 +268,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.3" typed_data: dependency: transitive description: @@ -282,14 +282,14 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.1" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "8.2.2" + version: "7.3.0" webdriver: dependency: transitive description: @@ -303,7 +303,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.7.0" + version: "2.5.2" xdg_directories: dependency: transitive description: @@ -312,5 +312,5 @@ packages: source: hosted version: "0.2.0+1" sdks: - dart: ">=2.17.0 <3.0.0" - flutter: ">=3.0.0" + dart: ">=2.15.0 <3.0.0" + flutter: ">=2.8.1" diff --git a/demo/flutter/pubspec.yaml b/demo/flutter/pubspec.yaml index 46399904..ca3e5def 100644 --- a/demo/flutter/pubspec.yaml +++ b/demo/flutter/pubspec.yaml @@ -15,7 +15,8 @@ dependencies: path_provider: ^2.0.9 flutter_voice_processor: ^1.1.0 - leopard_flutter: ^1.2.1 + leopard_flutter: + path: ../../binding/flutter dev_dependencies: integration_test: diff --git a/demo/flutter/scripts/prepare_demo.dart b/demo/flutter/scripts/prepare_demo.dart index c369ab62..8728d57f 100644 --- a/demo/flutter/scripts/prepare_demo.dart +++ b/demo/flutter/scripts/prepare_demo.dart @@ -21,7 +21,7 @@ Future readJsonFile(String filePath) async { void main(List arguments) async { var testData = await readJsonFile(testDataPath); List availableLanguages = List.from( - testData["tests"]["parameters"].map((x) => x["language"]).toList()); + testData["tests"]["language_tests"].map((x) => x["language"]).toList()); if (arguments.isEmpty) { print(