Skip to content

Commit

Permalink
WIP OnAudioQuery and HiveDB migration
Browse files Browse the repository at this point in the history
  • Loading branch information
ashwinkey04 committed Jan 20, 2022
1 parent 8de980f commit 6fc3480
Show file tree
Hide file tree
Showing 18 changed files with 471 additions and 281 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.5.31'
repositories {
google()
jcenter()
Expand Down
5 changes: 4 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import 'package:raag/provider/settings_provider.dart';
import 'package:raag/view/splash_screen.dart';

import 'model/strings.dart';
import 'provider/db_provider.dart';
import 'provider/theme.dart';

PlayerProvider playerProvider = new PlayerProvider();

void main() {
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initHive();

SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
.then((_) => runApp(MyApp()));
Expand Down
63 changes: 0 additions & 63 deletions lib/model/music_model.dart

This file was deleted.

17 changes: 17 additions & 0 deletions lib/model/song_model_adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:hive/hive.dart';
import 'package:on_audio_query/on_audio_query.dart';

class SongModelAdapter extends TypeAdapter<SongModel> {
@override
final typeId = 32;

@override
SongModel read(BinaryReader reader) {
return SongModel(reader.read());
}

@override
void write(BinaryWriter writer, SongModel obj) {
writer.write(obj.displayNameWOExt);
}
}
21 changes: 11 additions & 10 deletions lib/provider/audio_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
import 'package:http/http.dart' as http;
import 'package:on_audio_query/on_audio_query.dart';
import 'package:path_provider/path_provider.dart';
import 'package:raag/model/music_model.dart';
import 'package:raag/provider/audio_query.dart';

AnimationController playPauseController;

Expand Down Expand Up @@ -57,17 +57,18 @@ Future<File> urlToFile(String imageUrl) async {
return file;
}

Widget getAlbumArt(Song song, Color iconColor) {
Widget getAlbumArt(SongModel song, Color iconColor) {
final OfflineAudioQuery audioQuery = new OfflineAudioQuery();
final defaultIcon = Icon(Icons.music_note_sharp,
size: 24, color: iconColor);
if (song?.albumArtwork !=
null) // Directly access album art when scoped storage approach is not used (less than Android API level 29)
return Image(
image: FileImage(File(song.albumArtwork)),
);
// if (song?.albumArtwork !=
// null) // Directly access album art when scoped storage approach is not used (less than Android API level 29)
// return Image(
// image: FileImage(File(song.albumArtwork)),
// );
return FutureBuilder(
future:
FlutterAudioQuery().getArtwork(type: ResourceType.SONG, id: song?.id),
future:
audioQuery.getAlbumArt(song.id),
builder: (context, snapshot) {
Uint8List _imageBytes = snapshot.data;
if (_imageBytes == null || _imageBytes.isEmpty)
Expand Down
238 changes: 238 additions & 0 deletions lib/provider/audio_query.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
* This file is part of BlackHole (https://github.com/Sangwan5688/BlackHole).
*
* BlackHole is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BlackHole is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with BlackHole. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (c) 2021-2022, Ankit Sangwan
*/

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:on_audio_query/on_audio_query.dart';

class OfflineAudioQuery {
static OnAudioQuery audioQuery = OnAudioQuery();
static final RegExp avoid = RegExp(r'[\.\\\*\:\"\?#/;\|]');

Future<void> requestPermission() async {
while (!await audioQuery.permissionsStatus()) {
await audioQuery.permissionsRequest();
}
}

Future<List<SongModel>> getSongs({
SongSortType sortType,
OrderType orderType,
String path,
}) async {
return audioQuery.querySongs(
sortType: sortType ?? SongSortType.DATE_ADDED,
orderType: orderType ?? OrderType.DESC_OR_GREATER,
uriType: UriType.EXTERNAL,
path: path,
);
}

Future<Uint8List> getAlbumArt(int id) =>
audioQuery.queryArtwork(id, ArtworkType.AUDIO);

Future<List<PlaylistModel>> getPlaylists() async {
return audioQuery.queryPlaylists();
}

Future<bool> createPlaylist({String name}) async {
name.replaceAll(avoid, '').replaceAll(' ', ' ');
return audioQuery.createPlaylist(name);
}

Future<bool> removePlaylist({int playlistId}) async {
return audioQuery.removePlaylist(playlistId);
}

Future<bool> addToPlaylist({
int playlistId,
int audioId,
}) async {
return audioQuery.addToPlaylist(playlistId, audioId);
}

Future<bool> removeFromPlaylist({
int playlistId,
int audioId,
}) async {
return audioQuery.removeFromPlaylist(playlistId, audioId);
}

Future<bool> renamePlaylist({
int playlistId,
String newName,
}) async {
return audioQuery.renamePlaylist(playlistId, newName);
}

Future<List<SongModel>> getPlaylistSongs(
int playlistId, {
SongSortType sortType,
OrderType orderType,
String path,
}) async {
return audioQuery.queryAudiosFrom(
AudiosFromType.PLAYLIST,
playlistId,
sortType: sortType ?? SongSortType.DATE_ADDED,
orderType: orderType ?? OrderType.DESC_OR_GREATER,
);
}

Future<List<AlbumModel>> getAlbums({
AlbumSortType sortType,
OrderType orderType,
}) async {
return audioQuery.queryAlbums(
sortType: sortType,
orderType: orderType,
uriType: UriType.EXTERNAL,
);
}

Future<List<ArtistModel>> getArtists({
ArtistSortType sortType,
OrderType orderType,
}) async {
return audioQuery.queryArtists(
sortType: sortType,
orderType: orderType,
uriType: UriType.EXTERNAL,
);
}

Future<List<GenreModel>> getGenres({
GenreSortType sortType,
OrderType orderType,
}) async {
return audioQuery.queryGenres(
sortType: sortType,
orderType: orderType,
uriType: UriType.EXTERNAL,
);
}

static Future<String> queryNSave({
int id,
ArtworkType type,
String tempPath,
String fileName,
int size = 200,
int quality = 100,
ArtworkFormat format = ArtworkFormat.JPEG,
}) async {
final File file = File('$tempPath/$fileName.jpg');

if (!await file.exists()) {
await file.create();
final Uint8List image = await audioQuery.queryArtwork(
id,
type,
format: format,
size: size,
quality: quality,
);
file.writeAsBytesSync(image);
}
return file.path;
}

static Widget offlineArtworkWidget({
int id,
ArtworkType type,
String tempPath,
String fileName,
int size = 200,
int quality = 100,
ArtworkFormat format = ArtworkFormat.JPEG,
ArtworkType artworkType = ArtworkType.AUDIO,
BorderRadius borderRadius,
Clip clipBehavior = Clip.antiAlias,
BoxFit fit = BoxFit.cover,
FilterQuality filterQuality = FilterQuality.low,
double height = 50.0,
double width = 50.0,
double elevation = 5,
ImageRepeat imageRepeat = ImageRepeat.noRepeat,
bool gaplessPlayback = true,
Widget errorWidget,
Widget placeholder,
}) {
return FutureBuilder<String>(
future: queryNSave(
id: id,
type: type,
format: format,
quality: quality,
size: size,
tempPath: tempPath,
fileName: fileName,
),
builder: (context, item) {
if (item.data != null && item.data.isNotEmpty) {
return Card(
elevation: elevation,
shape: RoundedRectangleBorder(
borderRadius: borderRadius ?? BorderRadius.circular(7.0),
),
clipBehavior: clipBehavior,
child: Image(
image: FileImage(
File(
item.data,
),
),
gaplessPlayback: gaplessPlayback,
repeat: imageRepeat,
width: width,
height: height,
fit: fit,
filterQuality: filterQuality,
errorBuilder: (context, exception, stackTrace) {
return errorWidget ??
Image(
fit: BoxFit.cover,
height: height,
width: width,
image: const AssetImage('assets/cover.jpg'),
);
},
),
);
}
return Card(
elevation: elevation,
shape: RoundedRectangleBorder(
borderRadius: borderRadius ?? BorderRadius.circular(7.0),
),
clipBehavior: clipBehavior,
child: placeholder ??
Image(
fit: BoxFit.cover,
height: height,
width: width,
image: const AssetImage('assets/cover.jpg'),
),
);
},
);
}
}
Loading

0 comments on commit 6fc3480

Please sign in to comment.