new audio player package basic implementaion

This commit is contained in:
MohammadTaha Basiri 2022-04-05 22:30:39 +04:30
parent 2836b6f335
commit 6d55a3cf52
12 changed files with 95 additions and 111 deletions

View File

@ -4,6 +4,8 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application <application
android:label="Didvan" android:label="Didvan"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -12,13 +14,17 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize"
android:name="com.ryanheise.audioservice.AudioServiceActivity"
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
@ -40,10 +46,16 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity <service android:name="com.ryanheise.audioservice.AudioService">
android:name="com.yalantis.ucrop.UCropActivity" <intent-filter>
android:screenOrientation="portrait" <action android:name="android.media.browse.MediaBrowserService" />
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/> </intent-filter>
</service>
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
</application> </application>

View File

@ -1,5 +1,7 @@
PODS: PODS:
- audio_session (0.0.1): - assets_audio_player (0.0.1):
- Flutter
- assets_audio_player_web (0.0.1):
- Flutter - Flutter
- better_player (0.0.1): - better_player (0.0.1):
- Cache (~> 6.0.0) - Cache (~> 6.0.0)
@ -83,8 +85,6 @@ PODS:
- TOCropViewController (~> 2.6.1) - TOCropViewController (~> 2.6.1)
- image_picker (0.0.1): - image_picker (0.0.1):
- Flutter - Flutter
- just_audio (0.0.1):
- Flutter
- nanopb (2.30908.0): - nanopb (2.30908.0):
- nanopb/decode (= 2.30908.0) - nanopb/decode (= 2.30908.0)
- nanopb/encode (= 2.30908.0) - nanopb/encode (= 2.30908.0)
@ -111,15 +111,14 @@ PODS:
- TOCropViewController (2.6.1) - TOCropViewController (2.6.1)
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- video_player_avfoundation (0.0.1):
- Flutter
- wakelock (0.0.1): - wakelock (0.0.1):
- Flutter - Flutter
- webview_flutter_wkwebview (0.0.1): - webview_flutter_wkwebview (0.0.1):
- Flutter - Flutter
DEPENDENCIES: DEPENDENCIES:
- audio_session (from `.symlinks/plugins/audio_session/ios`) - assets_audio_player (from `.symlinks/plugins/assets_audio_player/ios`)
- assets_audio_player_web (from `.symlinks/plugins/assets_audio_player_web/ios`)
- better_player (from `.symlinks/plugins/better_player/ios`) - better_player (from `.symlinks/plugins/better_player/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
@ -128,13 +127,11 @@ DEPENDENCIES:
- flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`) - flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`) - image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_picker (from `.symlinks/plugins/image_picker/ios`) - image_picker (from `.symlinks/plugins/image_picker/ios`)
- just_audio (from `.symlinks/plugins/just_audio/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- record (from `.symlinks/plugins/record/ios`) - record (from `.symlinks/plugins/record/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
- wakelock (from `.symlinks/plugins/wakelock/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
@ -158,8 +155,10 @@ SPEC REPOS:
- TOCropViewController - TOCropViewController
EXTERNAL SOURCES: EXTERNAL SOURCES:
audio_session: assets_audio_player:
:path: ".symlinks/plugins/audio_session/ios" :path: ".symlinks/plugins/assets_audio_player/ios"
assets_audio_player_web:
:path: ".symlinks/plugins/assets_audio_player_web/ios"
better_player: better_player:
:path: ".symlinks/plugins/better_player/ios" :path: ".symlinks/plugins/better_player/ios"
firebase_core: firebase_core:
@ -176,8 +175,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/image_cropper/ios" :path: ".symlinks/plugins/image_cropper/ios"
image_picker: image_picker:
:path: ".symlinks/plugins/image_picker/ios" :path: ".symlinks/plugins/image_picker/ios"
just_audio:
:path: ".symlinks/plugins/just_audio/ios"
path_provider_ios: path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios" :path: ".symlinks/plugins/path_provider_ios/ios"
permission_handler_apple: permission_handler_apple:
@ -188,15 +185,14 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite/ios" :path: ".symlinks/plugins/sqflite/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/ios"
wakelock: wakelock:
:path: ".symlinks/plugins/wakelock/ios" :path: ".symlinks/plugins/wakelock/ios"
webview_flutter_wkwebview: webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios" :path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
audio_session: 4f3e461722055d21515cf3261b64c973c062f345 assets_audio_player: edee322b9cb625571b830b35872ead1a295fd917
assets_audio_player_web: 19826380c44375761aa0b9053665c1e3fbc3b86b
better_player: 2406bfe8175203c7a46fa15f9d778d73b12e1646 better_player: 2406bfe8175203c7a46fa15f9d778d73b12e1646
Cache: 4ca7e00363fca5455f26534e5607634c820ffc2d Cache: 4ca7e00363fca5455f26534e5607634c820ffc2d
Firebase: 7e8fe528c161b9271d365217a74c16aaf834578e Firebase: 7e8fe528c161b9271d365217a74c16aaf834578e
@ -216,7 +212,6 @@ SPEC CHECKSUMS:
HLSCachingReverseProxyServer: 59935e1e0244ad7f3375d75b5ef46e8eb26ab181 HLSCachingReverseProxyServer: 59935e1e0244ad7f3375d75b5ef46e8eb26ab181
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98 image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
image_picker: 541dcbb3b9cf32d87eacbd957845d8651d6c62c3 image_picker: 541dcbb3b9cf32d87eacbd957845d8651d6c62c3
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
@ -227,7 +222,6 @@ SPEC CHECKSUMS:
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162 webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162

View File

@ -28,6 +28,10 @@
<string>Main</string> <string>Main</string>
<key>FirebaseAppDelegateProxyEnabled</key> <key>FirebaseAppDelegateProxyEnabled</key>
<false/> <false/>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>We need to access to the microphone to record audio file</string> <string>We need to access to the microphone to record audio file</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>

View File

@ -1,5 +1,4 @@
import 'package:didvan/models/settings_data.dart'; import 'package:didvan/models/settings_data.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/storage/storage.dart'; import 'package:didvan/services/storage/storage.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
@ -15,7 +14,6 @@ class AppInitializer {
StorageService.appDocsDir = StorageService.appDocsDir =
(await getApplicationDocumentsDirectory()).path; (await getApplicationDocumentsDirectory()).path;
StorageService.appTempsDir = (await getTemporaryDirectory()).path; StorageService.appTempsDir = (await getTemporaryDirectory()).path;
MediaService.init();
} }
} }

