Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble closing an audio session #122

Closed
appcapsergen opened this issue Feb 5, 2024 · 1 comment
Closed

Trouble closing an audio session #122

appcapsergen opened this issue Feb 5, 2024 · 1 comment

Comments

@appcapsergen
Copy link

appcapsergen commented Feb 5, 2024

In my Flutter app the user is able to play a video, I use the chewie package for this. This player uses a VideoPlayerController (from the video_player package) to somewhat control the video player, which ultimately allows me to use the audio_service package to create an audio session. I use this to continue playing the video when the app is paused (in the background or when the phone is locked).

The problem I'm faced with now is that when I've started a video with background audio playback successfully, but then want to close that video, I can't seem to get the audio session to stop as well. This is especially visible on iOS (like in this screenshot), where the media player stays active even though I shut down the video and attempted to shut down the audio session as well.

Here's my audio handler, I basically close the audio handler by calling resetVideoFunctions. I have tried multiple things though, like closing/disposing the mediaItem, closing/disposing the player state, closing/disposing the streamController, closing/disposing the video controller, etc., etc... Nothing works

class MyAudioHandler extends BaseAudioHandler {
  StreamController<PlaybackState>? streamController;
  VoidCallback? _videoPlay, _videoPause, _videoStop;
  void Function(Duration position)? _videoSeek;

  HuddleAudioHandler();

  void setVideoFunctions(
      VoidCallback play, VoidCallback pause, VoidCallback stop, void Function(Duration position) seek, MediaItem item) {
    mediaItem.add(item);
    _videoPlay = play;
    _videoPause = pause;
    _videoStop = stop;
    _videoSeek = seek;
  }

  Future<void> resetVideoFunctions() async {
    mediaItem.add(null);
    _videoPlay = null;
    _videoPause = null;
    _videoStop = null;
    _videoSeek = null;
  }

  @override
  Future<void> play() async {
    _videoPlay?.call();
  }

  @override
  Future<void> pause() async {
    _videoPause?.call();
  }

  @override
  Future<void> stop() async {
    _videoStop?.call();
  }

  @override
  Future<void> seek(Duration position) async {
    _videoSeek?.call(position);
  }

  void initializeStreamController(VideoPlayerController? videoPlayerController) {
    bool isPlaying() => videoPlayerController?.value.isPlaying ?? false;

    AudioProcessingState processingState() {
      if (videoPlayerController == null) {
        return AudioProcessingState.idle;
      }
      if (videoPlayerController.value.isInitialized) {
        return AudioProcessingState.ready;
      }
      return AudioProcessingState.idle;
    }

    Duration bufferedPosition() {
      final DurationRange? currentBufferedRange =
          videoPlayerController?.value.buffered.firstOrNullWhere((DurationRange durationRange) {
        final Duration position = videoPlayerController.value.position;
        final bool isCurrentBufferedRange = durationRange.start < position && durationRange.end > position;
        return isCurrentBufferedRange;
      });

      return currentBufferedRange != null ? currentBufferedRange.end : Duration.zero;
    }

    void addVideoEvent() {
      streamController?.add(PlaybackState(
        controls: <MediaControl>[
          MediaControl.rewind,
          if (isPlaying()) MediaControl.pause else MediaControl.play,
          MediaControl.stop,
          MediaControl.fastForward,
        ],
        systemActions: const <MediaAction>{
          MediaAction.seek,
          MediaAction.seekForward,
          MediaAction.seekBackward,
        },
        androidCompactActionIndices: const <int>[0, 1, 3],
        processingState: processingState(),
        playing: isPlaying(),
        updatePosition: videoPlayerController?.value.position ?? Duration.zero,
        bufferedPosition: bufferedPosition(),
        speed: videoPlayerController?.value.playbackSpeed ?? 1.0,
      ));
    }

    void startStream() {
      videoPlayerController?.addListener(addVideoEvent);
    }

    void stopStream() {
      videoPlayerController?.removeListener(addVideoEvent);
      streamController?.close();
      streamController = null;
    }

    streamController = StreamController<PlaybackState>(
        onListen: startStream, onPause: stopStream, onResume: startStream, onCancel: stopStream);
  }
}

Hopefully someone can help me close the audio session!

@appcapsergen
Copy link
Author

appcapsergen commented Feb 5, 2024

My apologies, wrong package

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant