audio_service icon indicating copy to clipboard operation
audio_service copied to clipboard

Buffer Stream & Volume Stream not available

Open TheStarkster opened this issue 4 years ago • 10 comments

Is your feature request related to a problem? Please describe. we don't have buffer stream like we have in just_audio package as we're not able to access audio player instance from the background task class, so we're left with no choice but to rely on methods and streams which are being exposed from AudioService class

Describe the solution you'd like Provide a buffer stream in this package like just_audio

Describe alternatives you've considered we've no alternatives i presume

Additional context N/A

TheStarkster avatar Jul 08 '21 03:07 TheStarkster

Describe alternatives you've considered we've no alternatives i presume

An alternative would be to implement your own streams as needed because everything can be derived from playbackState.

E.g.:

  final ValueStream<Duration> bufferedPosition =
      BehaviorSubject.seeded(Duration.zero)
        ..addStream(_handler.playbackState
            .map((state) => state.bufferedPosition)
            .distinct());

But I'll leave this issue open since I may eventually consider adding such a stream in audio_service.

ryanheise avatar Jul 08 '21 03:07 ryanheise

thanks man! i saw there's almost everything in playbackstate that i need and im already streaming events to my bloc something like that

AudioService.playbackStateStream.listen((event) {
     add(AudioEvent.updatePlaybackState(event));
});

TheStarkster avatar Jul 08 '21 03:07 TheStarkster

hey @ryanheise what about volume stream? we can set a custom action to set the volume but how we can get the stream of it like just_audio? are we supposed to preserve in some local storage?

TheStarkster avatar Jul 08 '21 04:07 TheStarkster

Because everything is now in one isolate, i.e. in the same address space, you can share a reference to that just_audio stream with your UI.

ryanheise avatar Jul 08 '21 05:07 ryanheise

i am afraid, i don't know how to do so can you please elaborate? however i am trying this right now haven't tested this yet

player.volumeStream.listen((event) {
   AudioServiceBackground.sendCustomEvent(event);
});

and will try to listen to this in my bloc

TheStarkster avatar Jul 08 '21 05:07 TheStarkster

As a very simple example, you can copy player.bufferedPositionStream into a global variable and access it from anywhere. That's not great from a design point of view, but just as a means of explaining that it is possible to share a reference to the stream anywhere.

ryanheise avatar Jul 08 '21 07:07 ryanheise

ok but im not a big fan of global variables but i tried something else, what i did is sending custom events to my bloc

player.bufferedPositionStream.listen((event) {
      AudioServiceBackground.sendCustomEvent({"buffer": event});
    });

as i mentioned above and listening to those custom events in my bloc like this

AudioService.customEventStream.listen((event) {
            if(event["volume"] != null) {
              add(AudioEvent.updateVolumeStream(event["volume"] ?? 0));
            } else if(event["position"] != null) {
              add(AudioEvent.updatePositionStream(event["position"]));
            } else if(event["buffer"] != null) {
              add(AudioEvent.updateBufferStream(event["buffer"]));
            } else if(event["duration"] != null) {
              add(AudioEvent.updateDuration(event["duration"]));
            }
          });

and in those events which im calling (bloc events) im updating this state

class AudioDataStream extends Equatable {
  final Duration? bufferPosition;
  final Duration? audioPosition;
  final Duration? audioLength;
  final PlaybackState? playbackState;
  final bool? playing;
  final double? volume;
 // ...

i am putting this 👆 code just in case someone stumbled upon here, so it will be helpful.

and now there's something i would like to mention because i don't know if its my lack of knowledge for the playbackstate thing, but what it's doing is that it's streaming buffer and position after a delay of few second better say after a minute or so do you have any idea @ryanheise why is that, because of this thing i switched to AudioPlayer 's streams.

TheStarkster avatar Jul 08 '21 08:07 TheStarkster

I see from your code that you're asking about the stable release, whereas my answer was about the version that is development in Git (on the one-isolate branch). A global variable (again I'm not saying that's a good design) will not work in the current stable release, only in the latest development version. The point of that global variable example was not to say you should do it as a global variable but rather to explain that in the new "one isolate" version of audio_service, everything is in a single address space and so it is possible to pass references from anywhere to anywhere. It is up to you to take that and implement reference passing in a good architectural style.

I'm not sure about the delay issue you're running into, but any fix would be implemented on the development version anyway, so I would suggest testing on that.

ryanheise avatar Jul 08 '21 08:07 ryanheise

yea i somewhat assumed that there must be some other block of memory would've been allocated for that background class where we encapsulates all the business logic for audio. now i got your point when you just mentioned the "one-isolate" word all of that makes sense, thanks for helping out, i didn't knew about that branch

so im closing this issue for now & i'll open this if i see any issue regarding this whole thing, thanks a ton again!

TheStarkster avatar Jul 08 '21 09:07 TheStarkster

As per the reasons mentioned above, I still want to keep this open.

ryanheise avatar Jul 08 '21 11:07 ryanheise