8000 refactor: cargokit based rust plugins by KRTirtho · Pull Request #1758 · KRTirtho/spotube · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

refactor: cargokit based rust plugins #1758

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG FLUTTER_VERSION

FROM --platform=linux/arm64 krtirtho/flutter_distributor_arm64:${FLUTTER_VERSION}
FROM --platform=linux/arm64 krtirtho/flutter_distributor:${FLUTTER_VERSION}

ARG BUILD_VERSION

Expand All @@ -10,6 +10,8 @@ COPY . .

RUN chown -R $(whoami) /app

RUN rustup target add aarch64-unknown-linux-gnu

RUN flutter pub get

RUN alias dpkg-deb="dpkg-deb --Zxz" &&\
Expand Down
23 changes: 0 additions & 23 deletions .github/Dockerfile.flutter_distributor

This file was deleted.

10 changes: 10 additions & 0 deletions .github/workflows/spotube-release-binary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ jobs:
- name: Set up Docker Buildx
if: ${{matrix.platform == 'linux_arm'}}
uses: docker/setup-buildx-action@v3
- name: Setup Rust toolchain
if: ${{matrix.platform != 'linux_arm'}}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable

- name: Install ${{matrix.platform}} dependencies
run: |
Expand All @@ -94,6 +99,11 @@ jobs:
echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks
echo '${{ secrets.KEY_PROPERTIES }}' > android/key.properties

- name: Unessary hosted tools
if: ${{matrix.platform == 'linux_arm'}}
run: |
sudo rm -rf /usr/share/dotnet

