fix DeezerAudioSource and playback on Windows and Linux
This commit is contained in:
parent
0667c5a7a2
commit
5ba7e932e3
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:flutter/foundation.dart' as flutter;
|
||||
import 'package:freezer/api/deezer.dart';
|
||||
import 'package:freezer/api/definitions.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: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?
|
||||
// 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 {
|
||||
|
|
@ -25,6 +34,10 @@ class DeezerAudioSource extends StreamAudioSource {
|
|||
late String _mediaVersion;
|
||||
final StreamInfoCallback? onStreamObtained;
|
||||
|
||||
// some cache
|
||||
int? _cachedSourceLength;
|
||||
String? _cachedContentType;
|
||||
|
||||
DeezerAudioSource({
|
||||
required AudioQuality quality,
|
||||
required String trackId,
|
||||
|
|
@ -201,18 +214,69 @@ class DeezerAudioSource extends StreamAudioSource {
|
|||
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
|
||||
Future<StreamAudioResponse> request([int? start, int? end]) async {
|
||||
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...");
|
||||
if (!await deezerAPI.authorize()) {
|
||||
_logger.severe("authorization failed! cannot continue!");
|
||||
throw Exception("Authorization failed!");
|
||||
}
|
||||
|
||||
late final StreamController<List<int>> controller;
|
||||
|
||||
final Uri uri;
|
||||
try {
|
||||
uri = await _fallbackUrl();
|
||||
|
|
@ -243,73 +307,24 @@ class DeezerAudioSource extends StreamAudioSource {
|
|||
if (rc != HttpStatus.ok && rc != HttpStatus.partialContent) {
|
||||
throw Exception(await res.stream.bytesToString());
|
||||
}
|
||||
int counter = deezerStart ~/ chunkSize;
|
||||
|
||||
int dropBytes = start % chunkSize;
|
||||
|
||||
_logger.finest(
|
||||
"deezerStart: $deezerStart (actual start: $start), end: $end, counter: $counter, dropBytes: $dropBytes");
|
||||
var buffer = <int>[];
|
||||
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,
|
||||
);
|
||||
"deezerStart: $deezerStart (actual start: $start), end: $end, dropBytes: $dropBytes");
|
||||
final stream = decryptionStream(res.stream, start: start, trackId: trackId);
|
||||
|
||||
final cl = res.contentLength! - dropBytes;
|
||||
|
||||
if (end == null) {
|
||||
_cachedSourceLength = cl + start;
|
||||
}
|
||||
|
||||
return StreamAudioResponse(
|
||||
sourceLength: cl + start,
|
||||
sourceLength: _cachedSourceLength,
|
||||
contentLength: cl,
|
||||
offset: start,
|
||||
stream: controller.stream,
|
||||
contentType:
|
||||
stream: stream,
|
||||
contentType: _cachedContentType =
|
||||
quality == AudioQuality.FLAC ? "audio/flac" : "audio/mpeg");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ class PlayerHelper {
|
|||
final _streamInfoSubject = BehaviorSubject<StreamQualityInfo>();
|
||||
ValueStream<StreamQualityInfo> get streamInfo => _streamInfoSubject.stream;
|
||||
|
||||
final _bufferPositionSubject = BehaviorSubject<Duration>();
|
||||
ValueStream<Duration> get bufferPosition => _bufferPositionSubject.stream;
|
||||
|
||||
/// Find queue index by id
|
||||
///
|
||||
/// 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");
|
||||
_streamInfoSubject.add(event['data'] as StreamQualityInfo);
|
||||
break;
|
||||
case 'bufferPosition':
|
||||
_bufferPositionSubject.add(event['data'] as Duration);
|
||||
break;
|
||||
}
|
||||
});
|
||||
_mediaItemSubscription = audioHandler.mediaItem.listen((mediaItem) async {
|
||||
|
|
@ -366,8 +372,9 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
int _queueAutoIncrement = 0;
|
||||
|
||||
//Stream subscriptions
|
||||
StreamSubscription? _eventSub;
|
||||
StreamSubscription? _audioSessionSub;
|
||||
StreamSubscription? _eventSubscription;
|
||||
StreamSubscription? _bufferPositionSubscription;
|
||||
StreamSubscription? _audioSessionSubscription;
|
||||
StreamSubscription? _visualizerSubscription;
|
||||
|
||||
/// Android Auto helper class for navigation
|
||||
|
|
@ -455,7 +462,7 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
}
|
||||
});
|
||||
//Update state on all clients on change
|
||||
_eventSub = _player.playbackEventStream.listen((event) {
|
||||
_eventSubscription = _player.playbackEventStream.listen((event) {
|
||||
//Update
|
||||
_broadcastState();
|
||||
}, onError: (Object e, StackTrace st) {
|
||||
|
|
@ -466,10 +473,8 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
case ProcessingState.completed:
|
||||
//Player ended, get more songs
|
||||
if (_queueIndex == queue.value.length - 1) {
|
||||
customEvent.add({
|
||||
'action': 'queueEnd',
|
||||
'queueSource': queueSource!.toJson()
|
||||
});
|
||||
customEvent.add(
|
||||
{'action': 'queueEnd', 'queueSource': queueSource!.toJson()});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -477,8 +482,14 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
}
|
||||
});
|
||||
|
||||
_bufferPositionSubscription =
|
||||
_player.bufferedPositionStream.listen((bufferPosition) {
|
||||
customEvent.add({'action': 'bufferPosition', 'data': bufferPosition});
|
||||
});
|
||||
|
||||
//Audio session
|
||||
_audioSessionSub = _player.androidAudioSessionIdStream.listen((event) {
|
||||
_audioSessionSubscription =
|
||||
_player.androidAudioSessionIdStream.listen((event) {
|
||||
customEvent.add({'action': 'audioSession', 'id': event});
|
||||
});
|
||||
|
||||
|
|
@ -772,7 +783,9 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
//Load in just_audio
|
||||
try {
|
||||
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) {
|
||||
//Error loading tracks
|
||||
}
|
||||
|
|
@ -931,9 +944,10 @@ class AudioPlayerTask extends BaseAudioHandler {
|
|||
Future<void> stop() async {
|
||||
await _saveQueue();
|
||||
_player.stop();
|
||||
_eventSub?.cancel();
|
||||
_audioSessionSub?.cancel();
|
||||
_eventSubscription?.cancel();
|
||||
_audioSessionSubscription?.cancel();
|
||||
_visualizerSubscription?.cancel();
|
||||
_bufferPositionSubscription?.cancel();
|
||||
await super.stop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,9 +406,10 @@ class _PlayPauseButtonState extends State<PlayPauseButton>
|
|||
late final AnimationController _controller;
|
||||
late final Animation<double> _animation;
|
||||
late StreamSubscription _subscription;
|
||||
late bool _canPlay = audioHandler.playbackState.value.playing ||
|
||||
late bool _canPlay = audioHandler.playbackState.value.processingState ==
|
||||
AudioProcessingState.ready ||
|
||||
audioHandler.playbackState.value.processingState ==
|
||||
AudioProcessingState.ready;
|
||||
AudioProcessingState.idle;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -417,8 +418,9 @@ class _PlayPauseButtonState extends State<PlayPauseButton>
|
|||
_animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
|
||||
|
||||
_subscription = audioHandler.playbackState.listen((playbackState) {
|
||||
if (playbackState.playing ||
|
||||
playbackState.processingState == AudioProcessingState.ready) {
|
||||
if (playbackState.processingState == AudioProcessingState.ready ||
|
||||
audioHandler.playbackState.value.processingState ==
|
||||
AudioProcessingState.idle) {
|
||||
if (playbackState.playing) {
|
||||
_controller.forward();
|
||||
} else {
|
||||
|
|
@ -480,7 +482,6 @@ class _PlayPauseButtonState extends State<PlayPauseButton>
|
|||
switch (audioHandler.playbackState.value.processingState) {
|
||||
//Stopped/Error
|
||||
case AudioProcessingState.error:
|
||||
case AudioProcessingState.idle:
|
||||
child = null;
|
||||
break;
|
||||
//Loading, connecting, rewinding...
|
||||
|
|
|
|||
|
|
@ -933,7 +933,12 @@ class _SeekBarState extends State<SeekBar> {
|
|||
children: <Widget>[
|
||||
ValueListenableBuilder<Duration>(
|
||||
valueListenable: position,
|
||||
builder: (context, value, _) => Slider(
|
||||
builder: (context, value, _) => StreamBuilder<Duration>(
|
||||
stream: playerHelper.bufferPosition,
|
||||
builder: (context, snapshot) {
|
||||
return Slider(
|
||||
secondaryTrackValue:
|
||||
parseDuration(snapshot.data ?? Duration.zero),
|
||||
focusNode: FocusNode(
|
||||
canRequestFocus: false,
|
||||
skipTraversal:
|
||||
|
|
@ -951,7 +956,8 @@ class _SeekBarState extends State<SeekBar> {
|
|||
_seeking = false;
|
||||
audioHandler.seek(Duration(milliseconds: d.toInt()));
|
||||
},
|
||||
)),
|
||||
);
|
||||
})),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <dynamic_color/dynamic_color_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>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
|
|
@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||
g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin");
|
||||
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 =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
dynamic_color
|
||||
isar_flutter_libs
|
||||
media_kit_libs_linux
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
media_kit_native_event_loop
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
|
|
|||
109
pubspec.lock
109
pubspec.lock
|
|
@ -17,6 +17,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.13.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.6"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -363,14 +371,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -663,6 +663,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.2"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.3"
|
||||
infinite_listview:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -743,14 +751,13 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.35"
|
||||
just_audio_mpv:
|
||||
just_audio_media_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: just_audio_mpv
|
||||
sha256: d6e4e9fd20bfb9d2fd5e3dcd7906c90ed07f83d1d2f44f31204160821ab62fed
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.7"
|
||||
path: "../just_audio_media_kit"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
just_audio_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -767,14 +774,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -815,6 +814,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -839,14 +870,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1143,6 +1166,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1365,6 +1396,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1534,5 +1581,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.1.0 <4.0.0"
|
||||
dart: ">=3.1.3 <4.0.0"
|
||||
flutter: ">=3.13.0"
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ dependencies:
|
|||
ref: main
|
||||
logging: ^1.2.0
|
||||
just_audio: ^0.9.35
|
||||
just_audio_mpv: ^0.1.7
|
||||
just_audio_windows: ^0.2.0
|
||||
just_audio_media_kit:
|
||||
git: https://github.com/Pato05/just_audio_media_kit.git
|
||||
rxdart: ^0.27.7
|
||||
flutter_isolate: ^2.0.4
|
||||
isar: ^3.1.0+1
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <dynamic_color/dynamic_color_plugin_c_api.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 <share_plus/share_plus_windows_plugin_c_api.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
|
@ -21,8 +21,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
||||
IsarFlutterLibsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
|
||||
JustAudioWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("JustAudioWindowsPlugin"));
|
||||
MediaKitLibsWindowsAudioPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("MediaKitLibsWindowsAudioPluginCApi"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
connectivity_plus
|
||||
dynamic_color
|
||||
isar_flutter_libs
|
||||
just_audio_windows
|
||||
media_kit_libs_windows_audio
|
||||
permission_handler_windows
|
||||
share_plus
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
media_kit_native_event_loop
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
|
|
|||
Loading…
Reference in a new issue