Skip to content

Commit

Permalink
🐛 Fix: downloaded files not playing on IOS
Browse files Browse the repository at this point in the history
  • Loading branch information
devaryakjha committed Oct 23, 2023
1 parent ea58d9b commit 5b09d34
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 21 deletions.
31 changes: 27 additions & 4 deletions lib/cubits/download/download_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import 'dart:io';
import 'package:background_downloader/background_downloader.dart';
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:varanasi_mobile_app/features/user-library/data/user_library.dart';
import 'package:varanasi_mobile_app/models/app_config.dart';
Expand All @@ -21,7 +23,7 @@ import 'package:varanasi_mobile_app/utils/logger.dart';
part 'download_state.dart';

class DownloadCubit extends AppCubit<DownloadState> {
DownloadCubit() : super(const DownloadState());
DownloadCubit() : super(DownloadInitial());

late final Box<DownloadedMedia> _downloadBox;
late final FileDownloader _downloader;
Expand All @@ -32,11 +34,19 @@ class DownloadCubit extends AppCubit<DownloadState> {

Box<DownloadedMedia> get downloadBox => _downloadBox;

FileDownloader get downloader => _downloader;

DownloadLoadedState get loadedState => state as DownloadLoadedState;

@override
FutureOr<void> init() async {
final baseDir = await getApplicationDocumentsDirectory();
emit(DownloadLoadedState(downloadDirectory: baseDir));
_songMap = {};
_downloadBox = Hive.box<DownloadedMedia>(AppStrings.downloadBoxName);
_downloader = FileDownloader();
_downloader = FileDownloader()
..trackTasks()
..resumeFromBackground();
_downloader.updates.listen((update) {
if (update is TaskStatusUpdate) {
_handleTaskStatusUpdate(update);
Expand Down Expand Up @@ -144,12 +154,13 @@ class DownloadCubit extends AppCubit<DownloadState> {
for (final song in filteredsong) {
_songMap[song.itemId] = song;
}
emit(state.updateProgress(MapEntry(playlist.id!, 0)));
emit(loadedState.updateProgress(MapEntry(playlist.id!, 0)));
await _downloader.downloadBatch(
tasks,
batchProgressCallback: (succeeded, failed) {
final percentComplete = (succeeded + failed) / tasks.length;
emit(state.updateProgress(MapEntry(playlist.id!, percentComplete)));
emit(loadedState
.updateProgress(MapEntry(playlist.id!, percentComplete)));
_logger.i('Batch progress: $succeeded, $failed');
},
taskStatusCallback: _handleTaskStatusUpdate,
Expand Down Expand Up @@ -298,4 +309,16 @@ class DownloadCubit extends AppCubit<DownloadState> {
);
return library;
}

String getDownloadPath(String id) {
final item = _downloadBox.get(id);
final filename = _fileNameFromSong(item!.media);
return path.join(loadedState.downloadDirectory.path, '', filename);
}

File? getCacheFile(String itemId, String itemUrl) {
final ext = itemUrl.split('.').last;
final fileName = '$itemId.$ext';
return File(path.join(loadedState.downloadDirectory.path, '', fileName));
}
}
25 changes: 19 additions & 6 deletions lib/cubits/download/download_state.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
part of 'download_cubit.dart';

class DownloadState extends Equatable {
sealed class DownloadState extends Equatable {
const DownloadState();

@override
List<Object> get props => [];
}

class DownloadInitial extends DownloadState {}

class DownloadLoadedState extends DownloadState {
final Map<String, double> playlistProgressMap;
final Directory downloadDirectory;

const DownloadState({
const DownloadLoadedState({
this.playlistProgressMap = const {},
required this.downloadDirectory,
});

@override
List<Object> get props => [playlistProgressMap];
List<Object> get props => [playlistProgressMap, downloadDirectory];

DownloadState copyWith({
DownloadLoadedState copyWith({
Map<String, double>? playlistProgressMap,
Directory? downloadDirectory,
}) {
return DownloadState(
return DownloadLoadedState(
playlistProgressMap: playlistProgressMap ?? this.playlistProgressMap,
downloadDirectory: downloadDirectory ?? this.downloadDirectory,
);
}

DownloadState updateProgress(MapEntry<String, double> entry) {
DownloadLoadedState updateProgress(MapEntry<String, double> entry) {
final Map<String, double> oldProgress = Map.from(playlistProgressMap)
..addEntries([entry]);
return copyWith(
Expand Down
3 changes: 2 additions & 1 deletion lib/features/library/ui/library_widgets/page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' hide Typography;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Expand Down Expand Up @@ -134,7 +135,7 @@ class _LibraryContentState extends State<LibraryContent> {
sourceLibrary: state.sourceLibrary,
),
DisableChild(
disabled:
disabled: !kDebugMode &&
state.sourceLibrary?.isDownload == true,
child: DownloadPlaylist(
playlist: state.playlist,
Expand Down
1 change: 1 addition & 0 deletions lib/features/user-library/ui/user_library_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class UserLibraryPage extends HookWidget {
}
final library = [...state.library, downloadSnapshot.data]
.whereType<UserLibrary>()
.where((element) => element.isNotEmpty)
.toList()
..sort();
if (library.isEmpty) return const EmptyUserLibrary();
Expand Down
16 changes: 11 additions & 5 deletions lib/utils/player/audio_handler_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import 'dart:async';

import 'package:audio_service/audio_service.dart';
import 'package:audio_session/audio_session.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart';
import 'package:just_audio/just_audio.dart';
import 'package:rxdart/rxdart.dart';
import 'package:varanasi_mobile_app/cubits/config/config_cubit.dart';
import 'package:varanasi_mobile_app/cubits/download/download_cubit.dart';
import 'package:varanasi_mobile_app/models/app_config.dart';
import 'package:varanasi_mobile_app/models/download.dart';
import 'package:varanasi_mobile_app/utils/constants/strings.dart';
import 'package:varanasi_mobile_app/utils/helpers/get_app_context.dart';

import 'typings.dart';

Expand Down Expand Up @@ -183,13 +186,14 @@ final class AudioHandlerImpl extends BaseAudioHandler
final downloaded = _isSongDownloaded(itemId);
if (!downloaded) {
final uri = Uri.parse(mediaItem.id);
// final cacheFile =
// appContext.read<DownloadCubit>().getCacheFile(itemId, mediaItem.id);
final audioSource = LockCachingAudioSource(uri);
_mediaItemExpando[audioSource] = mediaItem;
return audioSource;
}
final box = Hive.box<DownloadedMedia>(AppStrings.downloadBoxName);
final downloadedMedia = box.get(itemId);
final audioSource = AudioSource.file(downloadedMedia!.path);
final path = appContext.read<DownloadCubit>().getDownloadPath(itemId);
final audioSource = AudioSource.file(path);
_mediaItemExpando[audioSource] = mediaItem;
return audioSource;
}
Expand All @@ -199,7 +203,8 @@ final class AudioHandlerImpl extends BaseAudioHandler

@override
Future<void> addQueueItem(MediaItem mediaItem) async {
await _playlist.add(_itemToSource(mediaItem));
final source = _itemToSource(mediaItem);
await _playlist.add(source);
}

@override
Expand All @@ -209,7 +214,8 @@ final class AudioHandlerImpl extends BaseAudioHandler

@override
Future<void> insertQueueItem(int index, MediaItem mediaItem) async {
await _playlist.insert(index, _itemToSource(mediaItem));
final source = _itemToSource(mediaItem);
await _playlist.insert(index, source);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/download_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DownloadPlaylist extends StatelessWidget {
@override
Widget build(BuildContext context) {
final progress = context.select((DownloadCubit value) =>
value.state.playlistProgressMap[playlist.id] ?? 0);
value.loadedState.playlistProgressMap[playlist.id] ?? 0);
final downloadBox = context.read<DownloadCubit>().downloadBox;
final keys = playlist.mediaItems?.map((e) => e.itemId).toList();
return ValueListenableBuilder(
Expand Down
8 changes: 4 additions & 4 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ packages:
source: hosted
version: "0.3.3+3"
path:
dependency: transitive
dependency: "direct main"
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
Expand All @@ -913,13 +913,13 @@ packages:
source: hosted
version: "1.0.1"
path_provider:
dependency: transitive
dependency: "direct main"
description:
name: path_provider
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.0.15"
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ dependencies:
background_downloader: ^7.10.1
lottie: ^2.7.0
percent_indicator: ^4.2.3
path_provider: ^2.1.1
path: ^1.8.3

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 5b09d34

Please sign in to comment.