0

我想从流中播放音频。我为此使用了Just Audio。我想要一个像Audio Video Progress bar这样的进度条也使用Audio Service在后台播放音频。

我已经为所有这些示例使用了这些示例,并且它们是单独工作的,但我无法将它们连接起来。你能举个例子来说明我该怎么做吗?

4

1 回答 1

2

audio_service 插件的示例包含如何使用audio_servicejust_audio。(结合2个包完成)

以下是SeekBaraudio_service 插件示例中给出的内容。

// A seek bar.
StreamBuilder<MediaState>(
    stream: _mediaStateStream,
    builder: (context, snapshot) {
        final mediaState = snapshot.data;
        return SeekBar(
            duration:
                mediaState?.mediaItem?.duration ?? Duration.zero,
            position: mediaState?.position ?? Duration.zero,
            onChangeEnd: (newPosition) {
                AudioService.seekTo(newPosition);
            },
        );
    },
),
...

class SeekBar extends StatefulWidget {
  final Duration duration;
  final Duration position;
  final ValueChanged<Duration>? onChanged;
  final ValueChanged<Duration>? onChangeEnd;

  SeekBar({
    required this.duration,
    required this.position,
    this.onChanged,
    this.onChangeEnd,
  });

  @override
  _SeekBarState createState() => _SeekBarState();
}

// more code in the plugin example

现在从上面的代码中,您可以看到该示例使用自定义设计SeekBar(使用滑块)。

您可以使用所需的插件小部件,而不是自定义滑块。ProgressBar在你的情况下。

StreamBuilder<MediaState>(
    stream: _mediaStateStream,
    builder: (context, snapshot) {
        final mediaState = snapshot.data;
        return ProgressBar(
            total:
                mediaState?.mediaItem?.duration ?? Duration.zero,
            progress: mediaState?.position ?? Duration.zero,
            onSeek: (newPosition) {
                AudioService.seekTo(newPosition);
            },
        );
    },
),

这是对上述内容的SeekBar更改ProgressBar。(结合第三个包完成)

注意:对于buffered. 您可以bufferedPosition从 audio_service 获取PlaybackStateStream

编辑:以下是我如何使用它来添加bufferedPosition.

(我改了MediaState类,对应的状态getter有点实现)

StreamBuilder<MediaState>(
    stream: _mediaStateStream,
    builder: (context, snapshot) {
        final mediaState = snapshot.data;
        return ProgressBar(
            total:
                mediaState?.mediaItem?.duration ?? Duration.zero,
            progress: mediaState?.position ?? Duration.zero,
            buffered: mediaState?.playbackState?
                .bufferedPosition ?? Duration.zero,
            onSeek: (newPosition) {
                AudioService.seekTo(newPosition);
            },
        );
    },
),
...
Stream<MediaState> get _mediaStateStream =>
  Rx.combineLatest3<MediaItem, Duration, PlaybackState, MediaState>(
      AudioService.currentMediaItemStream,
      AudioService.positionStream,
      AudioService.playbackStateStream,
      (mediaItem, position, playbackState) =>
          MediaState(mediaItem, position, playbackState));
...
class MediaState {
  final MediaItem mediaItem;
  final Duration position;
  final PlaybackState playbackState;

  MediaState(this.mediaItem, this.position, this.playbackState);
}
于 2021-06-22T12:04:30.540 回答