mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
feat(broken): Broken Warning! Initial Local Audio Player
This commit is contained in:
parent
24c9270bed
commit
c3bf5119eb
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@ -6,8 +6,7 @@
|
||||
"type": "dart",
|
||||
"request": "launch",
|
||||
"program": "lib/main.dart"
|
||||
}
|
||||
|
||||
},
|
||||
],
|
||||
"compounds": []
|
||||
}
|
@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:spotube/components/Library/UserAlbums.dart';
|
||||
import 'package:spotube/components/Library/UserArtists.dart';
|
||||
import 'package:spotube/components/Library/UserDownloads.dart';
|
||||
import 'package:spotube/components/Library/UserLocalTracks.dart';
|
||||
import 'package:spotube/components/Library/UserPlaylists.dart';
|
||||
import 'package:spotube/components/Shared/AnonymousFallback.dart';
|
||||
|
||||
@ -12,7 +13,7 @@ class UserLibrary extends ConsumerWidget {
|
||||
Widget build(BuildContext context, ref) {
|
||||
return Expanded(
|
||||
child: DefaultTabController(
|
||||
length: 4,
|
||||
length: 5,
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: const TabBar(
|
||||
@ -22,6 +23,7 @@ class UserLibrary extends ConsumerWidget {
|
||||
Tab(text: "Artists"),
|
||||
Tab(text: "Album"),
|
||||
Tab(text: "Downloads"),
|
||||
Tab(text: "Local"),
|
||||
],
|
||||
),
|
||||
body: TabBarView(children: [
|
||||
@ -29,6 +31,7 @@ class UserLibrary extends ConsumerWidget {
|
||||
AnonymousFallback(child: UserArtists()),
|
||||
const AnonymousFallback(child: UserAlbums()),
|
||||
const UserDownloads(),
|
||||
const UserLocalTracks(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
|
71
lib/components/Library/UserLocalTracks.dart
Normal file
71
lib/components/Library/UserLocalTracks.dart
Normal file
@ -0,0 +1,71 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_media_metadata/flutter_media_metadata.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:mime/mime.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/provider/UserPreferences.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
|
||||
const supportedAudioTypes = [
|
||||
"audio/webm",
|
||||
"audio/ogg",
|
||||
"audio/mpeg",
|
||||
"audio/opus",
|
||||
"audio/wav",
|
||||
"audio/aac",
|
||||
];
|
||||
|
||||
List<Track> usePullLocalTracks(WidgetRef ref) {
|
||||
final downloadDir = Directory(
|
||||
ref.watch(userPreferencesProvider.select((s) => s.downloadLocation)),
|
||||
);
|
||||
final localTracks = useState<List<Track>>([]);
|
||||
|
||||
useEffect(() {
|
||||
(() async {
|
||||
if (!await downloadDir.exists()) {
|
||||
await downloadDir.create(recursive: true);
|
||||
return;
|
||||
}
|
||||
final entities = downloadDir.listSync(recursive: true);
|
||||
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(
|
||||
(f) async => {
|
||||
"metadata": await MetadataRetriever.fromFile(f),
|
||||
"file": f,
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
final tracks = filesWithMetadata
|
||||
.map(
|
||||
(fileWithMetadata) => TypeConversionUtils.localTrack_X_Track(
|
||||
fileWithMetadata["metadata"] as Metadata,
|
||||
fileWithMetadata["file"] as File),
|
||||
)
|
||||
.toList();
|
||||
|
||||
localTracks.value = tracks;
|
||||
})();
|
||||
|
||||
return;
|
||||
}, [downloadDir]);
|
||||
|
||||
return localTracks.value;
|
||||
}
|
||||
|
||||
class UserLocalTracks extends HookConsumerWidget {
|
||||
const UserLocalTracks({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final tracks = usePullLocalTracks(ref);
|
||||
return Column();
|
||||
}
|
||||
}
|
@ -126,7 +126,7 @@ class Playback extends PersistedChangeNotifier {
|
||||
playlist?.tracks.indexWhere((t) => t.id == track?.id);
|
||||
|
||||
// when the track progress is above 80%, track isn't the last
|
||||
// and is not already fetch and nothing is fetching currently
|
||||
// and is not already fetched and nothing is fetching currently
|
||||
if (pos.inSeconds > currentDuration.inSeconds * .8 &&
|
||||
playlist != null &&
|
||||
currentTrackIndex != playlist!.tracks.length - 1 &&
|
||||
|
@ -1,6 +1,9 @@
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/widgets.dart' hide Image;
|
||||
import 'package:flutter_media_metadata/flutter_media_metadata.dart';
|
||||
import 'package:spotube/components/Shared/LinkText.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/utils/primitive_utils.dart';
|
||||
@ -81,4 +84,33 @@ abstract class TypeConversionUtils {
|
||||
track.uri = trackSmp.uri;
|
||||
return track;
|
||||
}
|
||||
|
||||
static Track localTrack_X_Track(Metadata metadata, File file) {
|
||||
final track = Track();
|
||||
track.album = Album()
|
||||
..name = metadata.albumName
|
||||
..genres = [if (metadata.genre != null) metadata.genre!]
|
||||
..artists = [
|
||||
Artist()
|
||||
..name = metadata.albumArtistName
|
||||
..id = metadata.albumArtistName
|
||||
..type = "artist",
|
||||
]
|
||||
..id = "${metadata.albumName}${metadata.albumLength}";
|
||||
track.artists = metadata.trackArtistNames
|
||||
?.map((name) => Artist()
|
||||
..name = name
|
||||
..id = name)
|
||||
.toList();
|
||||
|
||||
track.discNumber = metadata.discNumber;
|
||||
track.durationMs = metadata.trackDuration;
|
||||
track.id = "${metadata.trackName}${metadata.trackDuration}";
|
||||
track.name = metadata.trackName;
|
||||
track.trackNumber = metadata.trackNumber;
|
||||
track.type = "track";
|
||||
track.uri = file.path;
|
||||
|
||||
return track;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||
#include <flutter_media_metadata/flutter_media_metadata_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) bitsdojo_window_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
|
||||
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) flutter_media_metadata_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterMediaMetadataPlugin");
|
||||
flutter_media_metadata_plugin_register_with_registrar(flutter_media_metadata_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,6 +5,7 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_linux
|
||||
bitsdojo_window_linux
|
||||
flutter_media_metadata
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
@ -9,6 +9,7 @@ import audio_service
|
||||
import audio_session
|
||||
import audioplayers_darwin
|
||||
import bitsdojo_window_macos
|
||||
import flutter_media_metadata
|
||||
import package_info_plus_macos
|
||||
import path_provider_macos
|
||||
import shared_preferences_macos
|
||||
@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
|
||||
FlutterMediaMetadataPlugin.register(with: registry.registrar(forPlugin: "FlutterMediaMetadataPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
|
11
pubspec.lock
11
pubspec.lock
@ -573,6 +573,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
flutter_media_metadata:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../flutter_media_metadata"
|
||||
relative: true
|
||||
source: path
|
||||
version: "1.0.0"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -787,7 +794,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
@ -1389,5 +1396,5 @@ packages:
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
sdks:
|
||||
dart: ">=2.17.1 <3.0.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
@ -70,6 +70,9 @@ dependencies:
|
||||
queue: ^3.1.0+1
|
||||
auto_size_text: ^3.0.0
|
||||
badges: ^2.0.3
|
||||
mime: ^1.0.2
|
||||
flutter_media_metadata:
|
||||
path: ../flutter_media_metadata
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
|
||||
#include <flutter_media_metadata/flutter_media_metadata_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
@ -16,6 +17,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
BitsdojoWindowPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
|
||||
FlutterMediaMetadataPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterMediaMetadataPlugin"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
|
@ -5,6 +5,7 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_windows
|
||||
bitsdojo_window_windows
|
||||
flutter_media_metadata
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user