View File

@ -6,22 +6,15 @@ import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart'; import 'package:didvan/services/storage/storage.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:just_audio/just_audio.dart'; import 'package:assets_audio_player/assets_audio_player.dart';
class MediaService { class MediaService {
static final AudioPlayer audioPlayer = AudioPlayer(); static final audioPlayer = AssetsAudioPlayer();
static String? audioPlayerTag; static String? audioPlayerTag;
static StudioDetailsData? currentPodcast; static StudioDetailsData? currentPodcast;
static StudioRequestArgs? podcastPlaylistArgs; static StudioRequestArgs? podcastPlaylistArgs;
static void init() { static Duration? get duration => audioPlayer.current.value?.audio.duration;
audioPlayer.positionStream.listen((event) {
if (audioPlayer.duration != null && audioPlayer.duration! < event) {
audioPlayer.stop();
audioPlayer.seek(const Duration(seconds: 0));
}
});
}
static Future<void> handleAudioPlayback({ static Future<void> handleAudioPlayback({
required dynamic audioSource, required dynamic audioSource,
@ -37,31 +30,32 @@ class MediaService {
isNetworkAudio = false; isNetworkAudio = false;
} }
if (audioPlayerTag == tag) { if (audioPlayerTag == tag) {
if (audioPlayer.playing) { await audioPlayer.playOrPause();
await audioPlayer.pause(); return;
} else { }
await audioPlayer.play(); await audioPlayer.stop();
} audioPlayerTag = tag;
} else { if (isNetworkAudio) {
await audioPlayer.stop(); await audioPlayer.open(
audioPlayerTag = tag; Audio.network(
if (isNetworkAudio) {
await audioPlayer.setUrl(
isVoiceMessage isVoiceMessage
? (RequestHelper.baseUrl + ? (RequestHelper.baseUrl +
audioSource + audioSource +
'?accessToken=${RequestService.token}') '?accessToken=${RequestService.token}')
: audioSource, : audioSource,
),
);
} else {
if (kIsWeb) {
await audioPlayer.open(
Audio.network(audioSource!.replaceAll('%3A', ':')),
); );
} else { } else {
if (kIsWeb) { await audioPlayer.open(Audio.file(audioSource));
await audioPlayer.setUrl(audioSource!.replaceAll('%3A', ':'));
} else {
await audioPlayer.setFilePath(audioSource);
}
} }
audioPlayer.play();
} }
audioPlayer.play();
audioPlayer.updateCurrentAudioNotification();
} }
static Future<void> resetAudioPlayer() async { static Future<void> resetAudioPlayer() async {

View File

@ -21,7 +21,7 @@ class AudioWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.playingStream, stream: MediaService.audioPlayer.isPlaying,
builder: (context, snapshot) { builder: (context, snapshot) {
return Row( return Row(
children: [ children: [
@ -56,7 +56,7 @@ class _AudioControllerButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DidvanIconButton( return DidvanIconButton(
icon: MediaService.audioPlayer.playing == true && _nowPlaying icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying
? DidvanIcons.pause_circle_solid ? DidvanIcons.pause_circle_solid
: DidvanIcons.play_circle_solid, : DidvanIcons.play_circle_solid,
color: Theme.of(context).colorScheme.focusedBorder, color: Theme.of(context).colorScheme.focusedBorder,

View File

@ -117,12 +117,12 @@ class StudioDetailsState extends CoreProvier {
); );
if (nextStudio != null && !_positionListenerActivated) { if (nextStudio != null && !_positionListenerActivated) {
_positionListenerActivated = true; _positionListenerActivated = true;
MediaService.audioPlayer.positionStream.listen((event) { MediaService.audioPlayer.currentPosition.listen((event) {
if (MediaService.audioPlayerTag?.contains('message') == true) { if (MediaService.audioPlayerTag?.contains('message') == true) {
return; return;
} }
final duration = MediaService.audioPlayer.duration ?? final duration =
Duration(seconds: studio.duration); MediaService.duration ?? Duration(seconds: studio.duration);
if (event.compareTo(duration) > 0 && nextStudio != null) { if (event.compareTo(duration) > 0 && nextStudio != null) {
if (stopOnPodcastEnds) { if (stopOnPodcastEnds) {
MediaService.resetAudioPlayer(); MediaService.resetAudioPlayer();

View File

@ -107,9 +107,9 @@ class AudioPlayerWidget extends StatelessWidget {
onPressed: () { onPressed: () {
MediaService.audioPlayer.seek( MediaService.audioPlayer.seek(
Duration( Duration(
seconds: seconds: MediaService.audioPlayer.currentPosition
MediaService.audioPlayer.position.inSeconds + .value.inSeconds +
30, 30,
), ),
); );
}, },
@ -126,7 +126,7 @@ class AudioPlayerWidget extends StatelessWidget {
Expanded( Expanded(
child: Center( child: Center(
child: StreamBuilder<bool>( child: StreamBuilder<bool>(
stream: MediaService.audioPlayer.playingStream, stream: MediaService.audioPlayer.isPlaying,
builder: (context, snapshot) { builder: (context, snapshot) {
return _PlayPouseAnimatedIcon( return _PlayPouseAnimatedIcon(
audioSource: podcast.link, audioSource: podcast.link,
@ -149,7 +149,8 @@ class AudioPlayerWidget extends StatelessWidget {
Duration( Duration(
seconds: max( seconds: max(
0, 0,
MediaService.audioPlayer.position.inSeconds - MediaService.audioPlayer.currentPosition.value
.inSeconds -
10, 10,
), ),
), ),
@ -254,16 +255,15 @@ class AudioPlayerWidget extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 64), padding: const EdgeInsets.symmetric(horizontal: 64),
child: DidvanButton( child: DidvanButton(
style: state.timerValue == style: state.timerValue == MediaService.duration?.inMinutes &&
MediaService.audioPlayer.duration?.inMinutes &&
state.stopOnPodcastEnds state.stopOnPodcastEnds
? ButtonStyleMode.primary ? ButtonStyleMode.primary
: ButtonStyleMode.flat, : ButtonStyleMode.flat,
title: 'پایان پادکست', title: 'پایان پادکست',
onPressed: () async { onPressed: () async {
state.timerValue = state.timerValue = MediaService.duration!.inMinutes -
MediaService.audioPlayer.duration!.inMinutes - MediaService
MediaService.audioPlayer.position.inMinutes; .audioPlayer.currentPosition.value.inMinutes;
await controller.animateTo( await controller.animateTo(
state.timerValue * 10, state.timerValue * 10,
duration: DesignConfig.lowAnimationDuration, duration: DesignConfig.lowAnimationDuration,
@ -337,7 +337,7 @@ class __PlayPouseAnimatedIconState extends State<_PlayPouseAnimatedIcon>
} }
void _handleAnimation() { void _handleAnimation() {
if (MediaService.audioPlayer.playing) { if (MediaService.audioPlayer.isPlaying.value) {
_animationController.forward(); _animationController.forward();
} else { } else {
_animationController.reverse(); _animationController.reverse();

View File

@ -26,7 +26,10 @@ class AudioSlider extends StatelessWidget {
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: StreamBuilder<Duration>( child: StreamBuilder<Duration>(
stream: _isPlaying ? MediaService.audioPlayer.positionStream : null, stream:
_isPlaying && MediaService.audioPlayer.currentPosition.hasValue
? MediaService.audioPlayer.currentPosition
: null,
builder: (context, snapshot) => ProgressBar( builder: (context, snapshot) => ProgressBar(
thumbColor: Theme.of(context).colorScheme.title, thumbColor: Theme.of(context).colorScheme.title,
progressBarColor: DesignConfig.isDark progressBarColor: DesignConfig.isDark
@ -34,12 +37,8 @@ class AudioSlider extends StatelessWidget {
: Theme.of(context).colorScheme.primary, : Theme.of(context).colorScheme.primary,
baseBarColor: Theme.of(context).colorScheme.border, baseBarColor: Theme.of(context).colorScheme.border,
bufferedBarColor: Theme.of(context).colorScheme.splash, bufferedBarColor: Theme.of(context).colorScheme.splash,
total: MediaService.audioPlayer.duration ?? total: MediaService.duration ?? Duration(seconds: duration ?? 0),
Duration(seconds: duration ?? 0),
progress: snapshot.data ?? Duration.zero, progress: snapshot.data ?? Duration.zero,
buffered: _isPlaying
? MediaService.audioPlayer.bufferedPosition
: Duration.zero,
thumbRadius: disableThumb ? 0 : 6, thumbRadius: disableThumb ? 0 : 6,
barHeight: 3, barHeight: 3,
timeLabelTextStyle: TextStyle( timeLabelTextStyle: TextStyle(

View File

@ -1,3 +1,4 @@
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
@ -14,7 +15,6 @@ import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart'; import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:just_audio/just_audio.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class DidvanBNB extends StatelessWidget { class DidvanBNB extends StatelessWidget {
@ -106,7 +106,7 @@ class _PlayerNavBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.playingStream, stream: MediaService.audioPlayer.isPlaying,
builder: (context, snapshot) => GestureDetector( builder: (context, snapshot) => GestureDetector(
onTap: () => MediaService.currentPodcast == null onTap: () => MediaService.currentPodcast == null
? null ? null
@ -195,12 +195,10 @@ class _PlayerNavBar extends StatelessWidget {
], ],
), ),
), ),
StreamBuilder<PlayerState>( StreamBuilder<PlayingAudio?>(
stream: MediaService.audioPlayer.playerStateStream, stream: MediaService.audioPlayer.onReadyToPlay,
builder: (context, snapshot) { builder: (context, snapshot) {
final playerState = MediaService if (snapshot.data == null ||
.audioPlayer.playerState.processingState;
if (playerState == ProcessingState.loading ||
state.appState == AppState.busy) { state.appState == AppState.busy) {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@ -224,8 +222,7 @@ class _PlayerNavBar extends StatelessWidget {
}, },
), ),
if (state.appState != AppState.busy && if (state.appState != AppState.busy &&
MediaService.audioPlayer.playerState.processingState != snapshot.data != null)
ProcessingState.loading)
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 12, left: 12,

View File

@ -1,6 +1,20 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
assets_audio_player:
dependency: "direct main"
description:
name: assets_audio_player
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.4+1"
assets_audio_player_web:
dependency: transitive
description:
name: assets_audio_player_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.4+1"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -8,13 +22,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.8.2"
audio_session:
dependency: transitive
description:
name: audio_session
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.6+1"
audio_video_progress_bar: audio_video_progress_bar:
dependency: "direct main" dependency: "direct main"
description: description:
@ -406,27 +413,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3" version: "0.6.3"
just_audio:
dependency: "direct main"
description:
name: just_audio
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.20"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.7"
lints: lints:
dependency: transitive dependency: transitive
description: description:

View File

@ -50,7 +50,6 @@ dependencies:
flutter_vibrate: ^1.3.0 flutter_vibrate: ^1.3.0
universal_html: ^2.0.8 universal_html: ^2.0.8
record: ^3.0.2 record: ^3.0.2
just_audio: ^0.9.18
record_web: ^0.2.1 record_web: ^0.2.1
persian_datetime_picker: ^2.4.0 persian_datetime_picker: ^2.4.0
persian_number_utility: ^1.1.1 persian_number_utility: ^1.1.1
@ -66,6 +65,7 @@ dependencies:
expandable_bottom_sheet: ^1.1.1+1 expandable_bottom_sheet: ^1.1.1+1
permission_handler: ^9.2.0 permission_handler: ^9.2.0
better_player: ^0.0.81 better_player: ^0.0.81
assets_audio_player: ^3.0.4+1
dev_dependencies: dev_dependencies: