didvan-app/lib/services/media/media.dart

253 lines
7.5 KiB
Dart

import 'dart:io';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/providers/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:just_audio/just_audio.dart';
import 'package:path/path.dart' as p;
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:universal_html/html.dart' as html;
class MediaService {
static final audioPlayer = AudioPlayer();
static String? audioPlayerTag;
static StudioDetailsData? currentPodcast;
static StudioRequestArgs? podcastPlaylistArgs;
static int maxSizeInBytes = 15 * 1024 * 1024;
static Duration? get duration => audioPlayer.duration;
static Future<void> handleAudioPlayback({
required dynamic audioSource,
required int id,
bool isNetworkAudio = true,
bool isVoiceMessage = true,
bool isBlob = false,
void Function(bool isNext)? onTrackChanged,
}) async {
try {
String tag;
tag =
'${currentPodcast?.description == 'radar' ? 'radar' : isVoiceMessage ? 'message' : 'podcast'}-$id';
if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) {
audioSource = '${StorageService.appDocsDir}/podcasts/podcast-$id.mp3';
isNetworkAudio = false;
}
if (audioPlayerTag == tag) {
if (audioPlayer.playing) {
await audioPlayer.pause();
} else {
await audioPlayer.play();
}
return;
}
await audioPlayer.stop();
audioPlayerTag = tag;
String source;
if (isNetworkAudio) {
if (isVoiceMessage) {
source =
'${RequestHelper.baseUrl + audioSource}?accessToken=${RequestService.token}';
} else {
source = audioSource;
}
audioPlayer.setUrl(
source,
tag: isVoiceMessage
? null
: {
"artist": 'استودیو دیدوان',
"title": currentPodcast?.title ?? '',
},
);
} else {
if (isBlob) {
audioPlayer.setAudioSource(AudioSource.uri(Uri.parse(audioSource)));
} else {
audioPlayer.setFilePath(
audioSource,
tag: isVoiceMessage
? null
: {
"artist": 'استودیو دیدوان',
"title": currentPodcast?.title ?? '',
},
);
}
}
await audioPlayer.play();
// await audioPlayer.open(
// audio,
// showNotification: !isVoiceMessage,
// notificationSettings: NotificationSettings(
// customStopAction: (_) => resetAudioPlayer(),
// customNextAction: (_) => onTrackChanged?.call(true),
// customPrevAction: (_) => onTrackChanged?.call(false),
// ),
// );
} catch (e) {
// resetAudioPlayer();
// rethrow;
}
}
static Future<void> resetAudioPlayer() async {
audioPlayerTag = null;
currentPodcast = null;
podcastPlaylistArgs = null;
await MediaService.audioPlayer.stop();
}
static Future<XFile?> pickImage({required ImageSource source}) async {
try {
final imagePicker = ImagePicker();
final XFile? pickedFile = await imagePicker.pickImage(source: source);
return pickedFile;
} catch (e) {
e.printError(info: 'Pick Image Fail');
return null;
}
}
static Future<FilePickerResult?> pickPdfFile() async {
try {
final FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['pdf'],
allowMultiple: false,
);
return result;
} catch (e) {
e.printError(info: 'Pick PDF Fail');
// navigatorKey.currentState!.pop();
return null;
}
}
static Future<FilePickerResult?> pickMultiFile() async {
try {
return await FilePicker.platform
.pickFiles(
type: FileType.any,
// allowedExtensions: [
// 'pdf',
// 'doc',
// 'docx',
// 'xls',
// 'xlsx',
// 'ppt',
// 'pptx',
// 'txt',
// 'mp3',
// 'wav',
// 'aac',
// 'ogg',
// 'flac'
// ], // You can specify allowed extensions if needed
allowMultiple: true,
// Note: The maxFiles parameter is not directly supported by FilePicker.
// You will need to handle the limit after selection if necessary.
)
.then((result) {
if (result != null && result.files.length > 3) {
// Handle the case where the selected files exceed the max limit
// You can show an error message or return null
return null; // or show a message to the user
}
return result;
});
} catch (e) {
e.printError(info: 'Pick Multi File Fail');
return null;
}
}
static Future<FilePickerResult?> pickAudioFile() async {
try {
return await FilePicker.platform.pickFiles(
type: FileType.audio,
allowMultiple: false,
);
} catch (e) {
e.printError(info: 'Pick Audio Fail');
return null;
}
}
static Future<String?> downloadFile(String url, {final String? name}) async {
final basename = name ?? p.basename(url).split('?accessToken=').first;
Directory? dir;
try {
if (Platform.isIOS) {
dir = await getApplicationDocumentsDirectory(); // for iOS
} else {
dir = Directory('/storage/emulated/0/Download/'); // for android
if (!await dir.exists()) dir = (await getExternalStorageDirectory())!;
}
} catch (err) {
if (kDebugMode) {
print("Cannot get download folder path $err");
}
}
String path = "${dir?.path}${Platform.isIOS ? '/' : ''}";
final status = await Permission.storage.request();
if (status.isGranted) {
try {
await FlutterDownloader.enqueue(
url: url,
savedDir: path,
fileName: basename,
showNotification: true,
openFileFromNotification: true,
);
} catch (e) {
if (kDebugMode) {
print("Exception$e");
}
return null;
}
} else {
return null;
}
return path;
}
static String downloadFileFromWeb(String url) {
html.AnchorElement anchorElement = html.AnchorElement(href: url);
anchorElement.download = url;
anchorElement.click();
return anchorElement.pathname!;
}
static onLoadingPickFile(BuildContext context) {
ActionSheetUtils(context).openDialog(
barrierDismissible: false,
data: ActionSheetData(
content: Center(
child: Image.asset(
Assets.loadingAnimation,
width: 60,
height: 60,
),
),
hasConfirmButton: false,
hasDismissButton: false,
));
}
}