0

我正在开发我的第一个 Flutter 应用程序,它实现了基本的流功能。启动时,应用程序从源 A 加载流。应用程序包含导航菜单,允许用户播放来自其他源 B、C、D 等的流。我已经能够通过重载 AudioHandler 来更新播放的项目.playMediaItem(MediaItem mediaItem) 调用 AudioPlayer.setUrl(mediaItem.id):

class AudioPlayerHandler extends BaseAudioHandler {
  // Declare MediaItem used for streaming
  static const _initial_stream = MediaItem(
    id: someURL,
    title: 'Stream Title',
  );

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

  //Initialize audio handler
  AudioPlayerHandler() {
    _player.playbackEventStream.map(_transformEvent).pipe(playbackState);
    mediaItem.add(_initial_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();

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

在 UI 中,可以通过在 onPressed() 方法中实现以下内容来播放新流:

var stream_b = MediaItem(
  id: someURL,
  title: 'Stream B',
);

audioHandler.playMediaItem(stream_b);
audioHandler.play();

我希望我的 UI 元素能够反映这种变化,但目前 StreamBuilder 仍然显示初始流,即使用户选择了不同的流。我试过实现 AudioHandler.updateMediaItem() 和 AudioServiceBackground.setMediaItem(mediaItem):

  @override
  Future<void> playMediaItem(MediaItem mediaItem) async {
    _player.setUrl(mediaItem.id);
    updateMediaItem(mediaItem);
    AudioServiceBackground.setMediaItem(mediaItem);
  }

但两者都不起作用。AudioServiceBackground.setMediaItem() 已弃用,并显示使用 BaseAudioHandler.mediaItem 的建议。尝试在我的 UI 中设置 audioHandler.mediaItem = stream_b 时,我看到一个错误,即 AudioHandler 不包含设置 mediaItem 的方法,当我尝试在 AudioHandler 中实现我自己的方法时,我看到一个错误,因为 mediaItem 是最终的BaseAudioClass 中的字段,不能使用 setter 更改。

考虑到 mediaItem 是 BaseAudioHandler 中的最后一个字段,我怀疑我更改/更新 mediaItem 的方法不正确。任何人都可以建议一种方法来设置 AudioHandler.mediaItem 以便它可以在流构建器中用于显示当前正在播放的项目?

StreamBuilder<MediaItem?>(
 stream: audioHandler.mediaItem, // how to update mediaItem so this provides real-time information? 
 builder: (context, snapshot) {
   var mediaItem = snapshot.data;
   return Text(mediaItem?.title ?? '');
 },
),
4

1 回答 1

0

我需要覆盖 playMediaItem() 如下:

  @override
  Future<void> playMediaItem(MediaItem newItem) async {
    mediaItem.add(newItem);
    _player.setUrl(newItem.id);
  }
于 2021-12-30T23:35:06.093 回答