flutterdartflutter-audio-query

How to change the current mediaItem when the next mediaItem in the queue is played


I'm developing an iOS app in Flutter, using a package called audio_service. I use AudioServiceBackground.serQueue() to set multiple MediaItem to a Queue.

In the UI part, I'm trying to use AudioService.currentMediaItemStream to display the information of the currently playing media item.

When the first song in the queue is finished, the second song will be played. However, the information on the current media item does not change.

How do I detect that the song playing in the Queue has changed?

class AudioServiceScreen extends StatefulWidget {
  @override
  _AudioServiceScreenState createState() => _AudioServiceScreenState();
}

class _AudioServiceScreenState extends State<AudioServiceScreen> {
  @override
  void initState() {
    super.initState();
    Future(() async {
      await AudioService.connect();
      await start();
    });
  }

  @override
  void dispose() {
    Future(() async {
      await AudioService.disconnect();
    });
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ///,
      body: StreamBuilder<MediaItem?>(
        stream: AudioService.currentMediaItemStream,
        builder: (context, snapshot) {
          final mediaItem = snapshot.data;
        },
      ),
    );
  }

  Future<dynamic> start() async {
    final success = await AudioService.start(
      backgroundTaskEntrypoint: _backgroundTaskEntrypoint,
    );
    if (success) {
      await updateQueue();
    }
  }

  Future<void> updateQueue() async {
    final queue = await getMediaLibrary();  // get data from FireStore
    await AudioService.updateQueue(queue);
  }
}

void _backgroundTaskEntrypoint() {
  AudioServiceBackground.run(() => AudioPlayerTask());
}

class AudioPlayerTask extends BackgroundAudioTask {
  final AudioPlayer audioPlayer = AudioPlayer();

  @override
  Future<void> onStart(Map<String, dynamic>? params) async {
    final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration.speech());

    await AudioServiceBackground.setState(
      controls: [MediaControl.pause, MediaControl.stop],
      playing: false,
      processingState: AudioProcessingState.connecting,
    );
  }

  @override
  Future<void> onUpdateQueue(List<MediaItem> queue) async {
    await AudioServiceBackground.setQueue(queue);

    try {
      await audioPlayer.setAudioSource(ConcatenatingAudioSource(
        children:
            queue.map((item) => AudioSource.uri(Uri.parse(item.id))).toList(),
      ));
    } on Exception catch (e) {
      await onStop();
    }
  }
}

Solution

  • Try read the docs and follow some of the example there. Because on "Background Code" section, there is "on Start" code. Maybe that code can help you out. I am sorry I cannot help you that much. I never try that package.