feat(broken): Broken Warning! Initial Local Audio Player

This commit is contained in:
Kingkor Roy Tirtho 2022-08-30 16:08:01 +06:00
parent 24c9270bed
commit c3bf5119eb
12 changed files with 132 additions and 6 deletions

3
.vscode/launch.json vendored
View File

@ -6,8 +6,7 @@
"type": "dart",
"request": "launch",
"program": "lib/main.dart"
}
},
],
"compounds": []
}

View File

@ -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(),
]),
),
),

View 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();
}
}

View File

@ -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 &&

View File

@ -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;
}
}

View File

@ -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);

View File

@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_linux
bitsdojo_window_linux
flutter_media_metadata
url_launcher_linux
)

View File

@ -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"))

View File

@ -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"

View File

@ -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:

View File

@ -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(

View File

@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_windows
bitsdojo_window_windows
flutter_media_metadata
permission_handler_windows
url_launcher_windows
)