0

I have make an overlay that should be appear if my music ends. that overlay has elevated buttons and by pressing them it should remove the overlay and starts play another audio. but by pressing it audio is begin to but overlay is not being remove.by second time pressing button it removes.

I have observed that while my phone having some other activity that occurs then it appearing again. in specific case I have observed that when it is another audio started playing then it is appearing again and if I'm getting notification of any other apps in my phone then it is appearing again.

So I mean it is affected somehow by random events.

Below is the full code method having _showChoices:

import 'dart:ui';
import 'package:app/stories/get_stories.dart';
import 'package:audio_service/audio_service.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:app/globals.dart' as globals;
import 'package:just_audio/just_audio.dart';
import '../widgets/error_alert.dart';
import 'package:audio_session/audio_session.dart';

class PlayingStory extends StatefulWidget {
  final String story;
  final String episode;
  final String playLink;
  final String poster;

  const PlayingStory(
      {Key? key,
      required this.story,
      required this.episode,
      required this.playLink,
      required this.poster})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => PlayingStoryState();
}

class PlayingStoryState extends State<PlayingStory> with WidgetsBindingObserver {

  double _value = 0.0;
  final audioPlayer = AudioPlayer();
  late bool isPlaying;
  late AppLifecycleState state;
  late String episode = widget.episode;