- name: Build ${{matrix.platform}} binaries
run: dart cli/cli.dart build ${{matrix.platform}}
env:
Expand Down
5 changes: 5 additions & 0 deletions cli/commands/install-dependencies.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class InstallDependenciesCommand extends Command {
);
break;
case "ios":
await shell.run(
"""
rustup target add aarch64-apple-ios
""",
);
break;
case "android":
await shell.run(
Expand Down
5 changes: 5 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:local_notifier/local_notifier.dart';
import 'package:media_kit/media_kit.dart';
import 'package:metadata_god/metadata_god.dart';
import 'package:smtc_windows/smtc_windows.dart';
import 'package:spotube/collections/env.dart';
import 'package:spotube/collections/initializers.dart';
import 'package:spotube/collections/routes.dart';
Expand Down Expand Up @@ -91,6 +92,10 @@ Future<void> main(List<String> rawArgs) async {
6D4E await FlutterDiscordRPC.initialize(Env.discordAppId);
}

if(kIsWindows){
await SMTCWindows.initialize();
}

await KVStoreService.initialize();
await EncryptedKvStoreService.initialize();

Expand Down
3 changes: 2 additions & 1 deletion lib/pages/library/local_folder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ class LocalLibraryPage extends HookConsumerWidget {
currentTrack ??= tracks.first;
final isPlaylistPlaying = playlist.containsTracks(tracks);
if (!isPlaylistPlaying) {
var indexWhere = tracks.indexWhere((s) => s.id == currentTrack?.id);
await playback.load(
tracks,
initialIndex: tracks.indexWhere((s) => s.id == currentTrack?.id),
initialIndex: indexWhere,
autoPlay: true,
);
} else if (isPlaylistPlaying &&
Expand Down
6 changes: 4 additions & 2 deletions lib/provider/audio_player/audio_player.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:drift/drift.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:media_kit/media_kit.dart' hide Track;
Expand All @@ -11,6 +12,7 @@ import 'package:spotube/provider/audio_player/state.dart';
import 'package:spotube/provider/blacklist_provider.dart';
import 'package:spotube/provider/database/database.dart';
import 'package:spotube/provider/discord_provider.dart';
import 'package:spotube/provider/local_tracks/local_tracks_provider.dart';
import 'package:spotube/provider/server/sourced_track.dart';
import 'package:spotube/services/audio_player/audio_player.dart';

Expand Down Expand Up @@ -283,7 +285,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
// Giving the initial track a boost so MediaKit won't skip
// because of timeout
final intendedActiveTrack = medias.elementAt(initialIndex);
if (intendedActiveTrack is! LocalTrack) {
if (intendedActiveTrack.track is! LocalTrack) {
await ref.read(sourcedTrackProvider(intendedActiveTrack).future);
}

Expand All @@ -292,7 +294,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
await removeCollections(state.collections);

await audioPlayer.openPlaylist(
medias,
medias.map((s) => s as Media).toList(),
initialIndex: initialIndex,
autoPlay: autoPlay,
);
Expand Down
2 changes: 1 addition & 1 deletion lib/provider/download_manager_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class DownloadManagerProvider extends ChangeNotifier {
trackNumber: track.trackNumber,
discNumber: track.discNumber,
durationMs: track.durationMs?.toDouble() ?? 0.0,
fileSize: await file.length(),
fileSize: BigInt.from(await file.length()),
trackTotal: track.album?.tracks?.length ?? 0,
picture: imageBytes != null
? Picture(
Expand Down
96 changes: 49 additions & 47 deletions lib/provider/local_tracks/local_tracks_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:spotube/extensions/track.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
// ignore: depend_on_referenced_packages
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart' show FfiException;
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart' show FrbException;

const supportedAudioTypes = [
"audio/webm",
Expand All @@ -37,7 +37,7 @@ final localTracksProvider =
FutureProvider<Map<String, List<LocalTrack>>>((ref) async {
try {
if (kIsWeb) return {};
final Map<String, List<LocalTrack>> tracks = {};
final Map<String, List<LocalTrack>> libraryToTracks = {};

final downloadLocation = ref.watch(
userPreferencesProvider.select((s) => s.downloadLocation),
Expand All @@ -52,59 +52,61 @@ final localTracksProvider =

for (final location in [downloadLocation, ...localLibraryLocations]) {
if (location.isEmpty) continue;
final entities = <FileSystemEntity>[];
final entities = <File>[];
if (await Directory(location).exists()) {
try {
entities.addAll(Directory(location).listSync(recursive: true));
final dirEntities =
await Directory(location).list(recursive: true).toList();

entities.addAll(
dirEntities
.where(
(e) =>
e is File &&
supportedAudioTypes.contains(lookupMimeType(e.path)),
)
.cast<File>(),
);
} catch (e, stack) {
AppLogger.reportError(e, stack);
}
}

final filesWithMetadata = (await Future.wait(
entities.map((e) => File(e.path)).where((file) {
final mimetype = lookupMimeType(file.path);
return mimetype != null && supportedAudioTypes.contains(mimetype);
}).map(
(file) async {
try {
final metadata = await MetadataGod.readMetadata(file: file.path)
.timeout(const Duration(seconds: 10));
final List<Map<dynamic, dynamic>> filesWithMetadata = [];

final imageFile = File(join(
(await getTemporaryDirectory()).path,
"spotube",
basenameWithoutExtension(file.path) +
imgMimeToExt[metadata.picture?.mimeType ?? "image/jpeg"]!,
));
if (!await imageFile.exists() && metadata.picture != null) {
await imageFile.create(recursive: true);
await imageFile.writeAsBytes(
metadata.picture?.data ?? [],
mode: FileMode.writeOnly,
);
}
for (final file in entities) {
try {
final metadata = await MetadataGod.readMetadata(file: file.path);

return {
"metadata": metadata,
"file": file,
"art": imageFile.path
};
} catch (e, stack) {
if (e case FfiException() || TimeoutException()) {
return {"file": file};
}
AppLogger.reportError(e, stack);
return {};
}
},
),
))
.where((e) => e.isNotEmpty)
.toList();
await Future.delayed(const Duration(milliseconds: 50));

final imageFile = File(join(
(await getTemporaryDirectory()).path,
"spotube",
basenameWithoutExtension(file.path) +
imgMimeToExt[metadata.picture?.mimeType ?? "image/jpeg"]!,
));
if (!await imageFile.exists() && metadata.picture != null) {
await imageFile.create(recursive: true);
await imageFile.writeAsBytes(
metadata.picture?.data ?? [],
mode: FileMode.writeOnly,
);
}

filesWithMetadata.add(
{"metadata": metadata, "file": file, "art": imageFile.path},
);
} catch (e, stack) {
if (e case FrbException() || TimeoutException()) {
filesWithMetadata.add({"file": file});
}
AppLogger.reportError(e, stack);
continue;
}
}

// ignore: no_leading_underscores_for_local_identifiers
final _tracks = filesWithMetadata
final tracksFromMetadata = filesWithMetadata
.map(
(fileWithMetadata) => LocalTrack.fromTrack(
track: Track().fromFile(
Expand All @@ -117,9 +119,9 @@ final localTracksProvider =
)
.toList();

tracks[location] = _tracks;
libraryToTracks[location] = tracksFromMetadata;
}
return tracks;
return libraryToTracks;
} catch (e, stack) {
AppLogger.reportError(e, stack);
return {};
Expand Down
37 changes: 22 additions & 15 deletions lib/services/audio_player/audio_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@ class SpotubeMedia extends mk.Media {
);

@override
String get uri => track is LocalTrack
? (track as LocalTrack).path
: "http://${kIsWindows ? "localhost" : InternetAddress.anyIPv4.address}:$serverPort/stream/${track.id}";
String get uri {
return switch (track) {
/// [super.uri] must be used instead of [track.path] to prevent wrong
/// path format exceptions in Windows causing [extras] to be null
LocalTrack() => super.uri,
_ =>
"http://${kIsWindows ? "localhost" : InternetAddress.anyIPv4.address}:"
"$serverPort/stream/${track.id}",
};
}

factory SpotubeMedia.fromMedia(mk.Media media) {
final track = media.uri.startsWith("http")
Expand All @@ -56,20 +63,20 @@ class SpotubeMedia extends mk.Media {
);
}

@override
operator ==(Object other) {
if (other is! SpotubeMedia) return false;
// @override
// operator ==(Object other) {
// if (other is! SpotubeMedia) return false;

final isLocal = track is LocalTrack && other.track is LocalTrack;
return isLocal
? (other.track as LocalTrack).path == (track as LocalTrack).path
: other.track.id == track.id;
}
// final isLocal = track is LocalTrack && other.track is LocalTrack;
// return isLocal
// ? (other.track as LocalTrack).path == (track as LocalTrack).path
// : other.track.id == track.id;
// }

@override
int get hashCode => track is LocalTrack
? (track as LocalTrack).path.hashCode
: track.id.hashCode;
// @override
// int get hashCode => track is LocalTrack
// ? (track as LocalTrack).path.hashCode
// : track.id.hashCode;
}

abstract class AudioPlayerInterface {
Expand Down
4 changes: 3 additions & 1 deletion lib/services/audio_player/audio_players_streams_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,7 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {

Stream<String> get errorStream => _mkPlayer.stream.error;

Stream<mk.Playlist> get playlistStream => _mkPlayer.stream.playlist;
Stream<mk.Playlist> get playlistStream => _mkPlayer.stream.playlist.map((s) {
return s;
});
}
Loading
0