fix DeezerAudioSource and playback on Windows and Linux

This commit is contained in:
Pato05 2023-10-15 16:48:55 +02:00
parent 0667c5a7a2
commit 5ba7e932e3
No known key found for this signature in database
GPG key ID: F53CA394104BA0CB
10 changed files with 226 additions and 136 deletions

View file

@ -1,9 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:encrypt/encrypt.dart'; import 'package:encrypt/encrypt.dart';
import 'package:flutter/foundation.dart' as flutter;
import 'package:freezer/api/deezer.dart'; import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/definitions.dart'; import 'package:freezer/api/definitions.dart';
import 'package:freezer/settings.dart'; import 'package:freezer/settings.dart';
@ -13,6 +15,13 @@ import 'package:http/http.dart' as http;
import 'package:dart_blowfish/dart_blowfish.dart'; import 'package:dart_blowfish/dart_blowfish.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
typedef _IsolateMessage = (
Stream<List<int>> source,
int start,
String trackId,
SendPort sendPort
);
// Maybe better implementation of Blowfish CBC instead of random-ass, unpublished library from github? // Maybe better implementation of Blowfish CBC instead of random-ass, unpublished library from github?
// This class can be considered a rewrite in Dart of the Java backend (from the StreamServer.deezer() function and also from the Deezer class) // This class can be considered a rewrite in Dart of the Java backend (from the StreamServer.deezer() function and also from the Deezer class)
class DeezerAudioSource extends StreamAudioSource { class DeezerAudioSource extends StreamAudioSource {
@ -25,6 +34,10 @@ class DeezerAudioSource extends StreamAudioSource {
late String _mediaVersion; late String _mediaVersion;
final StreamInfoCallback? onStreamObtained; final StreamInfoCallback? onStreamObtained;
// some cache
int? _cachedSourceLength;
String? _cachedContentType;
DeezerAudioSource({ DeezerAudioSource({
required AudioQuality quality, required AudioQuality quality,
required String trackId, required String trackId,
@ -201,18 +214,69 @@ class DeezerAudioSource extends StreamAudioSource {
return decrypted; return decrypted;
} }
static Stream<List<int>> decryptionStream(Stream<List<int>> source,
{required int start, required String trackId}) async* {
var dropBytes = start % 2048;
final deezerStart = start - dropBytes;
int counter = deezerStart ~/ chunkSize;
final buffer = List<int>.empty(growable: true);
final key = await flutter.compute(getKey, trackId);
await for (var bytes in source) {
if (dropBytes > 0) {
bytes = bytes.sublist(dropBytes);
}
buffer.addAll(bytes);
int i;
for (i = 0; i < buffer.length; i += chunkSize) {
if (buffer.length <= i + chunkSize) {
break;
}
bytes = buffer.sublist(i, i + chunkSize);
if ((counter % 3) == 0) {
bytes = decryptChunk(key, bytes);
}
counter++;
yield bytes;
}
if (i < buffer.length) {
buffer.removeRange(0, i);
} else {
buffer.clear();
}
}
// add remaining items in buffer
if (buffer.isNotEmpty) yield buffer;
}
@override @override
Future<StreamAudioResponse> request([int? start, int? end]) async { Future<StreamAudioResponse> request([int? start, int? end]) async {
start ??= 0; start ??= 0;
if (_cachedSourceLength != null) {
if (start == _cachedSourceLength) {
return StreamAudioResponse(
sourceLength: _cachedSourceLength,
contentLength: 0,
offset: start,
stream: const Stream<List<int>>.empty(),
contentType: _cachedContentType!);
}
}
_logger.fine("authorizing..."); _logger.fine("authorizing...");
if (!await deezerAPI.authorize()) { if (!await deezerAPI.authorize()) {
_logger.severe("authorization failed! cannot continue!"); _logger.severe("authorization failed! cannot continue!");
throw Exception("Authorization failed!"); throw Exception("Authorization failed!");
} }
late final StreamController<List<int>> controller;
final Uri uri; final Uri uri;
try { try {
uri = await _fallbackUrl(); uri = await _fallbackUrl();
@ -243,73 +307,24 @@ class DeezerAudioSource extends StreamAudioSource {
if (rc != HttpStatus.ok && rc != HttpStatus.partialContent) { if (rc != HttpStatus.ok && rc != HttpStatus.partialContent) {
throw Exception(await res.stream.bytesToString()); throw Exception(await res.stream.bytesToString());
} }
int counter = deezerStart ~/ chunkSize;
int dropBytes = start % chunkSize; int dropBytes = start % chunkSize;
_logger.finest( _logger.finest(
"deezerStart: $deezerStart (actual start: $start), end: $end, counter: $counter, dropBytes: $dropBytes"); "deezerStart: $deezerStart (actual start: $start), end: $end, dropBytes: $dropBytes");
var buffer = <int>[]; final stream = decryptionStream(res.stream, start: start, trackId: trackId);
final key = getKey(trackId);
int total = 0;
final subscription = res.stream.listen(
(bytes) {
// _logger.finest(
// "got stream bytes (${bytes.length}) with buffer.length = ${buffer.length}");
total += bytes.length;
buffer.addAll(bytes);
int i;
for (i = 0; i < buffer.length; i += chunkSize) {
if (buffer.length <= i + chunkSize) {
break;
}
bytes = buffer.sublist(i, i + chunkSize);
if ((counter % 3) == 0) {
bytes = decryptChunk(key, bytes);
}
if (dropBytes > 0) {
controller.add(bytes.sublist(dropBytes));
dropBytes = 0;
counter++;
continue;
}
counter++;
controller.add(bytes);
}
buffer.removeRange(0, i);
},
onDone: () {
total += buffer.length;
_logger.finest(
"onDone() called, remaining buffer ${buffer.length}, total: $total");
// add remaining items in buffer
if (buffer.isNotEmpty) controller.add(buffer);
controller.close();
},
);
subscription.pause();
controller = StreamController<List<int>>(
onListen: subscription.resume,
onPause: subscription.pause,
onResume: subscription.resume,
onCancel: subscription.cancel,
);
final cl = res.contentLength! - dropBytes; final cl = res.contentLength! - dropBytes;
if (end == null) {
_cachedSourceLength = cl + start;
}
return StreamAudioResponse( return StreamAudioResponse(
sourceLength: cl + start, sourceLength: _cachedSourceLength,
contentLength: cl, contentLength: cl,
offset: start, offset: start,
stream: controller.stream, stream: stream,
contentType: contentType: _cachedContentType =
quality == AudioQuality.FLAC ? "audio/flac" : "audio/mpeg"); quality == AudioQuality.FLAC ? "audio/flac" : "audio/mpeg");
} }
} }

View file

@ -50,6 +50,9 @@ class PlayerHelper {
final _streamInfoSubject = BehaviorSubject<StreamQualityInfo>(); final _streamInfoSubject = BehaviorSubject<StreamQualityInfo>();
ValueStream<StreamQualityInfo> get streamInfo => _streamInfoSubject.stream; ValueStream<StreamQualityInfo> get streamInfo => _streamInfoSubject.stream;
final _bufferPositionSubject = BehaviorSubject<Duration>();
ValueStream<Duration> get bufferPosition => _bufferPositionSubject.stream;
/// Find queue index by id /// Find queue index by id
/// ///
/// The function gets more expensive the longer the queue is and the further the element is from the beginning. /// The function gets more expensive the longer the queue is and the further the element is from the beginning.
@ -128,6 +131,9 @@ class PlayerHelper {
Logger('PlayerHelper').fine("streamInfo received"); Logger('PlayerHelper').fine("streamInfo received");
_streamInfoSubject.add(event['data'] as StreamQualityInfo); _streamInfoSubject.add(event['data'] as StreamQualityInfo);
break; break;
case 'bufferPosition':
_bufferPositionSubject.add(event['data'] as Duration);
break;
} }
}); });
_mediaItemSubscription = audioHandler.mediaItem.listen((mediaItem) async { _mediaItemSubscription = audioHandler.mediaItem.listen((mediaItem) async {
@ -366,8 +372,9 @@ class AudioPlayerTask extends BaseAudioHandler {
int _queueAutoIncrement = 0; int _queueAutoIncrement = 0;
//Stream subscriptions //Stream subscriptions
StreamSubscription? _eventSub; StreamSubscription? _eventSubscription;
StreamSubscription? _audioSessionSub; StreamSubscription? _bufferPositionSubscription;
StreamSubscription? _audioSessionSubscription;
StreamSubscription? _visualizerSubscription; StreamSubscription? _visualizerSubscription;
/// Android Auto helper class for navigation /// Android Auto helper class for navigation
@ -430,7 +437,7 @@ class AudioPlayerTask extends BaseAudioHandler {
_box = await Hive.openLazyBox('playback', _box = await Hive.openLazyBox('playback',
path: (await getTemporaryDirectory()).path); path: (await getTemporaryDirectory()).path);
_player = AudioPlayer( _player = AudioPlayer(
handleInterruptions: !initArgs.ignoreInterruptions, handleInterruptions: !initArgs.ignoreInterruptions,
androidApplyAudioAttributes: true, androidApplyAudioAttributes: true,
@ -455,7 +462,7 @@ class AudioPlayerTask extends BaseAudioHandler {
} }
}); });
//Update state on all clients on change //Update state on all clients on change
_eventSub = _player.playbackEventStream.listen((event) { _eventSubscription = _player.playbackEventStream.listen((event) {
//Update //Update
_broadcastState(); _broadcastState();
}, onError: (Object e, StackTrace st) { }, onError: (Object e, StackTrace st) {
@ -466,10 +473,8 @@ class AudioPlayerTask extends BaseAudioHandler {
case ProcessingState.completed: case ProcessingState.completed:
//Player ended, get more songs //Player ended, get more songs
if (_queueIndex == queue.value.length - 1) { if (_queueIndex == queue.value.length - 1) {
customEvent.add({ customEvent.add(
'action': 'queueEnd', {'action': 'queueEnd', 'queueSource': queueSource!.toJson()});
'queueSource': queueSource!.toJson()
});
} }
break; break;
default: default:
@ -477,8 +482,14 @@ class AudioPlayerTask extends BaseAudioHandler {
} }
}); });
_bufferPositionSubscription =
_player.bufferedPositionStream.listen((bufferPosition) {
customEvent.add({'action': 'bufferPosition', 'data': bufferPosition});
});
//Audio session //Audio session
_audioSessionSub = _player.androidAudioSessionIdStream.listen((event) { _audioSessionSubscription =
_player.androidAudioSessionIdStream.listen((event) {
customEvent.add({'action': 'audioSession', 'id': event}); customEvent.add({'action': 'audioSession', 'id': event});
}); });
@ -772,7 +783,9 @@ class AudioPlayerTask extends BaseAudioHandler {
//Load in just_audio //Load in just_audio
try { try {
await _player.setAudioSource(_audioSource, await _player.setAudioSource(_audioSource,
initialIndex: _queueIndex, initialPosition: Duration.zero, preload: kIsWeb || defaultTargetPlatform != TargetPlatform.linux); initialIndex: _queueIndex,
initialPosition: Duration.zero,
preload: kIsWeb || defaultTargetPlatform != TargetPlatform.linux);
} catch (e) { } catch (e) {
//Error loading tracks //Error loading tracks
} }
@ -931,9 +944,10 @@ class AudioPlayerTask extends BaseAudioHandler {
Future<void> stop() async { Future<void> stop() async {
await _saveQueue(); await _saveQueue();
_player.stop(); _player.stop();
_eventSub?.cancel(); _eventSubscription?.cancel();
_audioSessionSub?.cancel(); _audioSessionSubscription?.cancel();
_visualizerSubscription?.cancel(); _visualizerSubscription?.cancel();
_bufferPositionSubscription?.cancel();
await super.stop(); await super.stop();
} }

View file

@ -406,19 +406,21 @@ class _PlayPauseButtonState extends State<PlayPauseButton>
late final AnimationController _controller; late final AnimationController _controller;
late final Animation<double> _animation; late final Animation<double> _animation;
late StreamSubscription _subscription; late StreamSubscription _subscription;
late bool _canPlay = audioHandler.playbackState.value.playing || late bool _canPlay = audioHandler.playbackState.value.processingState ==
AudioProcessingState.ready ||
audioHandler.playbackState.value.processingState == audioHandler.playbackState.value.processingState ==
AudioProcessingState.ready; AudioProcessingState.idle;
@override @override
void initState() { void initState() {
_controller = AnimationController( _controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 200)); vsync: this, duration: const Duration(milliseconds: 200));
_animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut); _animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
_subscription = audioHandler.playbackState.listen((playbackState) { _subscription = audioHandler.playbackState.listen((playbackState) {
if (playbackState.playing || if (playbackState.processingState == AudioProcessingState.ready ||
playbackState.processingState == AudioProcessingState.ready) { audioHandler.playbackState.value.processingState ==
AudioProcessingState.idle) {
if (playbackState.playing) { if (playbackState.playing) {
_controller.forward(); _controller.forward();
} else { } else {
@ -480,7 +482,6 @@ class _PlayPauseButtonState extends State<PlayPauseButton>
switch (audioHandler.playbackState.value.processingState) { switch (audioHandler.playbackState.value.processingState) {
//Stopped/Error //Stopped/Error
case AudioProcessingState.error: case AudioProcessingState.error:
case AudioProcessingState.idle:
child = null; child = null;
break; break;
//Loading, connecting, rewinding... //Loading, connecting, rewinding...

View file

@ -933,25 +933,31 @@ class _SeekBarState extends State<SeekBar> {
children: <Widget>[ children: <Widget>[
ValueListenableBuilder<Duration>( ValueListenableBuilder<Duration>(
valueListenable: position, valueListenable: position,
builder: (context, value, _) => Slider( builder: (context, value, _) => StreamBuilder<Duration>(
focusNode: FocusNode( stream: playerHelper.bufferPosition,
canRequestFocus: false, builder: (context, snapshot) {
skipTraversal: return Slider(
true), // Don't focus on Slider - it doesn't work (and not needed) secondaryTrackValue:
value: parseDuration(value), parseDuration(snapshot.data ?? Duration.zero),
max: duration.inMilliseconds.toDouble(), focusNode: FocusNode(
onChangeStart: (double d) { canRequestFocus: false,
_seeking = true; skipTraversal:
position.value = Duration(milliseconds: d.toInt()); true), // Don't focus on Slider - it doesn't work (and not needed)
}, value: parseDuration(value),
onChanged: (double d) { max: duration.inMilliseconds.toDouble(),
position.value = Duration(milliseconds: d.toInt()); onChangeStart: (double d) {
}, _seeking = true;
onChangeEnd: (double d) { position.value = Duration(milliseconds: d.toInt());
_seeking = false; },
audioHandler.seek(Duration(milliseconds: d.toInt())); onChanged: (double d) {
}, position.value = Duration(milliseconds: d.toInt());
)), },
onChangeEnd: (double d) {
_seeking = false;
audioHandler.seek(Duration(milliseconds: d.toInt()));
},
);
})),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0), padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Row( child: Row(

View file

@ -8,6 +8,7 @@
#include <dynamic_color/dynamic_color_plugin.h> #include <dynamic_color/dynamic_color_plugin.h>
#include <isar_flutter_libs/isar_flutter_libs_plugin.h> #include <isar_flutter_libs/isar_flutter_libs_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar = g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin");
isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar); isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar);
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View file

@ -5,10 +5,12 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color dynamic_color
isar_flutter_libs isar_flutter_libs
media_kit_libs_linux
url_launcher_linux url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
media_kit_native_event_loop
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)

View file

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.13.0" version: "5.13.0"
archive:
dependency: transitive
description:
name: archive
sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03"
url: "https://pub.dev"
source: hosted
version: "3.4.6"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -363,14 +371,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.5" version: "2.0.5"
eventify:
dependency: transitive
description:
name: eventify
sha256: b829429f08586cc2001c628e7499e3e3c2493a1d895fd73b00ecb23351aa5a66
url: "https://pub.dev"
source: hosted
version: "1.0.1"
fading_edge_scrollview: fading_edge_scrollview:
dependency: transitive dependency: transitive
description: description:
@ -663,6 +663,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.0.2" version: "9.0.2"
image:
dependency: transitive
description:
name: image
sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271"
url: "https://pub.dev"
source: hosted
version: "4.1.3"
infinite_listview: infinite_listview:
dependency: transitive dependency: transitive
description: description:
@ -743,14 +751,13 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.35" version: "0.9.35"
just_audio_mpv: just_audio_media_kit:
dependency: "direct main" dependency: "direct main"
description: description:
name: just_audio_mpv path: "../just_audio_media_kit"
sha256: d6e4e9fd20bfb9d2fd5e3dcd7906c90ed07f83d1d2f44f31204160821ab62fed relative: true
url: "https://pub.dev" source: path
source: hosted version: "0.0.1"
version: "0.1.7"
just_audio_platform_interface: just_audio_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -767,14 +774,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.8" version: "0.4.8"
just_audio_windows:
dependency: "direct main"
description:
name: just_audio_windows
sha256: "7b8801f3987e98a2002cd23b5600b2daf162248ff1413266fb44c84448c1c0d3"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -815,6 +814,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.0" version: "0.5.0"
media_kit:
dependency: transitive
description:
name: media_kit
sha256: "1283b500341d41f033478706204a2b4ae2612e9b331c934bc4fad8c4bb869f6d"
url: "https://pub.dev"
source: hosted
version: "1.1.8+2"
media_kit_libs_linux:
dependency: transitive
description:
name: media_kit_libs_linux
sha256: e186891c31daa6bedab4d74dcdb4e8adfccc7d786bfed6ad81fe24a3b3010310
url: "https://pub.dev"
source: hosted
version: "1.1.3"
media_kit_libs_windows_audio:
dependency: transitive
description:
name: media_kit_libs_windows_audio
sha256: c2fd558cc87b9d89a801141fcdffe02e338a3b21a41a18fbd63d5b221a1b8e53
url: "https://pub.dev"
source: hosted
version: "1.0.9"
media_kit_native_event_loop:
dependency: transitive
description:
name: media_kit_native_event_loop
sha256: a605cf185499d14d58935b8784955a92a4bf0ff4e19a23de3d17a9106303930e
url: "https://pub.dev"
source: hosted
version: "1.0.8"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -839,14 +870,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
mpv_dart:
dependency: transitive
description:
name: mpv_dart
sha256: a33bd9a68439b496b7a5f36fecd3aa3cf6cbf0176ae15b9b60b12ae96e58f5a4
url: "https://pub.dev"
source: hosted
version: "0.0.1"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -1143,6 +1166,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.27.7" version: "0.27.7"
safe_local_storage:
dependency: transitive
description:
name: safe_local_storage
sha256: ede4eb6cb7d88a116b3d3bf1df70790b9e2038bc37cb19112e381217c74d9440
url: "https://pub.dev"
source: hosted
version: "1.0.2"
scrobblenaut: scrobblenaut:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1365,6 +1396,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
universal_platform:
dependency: transitive
description:
name: universal_platform
sha256: d315be0f6641898b280ffa34e2ddb14f3d12b1a37882557869646e0cc363d0cc
url: "https://pub.dev"
source: hosted
version: "1.0.0+1"
uri_parser:
dependency: transitive
description:
name: uri_parser
sha256: "6543c9fd86d2862fac55d800a43e67c0dcd1a41677cb69c2f8edfe73bbcf1835"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1534,5 +1581,5 @@ packages:
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.1.0 <4.0.0" dart: ">=3.1.3 <4.0.0"
flutter: ">=3.13.0" flutter: ">=3.13.0"

View file

@ -86,8 +86,8 @@ dependencies:
ref: main ref: main
logging: ^1.2.0 logging: ^1.2.0
just_audio: ^0.9.35 just_audio: ^0.9.35
just_audio_mpv: ^0.1.7 just_audio_media_kit:
just_audio_windows: ^0.2.0 git: https://github.com/Pato05/just_audio_media_kit.git
rxdart: ^0.27.7 rxdart: ^0.27.7
flutter_isolate: ^2.0.4 flutter_isolate: ^2.0.4
isar: ^3.1.0+1 isar: ^3.1.0+1

View file

@ -9,7 +9,7 @@
#include <connectivity_plus/connectivity_plus_windows_plugin.h> #include <connectivity_plus/connectivity_plus_windows_plugin.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h> #include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <isar_flutter_libs/isar_flutter_libs_plugin.h> #include <isar_flutter_libs/isar_flutter_libs_plugin.h>
#include <just_audio_windows/just_audio_windows_plugin.h> #include <media_kit_libs_windows_audio/media_kit_libs_windows_audio_plugin_c_api.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
@ -21,8 +21,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
IsarFlutterLibsPluginRegisterWithRegistrar( IsarFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
JustAudioWindowsPluginRegisterWithRegistrar( MediaKitLibsWindowsAudioPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("JustAudioWindowsPlugin")); registry->GetRegistrarForPlugin("MediaKitLibsWindowsAudioPluginCApi"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar( SharePlusWindowsPluginCApiRegisterWithRegistrar(

View file

@ -6,13 +6,14 @@ list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus connectivity_plus
dynamic_color dynamic_color
isar_flutter_libs isar_flutter_libs
just_audio_windows media_kit_libs_windows_audio
permission_handler_windows permission_handler_windows
share_plus share_plus
url_launcher_windows url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
media_kit_native_event_loop
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)