diff --git a/CHANGELOG.md b/CHANGELOG.md index 2035662..8197865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.0.5 + +* Fix timing of progress completion events (@volskaya). +* Update minimum flutter version to 3.0. +* Update AGP to 7.3.0. + ## 0.0.4 * Allow extracting multiple files simultaneously (@AlexSmirnov9107). diff --git a/analysis_options.yaml b/analysis_options.yaml index a5744c1..46c8448 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,12 @@ include: package:flutter_lints/flutter.yaml -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +analyzer: + language: + strict-casts: true + strict-inference: true + strict-raw-types: true + +linter: + rules: + prefer_single_quotes: false + unawaited_futures: false diff --git a/android/build.gradle b/android/build.gradle index f6a7061..5a4b208 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.0' } } @@ -22,7 +22,11 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - compileSdkVersion 31 + // Conditional for compatibility with AGP <4.2. + if (project.android.hasProperty("namespace")) { + namespace 'com.ryanheise.just_waveform' + } + compileSdkVersion 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c9d085..3c472b9 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/android/src/main/java/com/ryanheise/just_waveform/JustWaveformPlugin.java b/android/src/main/java/com/ryanheise/just_waveform/JustWaveformPlugin.java index 9869dfa..a5acdd4 100644 --- a/android/src/main/java/com/ryanheise/just_waveform/JustWaveformPlugin.java +++ b/android/src/main/java/com/ryanheise/just_waveform/JustWaveformPlugin.java @@ -3,23 +3,25 @@ import androidx.annotation.NonNull; import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import android.os.Handler; +import android.os.Looper; import java.util.List; -import io.flutter.plugin.common.PluginRegistry.Registrar; import java.util.HashMap; /** JustWaveformPlugin */ public class JustWaveformPlugin implements FlutterPlugin, MethodCallHandler { private MethodChannel channel; - private Handler handler = new Handler(); + private Handler handler = new Handler(Looper.getMainLooper()); @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { - channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "com.ryanheise.just_waveform"); + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + BinaryMessenger messenger = binding.getBinaryMessenger(); + channel = new MethodChannel(messenger, "com.ryanheise.just_waveform"); channel.setMethodCallHandler(this); } @@ -35,7 +37,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) waveformExtractor.start(new WaveformExtractor.OnProgressListener() { @Override public void onProgress(int progress) { - HashMap args = new HashMap(); + HashMap args = new HashMap<>(); args.put("progress", progress); args.put("waveOutFile", waveOutPath); diff --git a/android/src/main/java/com/ryanheise/just_waveform/WaveformExtractor.java b/android/src/main/java/com/ryanheise/just_waveform/WaveformExtractor.java index 8a75ac5..79dec85 100644 --- a/android/src/main/java/com/ryanheise/just_waveform/WaveformExtractor.java +++ b/android/src/main/java/com/ryanheise/just_waveform/WaveformExtractor.java @@ -19,7 +19,7 @@ public class WaveformExtractor { private static final int TIMEOUT = 5000; - private static final int MAX_SAMPLE_SIZE = 256 * 1024; + //private static final int MAX_SAMPLE_SIZE = 256 * 1024; private String inPath; private String wavePath; @@ -65,7 +65,7 @@ public void run() { extractor.setDataSource(inPath); inFormat = selectAudioTrack(extractor); - int trackCount = extractor.getTrackCount(); + //int trackCount = extractor.getTrackCount(); //System.out.println("extractor format = " + inFormat); inMime = inFormat.getString(MediaFormat.KEY_MIME); processAudio(); @@ -85,17 +85,17 @@ void processAudio() { int sampleRate = inFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); //System.out.println("sample rate = " + sampleRate); long duration = inFormat.getLong(MediaFormat.KEY_DURATION); - int durationMs = (int)(duration/1000); + //int durationMs = (int)(duration/1000); long expectedSampleCount = duration * sampleRate / 1000000; // If we hear 2 stereo samples at the same time, we count that as 1 sample here. //System.out.println("expected sample count = " + expectedSampleCount); boolean sawInputEOS = false; int decoderIdleCount = 0; - int bufferSize = MAX_SAMPLE_SIZE; + //int bufferSize = MAX_SAMPLE_SIZE; int frameCount = 0; - int offset = 100; + //int offset = 100; - ByteBuffer buffer = ByteBuffer.allocate(bufferSize); + //ByteBuffer buffer = ByteBuffer.allocate(bufferSize); BufferInfo bufferInfo = new BufferInfo(); // For the wave @@ -126,7 +126,7 @@ void processAudio() { int waitingToDecode = 0; int waitingForDecoded = 0; long presentationTime = 0L; - long stopwatchStart = System.currentTimeMillis(); + //long stopwatchStart = System.currentTimeMillis(); decoder = MediaCodec.createDecoderByType(inMime); decoder.configure(inFormat, null, null, 0); decoder.start(); @@ -225,7 +225,6 @@ void processAudio() { try (FileOutputStream fout = new FileOutputStream(new File(wavePath))) { FileChannel channel = fout.getChannel(); int waveHeaderLength = 20; // in bytes - int waveHeaderLengthInShorts = waveHeaderLength / 2; // in shorts ByteBuffer waveHeaderBytes = ByteBuffer.allocate(waveHeaderLength); waveHeaderBytes.order(ByteOrder.LITTLE_ENDIAN); IntBuffer waveHeader = waveHeaderBytes.asIntBuffer(); diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 88f9cae..f278c21 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -25,7 +25,8 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 31 + namespace 'com.ryanheise.just_waveform_example' + compileSdkVersion 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index bdd5f7b..03a29dc 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -21,15 +21,6 @@ android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> - - diff --git a/example/android/build.gradle b/example/android/build.gradle index 622ddc5..4f5bdd8 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.0' } } @@ -14,6 +14,13 @@ allprojects { google() mavenCentral() } + + gradle.projectsEvaluated{ + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:deprecation" + options.compilerArgs << "-Xlint:unchecked" + } + } } rootProject.buildDir = '../build' @@ -22,6 +29,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..6b66533 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/example/lib/main.dart b/example/lib/main.dart index ab1bf85..78b7ca0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -68,7 +68,7 @@ class _MyAppState extends State { return Center( child: Text( 'Error: ${snapshot.error}', - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), ); @@ -79,7 +79,7 @@ class _MyAppState extends State { return Center( child: Text( '${(100 * progress).toInt()}%', - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.titleLarge, ), ); } diff --git a/lib/just_waveform.dart b/lib/just_waveform.dart index 5e0704d..46bb549 100644 --- a/lib/just_waveform.dart +++ b/lib/just_waveform.dart @@ -12,19 +12,32 @@ class JustWaveform { switch (call.method) { case 'onProgress': final args = call.arguments; - int progress = args['progress']; - String waveOutFilePath = args['waveOutFile']; - Waveform? waveform; + int progress = args['progress'] as int; + String waveOutFilePath = args['waveOutFile'] as String; + final progressController = _progressControllers[waveOutFilePath]; + if (progressController == null) break; + if (progressController.isClosed) break; - if (progress == 100) { - waveform = await parse(File(waveOutFilePath)); - } + Waveform? waveform; - _progressControllers[waveOutFilePath] - ?.add(WaveformProgress._(progress / 100, waveform)); - if (progress == 100) { - _progressControllers[waveOutFilePath]?.close(); - _progressControllers.remove(waveOutFilePath); + try { + if (progress == 100) { + waveform = await parse(File(waveOutFilePath)); + } + + progressController + .add(WaveformProgress._(progress / 100, waveform)); + if (progress == 100) { + progressController.close(); + _progressControllers.remove(waveOutFilePath); + } + } on RangeError { + // If the waveform file is too short. + progressController + .add(WaveformProgress._(progress / 100, waveform)); + progressController.close(); + } catch (e, stackTrace) { + progressController.addError(e, stackTrace); } break; } diff --git a/pubspec.yaml b/pubspec.yaml index 00383a7..acd9284 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,14 @@ name: just_waveform description: Extracts waveform data from an audio file suitable for visually rendering the waveform. -version: 0.0.4 +version: 0.0.5 homepage: https://github.com/ryanheise/just_waveform +topics: + - audio + - waveform environment: - sdk: ">=2.12.0 <3.0.0" - flutter: ">=1.20.0" + sdk: ">=2.14.0 <4.0.0" + flutter: ">=3.0.0" dependencies: flutter: @@ -16,7 +19,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^1.0.0 + flutter_lints: ^2.0.1 flutter: plugin: