在没有队列的情况下更改 AudioHandler.mediaItem
Changing AudioHandler.mediaItem without a Queue
我正在开发我的第一个实现基本流功能的 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 中的最终字段,我怀疑我在 changing/updating 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 ?? '');
},
),
我需要按如下方式覆盖 playMediaItem():
@override
Future<void> playMediaItem(MediaItem newItem) async {
mediaItem.add(newItem);
_player.setUrl(newItem.id);
}
将 AudioProcessingState 设置为空闲时,它会从队列中删除 MediaItem。只需将歌曲排队,然后设置 AudioProcessingState.idle 和 AudioProcessingState.ready 之后。
像这样:
playbackState.add(playbackState.value.copyWith(
processingState:AudioProcessingState.idle));
var _item2 = MediaItem(
id: '2',
album: "Out of Time",
title: "REM - Losing My Religion"
);
mediaItem.add(_item2)
playbackState.add(playbackState.value.copyWith(
processingState:AudioProcessingState.ready));
这可能不是最好的方法,但确实可以完成工作。
我正在开发我的第一个实现基本流功能的 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 中的最终字段,我怀疑我在 changing/updating 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 ?? '');
},
),
我需要按如下方式覆盖 playMediaItem():
@override
Future<void> playMediaItem(MediaItem newItem) async {
mediaItem.add(newItem);
_player.setUrl(newItem.id);
}
将 AudioProcessingState 设置为空闲时,它会从队列中删除 MediaItem。只需将歌曲排队,然后设置 AudioProcessingState.idle 和 AudioProcessingState.ready 之后。
像这样:
playbackState.add(playbackState.value.copyWith(
processingState:AudioProcessingState.idle));
var _item2 = MediaItem(
id: '2',
album: "Out of Time",
title: "REM - Losing My Religion"
);
mediaItem.add(_item2)
playbackState.add(playbackState.value.copyWith(
processingState:AudioProcessingState.ready));
这可能不是最好的方法,但确实可以完成工作。