Search code examples
flutterjust-audioaudio-service

Changing Audio Source In audio_service and just_audio (Flutter)


I am working on my first Flutter app which implements basic stream functionality. Upon starting, the app loads a stream from source A. The app contains navigation menus to allow the user to play streams from additional sources B, C, D... etc. The initial stream from source A functions exactly as expected, but I can't figure out how to change the stream source from A to B, C, D. To be clear, I understand what I need to do within the UI, but I am not sure how to change the audio's source within audio_service and just_audio. Looking through docs, I found a good candidate function provided by AudioHandler within the audio_service.dart package (playMediaItem()), however, creating a new MediaItem and passing it to this function has no effect:

I have set up my AudioPlayerHander class according to the audio_service docs:

class AudioPlayerHandler extends BaseAudioHandler {
  // Declare MediaItem used for streaming
  static const _stream = MediaItem(
    id: 'some URL',
    title: 'Stream A',
  );

  // Instantiate a just_audio AudioPlayer
  final _player = AudioPlayer();

  //Initialize audio handler
  AudioPlayerHandler() {
    _player.playbackEventStream.map(_transformEvent).pipe(playbackState);
    mediaItem.add(_stream);
    _player.setAudioSource(AudioSource.uri(Uri.parse(_stream.id)));
  }

  @override
  Future<void> play() => _player.play();

  @override
  Future<void> pause() => _player.pause();

  @override
  Future<void> stop() => _player.stop();

The user can navigate to a route wherein they click a button to play source B:

var stream_b = MediaItem(
id: 'some URL', // 
title: 'Stream B',
);

audioHandler.playMediaItem(stream_b); //no apparent effect
audioHandler.play(); // If stream A was paused or stopped, it will now resume 

Solution

  • Within class AudioPlayerHandler shown above, I needed to add a method:

      Future<void> playMediaItem(MediaItem mediaItem) => _player.setUrl(mediaItem.id);