  void _showChoices(BuildContext context) {

    // GetStories().updateStoryList(widget.story,context);
    var nextEpisode = GetStories().fetchNextEpisodes(widget.story);

    OverlayState overlayState = Overlay.of(context);
    OverlayEntry? choice;

    final Size size = MediaQuery.of(context).size;
    final height = size.height;
    final width = size.width;

    choice = OverlayEntry(builder: (context) {
      print("_-_-_-_-_-_-_-_-_-_-_ OVERLAY CALLED _-_-_-_-_-_-_-_-_-_-_");
      return Scaffold(
        backgroundColor: Colors.transparent,
        body: Center(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: width * 0.035, vertical: height * 0.06),
            child: ColoredBox(
              color: const Color(0xff838080),
              child: BackdropFilter(
                filter: ImageFilter.blur(
                  sigmaY: 8.0,
                  sigmaX: 8.0,
                ),
                child: Center(
                  child: ListView(
                    children: [

                      FutureBuilder<Map<dynamic, dynamic>>(
                        future: nextEpisode,
                        builder: (context, snapshot) {
                          if (!snapshot.hasData) {
                            return const Center(
                              child: CircularProgressIndicator(),
                            );
                          }

                          final nxteps = snapshot.data!;

                          return ListView.builder(
                            physics: const NeverScrollableScrollPhysics(),
                            shrinkWrap: true,
                            itemCount: nxteps.length,
                            itemBuilder: (context, index) {
                              return ListTile(
                                onTap: () async {
                                  var eps = await GetStories().playNextEpisode(widget.story, nxteps.keys.toList()[index]);
                                  // eps.keys.toList().sort();
                                  setState(() {
                                    print(eps);
                                    audioInit(eps.values.toList()[0]);
                                    episode = eps.values.toList()[1];
                                    choice!.remove();
                                  });
                                },
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5),
                                ),
                                tileColor: Colors.red,
                                title: Text(
                                  nxteps.values.toList()[index],
                                  style: const TextStyle(color: Colors.white),
                                ),
                                subtitle: Text(
                                  nxteps.keys.toList()[index],
                                  style: const TextStyle(color: Colors.white),
                                ),
                                leading: IconButton(
                                  onPressed: () {
                                    choice!.remove();
                                  },
                                  color: Colors.white,
                                  iconSize: height * 0.04,
                                  icon: const Icon(
                                    Icons.play_arrow_rounded,
                                  ),
                                ),
                              );
                            },
                          );
                        },
                      )

                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      );
    });

    overlayState.insert(choice);
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    audioInit(widget.playLink);
    isPlaying = false;
  }

  Future<void> audioInit(audio) async {
    final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration.speech());

    audioPlayer.positionStream.listen((position) {
      if (mounted == true) {
        setState(() {
          _value = position.inSeconds.toDouble();
        });
      }
    });

    audioPlayer.playerStateStream.listen((event) {
      if(event.processingState == ProcessingState.completed) {
        if(mounted) {
          setState(() {
            isPlaying = false;
            _showChoices(context);
          });
        }
        if (kDebugMode) {
          print("_-_-_-_-_-_ SONG COMPLETED _-_-_-_-_-_");
        }
      } else {
        if (kDebugMode) {
          print("_-_-_-_-_-_ SONG NOT COMPLETED _-_-_-_-_-_");
        }
      }
    });

    audioPlayer.playbackEventStream.listen((event) {
    }, onError: (Object e, StackTrace stackTrace) {
      if (kDebugMode) {
        print('A stream error occurred: $e');
      }
    });
    // Try to load audio from a source and catch any errors.
    try {
      // AAC example: https://dl.espressif.com/dl/audio/ff-16b-2c-44100hz.aac
      await audioPlayer.setAudioSource(AudioSource.uri(
        Uri.parse(audio),
        tag: MediaItem(
          // Specify a unique ID for each media item:
          id: 'StoryFy',
          // Metadata to display in the notification:
          album: widget.story,
          title: episode.split("=")[0],
          artUri: Uri.parse(widget.poster),
        ),
      ));
    } catch (e) {
      if (kDebugMode) {
        print("Error loading audio source: $e");
      }
    }
  }

  // @override
  // void dispose() {
  //   audioPlayer.dispose();
  //   WidgetsBinding.instance.removeObserver(this);
  //   super.dispose();
  // }

  // @override
  // void didChangeAppLifecycleState(AppLifecycleState state) {
  //   super.didChangeAppLifecycleState(state);
  //   if (state == AppLifecycleState.resumed) {
  //     // Resume audio playback if necessary
  //     // if (isPlaying) {
  //     //   audioPlayer.play();
  //     // }
  //     state = state;
  //   } else if (state == AppLifecycleState.paused) {
  //     // Pause audio playback if necessary
  //     // if (isPlaying) {
  //     //   audioPlayer.pause();
  //     // }
  //   }
  // }

  String formatDuration(Duration duration) {
    final hours = duration.inHours.remainder(60).toString().padLeft(2, '0');
    final minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0');
    final seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');
    return '$hours:$minutes:$seconds';
  }

  @override
  Widget build(BuildContext context) {
    final Size screenSize = MediaQuery.of(context).size;
    final double width = screenSize.width;
    final double height = screenSize.height;

    return Scaffold(
        appBar: AppBar(),
        body: Padding(
          padding: EdgeInsets.symmetric(horizontal: width * 0.03),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Center(
                child: Card(
                  elevation: 10,
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(10),
                    child: Image.network(
                      widget.poster,
                      height: height * 0.5,
                      width: width,
                      fit: BoxFit.fill,
                    ),
                  ),
                ),
              ),
              SizedBox(
                height: height * 0.05,
              ),
              Center(
                child: Text(
                  episode.split("=")[0],
                  style: TextStyle(
                    fontSize: height * 0.03,
                  ),
                ),
              ),
              SizedBox(
                height: height * 0.01,
              ),
              Center(
                child: Text(
                  widget.story,
                  style: TextStyle(
                    fontSize: height * 0.02,
                  ),
                ),
              ),
              SizedBox(
                height: height * 0.02,
              ),
              StreamBuilder<Duration?>(
                stream: audioPlayer.durationStream,
                builder: (context, snapshot) {
                  final duration = snapshot.data ?? Duration.zero;
                  return Slider(
                    value: _value,
                    min: 0.0,
                    max: duration.inSeconds.toDouble(),
                    inactiveColor: globals.shadowColor,
                    onChanged: (newValue) {
                      final clampedValue = newValue.clamp(0.0, duration.inSeconds.toDouble());
                      audioPlayer.seek(Duration(seconds: clampedValue.toInt()));
                    },
                  );
                },
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  StreamBuilder<Duration>(
                    stream: audioPlayer.positionStream,
                    builder: (context, snapshot) {
                      final position = snapshot.data ?? Duration.zero;
                      return Text(formatDuration(position));
                    },
                  ),
                  StreamBuilder<Duration?>(
                    stream: audioPlayer.durationStream,
                    builder: (context, snapshot) {
                      final duration = snapshot.data ?? Duration.zero;
                      return Text(formatDuration(duration));
                    },
                  ),
                ],
              ),
              SizedBox(
                height: height * 0.02,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  IconButton(
                    onPressed: () {
                      showAlert(context, "data.values.toList()[index]");
                      audioPlayer.seekToPrevious();
                    },
                    iconSize: height * 0.05,
                    color: Colors.storyfytheme,
                    icon: const Icon(
                      Icons.skip_previous_rounded,
                    ),
                  ),
                  IconButton(
                    onPressed: () async {
                      final currentPosition = audioPlayer.position;
                      final duration = audioPlayer.duration;
                      if (currentPosition != null && duration != null) {
                        final newPosition = currentPosition - const Duration(seconds: 10);
                        final clampedPosition = newPosition.isNegative ? Duration.zero : newPosition;
                        audioPlayer.seek(clampedPosition);
                      }
                    },
                    iconSize: height * 0.05,
                    color: Colors.storyfytheme,
                    icon: const Icon(
                      Icons.replay_10_rounded,
                    ),
                  ),
                  IconButton(
                    onPressed: () {
                      if (mounted == true) {
                        setState(() {
                          (isPlaying)
                              ? audioPlayer.pause()
                              : audioPlayer.play();
                          isPlaying = !isPlaying;
                        });
                      }
                    },
                    iconSize: height * 0.05,
                    color: Colors.storyfytheme,
                    icon: isPlaying
                        ? const Icon(
                            Icons.pause,
                          )
                        : const Icon(
                            Icons.play_arrow_rounded,
                          ),
                  ),
                  IconButton(
                    onPressed: () async {
                      final currentPosition = audioPlayer.position;
                      final duration = audioPlayer.duration;
                      if (currentPosition != null && duration != null) {
                        final newPosition = currentPosition + const Duration(seconds: 10);
                        final clampedPosition = newPosition.compareTo(duration) > 0 ? duration : newPosition;
                        audioPlayer.seek(clampedPosition);
                      }
                      // await audioPlayer.seek(Duration(
                      //     seconds: audioPlayer.position.inSeconds + 10));
                    },
                    iconSize: height * 0.05,
                    color: Colors.storyfytheme,
                    icon: const Icon(
                      Icons.forward_10_rounded,
                    ),
                  ),
                  IconButton(
                    onPressed: () {
                      showAlert(context, "data.values.toList()[index]");
                      audioPlayer.seekToNext();
                    },
                    iconSize: height * 0.05,
                    color: Colors.storyfytheme,
                    icon: const Icon(
                      Icons.skip_next_rounded,
                    ),
                  )
                ],
              )
            ],
          ),
        )
    );
  }
}

Thanks...

0 Answers0