无法向Android的audio_service 0.8.0 flutter添加自定义队列

问题描述 投票:0回答:1

我想查看一个如何向音频服务添加自定义队列的示例。我正在返回一个带有音乐列表的JSON。但是我无法将其添加到音频服务后台并运行它。请帮忙。这是我的球员班级的一个例子。songModel具有所有歌曲数据下面的代码是我的实现。

`import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'Songs.dart';
import 'backgroundTask.dart';

class Player extends StatefulWidget {
  SongModel songModel;
      Player({@required this.songModel});
  @override
  _Player createState() => _Player();
}

class _Player extends State<Player> {
  static SongModel data;
   List<MediaItem> songs;
  @override
  Future<void> initState()  {
    super.initState();
    data = widget.songModel;
    songs = data.songs;
    print(songs);
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: StreamBuilder<ScreenState>(
        stream: _screenStateStream,
        builder: (context, snapshot) {
          final screenState = snapshot.data;
          final queue = screenState?.queue;
          final mediaItem = screenState?.mediaItem;
          final state = screenState?.playbackState;
          final basicState = state?.basicState ?? BasicPlaybackState.none;
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(data.currentSong.title),
              Text(data.songs.length.toString()),
              Column(mainAxisAlignment: MainAxisAlignment.center, children: [
                if (queue != null && queue.isNotEmpty)
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      IconButton(
                        icon: Icon(Icons.skip_previous),
                        iconSize: 64.0,
                        onPressed: mediaItem == queue.first
                            ? null
                            : AudioService.skipToPrevious,
                      ),
                      IconButton(
                        icon: Icon(Icons.skip_next),
                        iconSize: 64.0,
                        onPressed: mediaItem == queue.last
                            ? null
                            : AudioService.skipToNext,
                      ),
                      if (mediaItem?.title != null) Text(mediaItem.title),
                    ],
                  ),
              ]),
              if (mediaItem?.title != null) Text(mediaItem.title),
              if (basicState == BasicPlaybackState.playing)
                RaisedButton(child: Text("Pause"), onPressed: pause)
              else if (basicState == BasicPlaybackState.buffering ||
                  basicState == BasicPlaybackState.skippingToNext ||
                  basicState == BasicPlaybackState.skippingToPrevious)
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: SizedBox(
                    width: 64.0,
                    height: 64.0,
                    child: CircularProgressIndicator(),
                  ),
                )
              else if (state != BasicPlaybackState.stopped)
                RaisedButton(child: Text("Stop"), onPressed: stop),
              RaisedButton(child: Text("Play"), onPressed: play),
              RaisedButton(child: Text("StartService"),onPressed:()=> start(data.songs))
            ],
          );
        },
      )),
    );
  }


}


 _backgroundTaskEntrypoint(){

  AudioServiceBackground.run(() => AudioPlayerTask());
}

start(data) {
  AudioService.start(
    backgroundTaskEntrypoint:_backgroundTaskEntrypoint,
    androidNotificationChannelName: 'com.zimosound_app.us',
    notificationColor: 0xFF2196f3,
    androidNotificationIcon: 'mipmap/ic_launcher',
    enableQueue: true,
  );
  AudioServiceBackground.setQueue(data);
  print(AudioService.queue);
}







stop() => AudioService.stop();

play() async {
  if (await AudioService.running) {
    AudioService.play();
  }
}

pause() => AudioService.pause();

Stream<ScreenState> get _screenStateStream =>
    Rx.combineLatest3<List<MediaItem>, MediaItem, PlaybackState, ScreenState>(
        AudioService.queueStream,
        AudioService.currentMediaItemStream,
        AudioService.playbackStateStream,
        (queue, mediaItem, playbackState) =>
            ScreenState(queue, mediaItem, playbackState));

class ScreenState {
  final List<MediaItem> queue;
  final MediaItem mediaItem;
  final PlaybackState playbackState;

  ScreenState(this.queue, this.mediaItem, this.playbackState);
}
`

这是我的背景音频课程

    import 'dart:async';

import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';

MediaControl playControl = MediaControl(
  androidIcon: 'drawable/ic_action_play_arrow',
  label: 'Play',
  action: MediaAction.play,
);
MediaControl pauseControl = MediaControl(
  androidIcon: 'drawable/ic_action_pause',
  label: 'Pause',
  action: MediaAction.pause,
);
MediaControl skipToNextControl = MediaControl(
  androidIcon: 'drawable/ic_action_skip_next',
  label: 'Next',
  action: MediaAction.skipToNext,
);
MediaControl skipToPreviousControl = MediaControl(
  androidIcon: 'drawable/ic_action_skip_previous',
  label: 'Previous',
  action: MediaAction.skipToPrevious,
);
MediaControl stopControl = MediaControl(
  androidIcon: 'drawable/ic_action_stop',
  label: 'Stop',
  action: MediaAction.stop,
);


final prevControl = MediaControl(
  androidIcon: 'drawable/ic_action_stop',
  label: 'Stop',
  action: MediaAction.stop,
);

class AudioPlayerTask extends BackgroundAudioTask {
  var _queue = AudioService.queue;
  int _queueIndex;
  AudioPlayer _audioPlayer = new AudioPlayer();
  Completer _completer = Completer();
  BasicPlaybackState _skipState;
  bool _playing;

//  AudioPlayerTask(List<MediaItem> queue, int queueIndex){
//    this._queue = queue;
//    this._queueIndex = queueIndex;
//  }

  bool get hasNext => _queueIndex + 1 < _queue.length;

  bool get hasPrevious => _queueIndex > 0;

  MediaItem get mediaItem => _queue[_queueIndex];

  BasicPlaybackState _eventToBasicState(AudioPlaybackEvent event) {
    if (event.buffering) {
      return BasicPlaybackState.buffering;
    } else {
      switch (event.state) {
        case AudioPlaybackState.none:
          return BasicPlaybackState.none;
        case AudioPlaybackState.stopped:
          return BasicPlaybackState.stopped;
        case AudioPlaybackState.paused:
          return BasicPlaybackState.paused;
        case AudioPlaybackState.playing:
          return BasicPlaybackState.playing;
        case AudioPlaybackState.connecting:
          return _skipState ?? BasicPlaybackState.connecting;
        case AudioPlaybackState.completed:
          return BasicPlaybackState.stopped;
        default:
          throw Exception("Illegal state");
      }
    }
  }

  @override
  Future<void> onStart() async {
    var playerStateSubscription = _audioPlayer.playbackStateStream
        .where((state) => state == AudioPlaybackState.completed)
        .listen((state) {
      _handlePlaybackCompleted();
    });
    var eventSubscription = _audioPlayer.playbackEventStream.listen((event) {
      final state = _eventToBasicState(event);
      if (state != BasicPlaybackState.stopped) {
        _setState(
          state: state,
          position: event.position.inMilliseconds,
        );
      }
    });
   // AudioServiceBackground.setQueue(_queue);
    await onSkipToNext();
    await _completer.future;
    playerStateSubscription.cancel();
    eventSubscription.cancel();
  }

  void _handlePlaybackCompleted() {
    if (hasNext) {
      onSkipToNext();
    } else {
      onStop();
    }
  }

  void playPause() {
    if (AudioServiceBackground.state.basicState == BasicPlaybackState.playing)
      onPause();
    else
      onPlay();
  }

  @override
  Future<void> onSkipToNext() => _skip(1);

  @override
  Future<void> onSkipToPrevious() => _skip(-1);

  Future<void> _skip(int offset) async {
    final newPos = _queueIndex + offset;
    if (!(newPos >= 0 && newPos < _queue.length)) return;
    if (_playing == null) {
      // First time, we want to start playing
      _playing = true;
    } else if (_playing) {
      // Stop current item
      await _audioPlayer.stop();
    }
    // Load next item
    _queueIndex = newPos;
    AudioServiceBackground.setMediaItem(mediaItem);
    _skipState = offset > 0
        ? BasicPlaybackState.skippingToNext
        : BasicPlaybackState.skippingToPrevious;
    await _audioPlayer.setUrl(mediaItem.id);
    _skipState = null;
    // Resume playback if we were playing
    if (_playing) {
      onPlay();
    } else {
      _setState(state: BasicPlaybackState.paused);
    }
  }

  @override
  void onPlay() {
    if (_skipState == null) {
      _playing = true;
      _audioPlayer.play();
      AudioServiceBackground.sendCustomEvent('just played');
    }
  }

  @override
  void onPause() {
    if (_skipState == null) {
      _playing = false;
      _audioPlayer.pause();
      AudioServiceBackground.sendCustomEvent('just paused');
    }
  }

  @override
  void onSeekTo(int position) {
    _audioPlayer.seek(Duration(milliseconds: position));
  }

  @override
  void onClick(MediaButton button) {
    playPause();
  }

  @override
  Future<void> onStop() async {
    await _audioPlayer.stop();
    await _audioPlayer.dispose();
    _setState(state: BasicPlaybackState.stopped);
    _completer.complete();
  }

  void _setState({@required BasicPlaybackState state, int position}) {
    if (position == null) {
      position = _audioPlayer.playbackEvent.position.inMilliseconds;
    }
    AudioServiceBackground.setState(
      controls: getControls(state),
      systemActions: [MediaAction.seekTo],
      basicState: state,
      position: position,
    );
  }

  List<MediaControl> getControls(BasicPlaybackState state) {
    if (_playing) {
      return [
        skipToPreviousControl,
        pauseControl,
        skipToNextControl,
        stopControl,
      ];
    } else {
      return [

        skipToPreviousControl,
        playControl,
        skipToNextControl,
        stopControl,
      ];
    }
  }

  @override
  void onAudioBecomingNoisy() {
    playPause();
  }

  @override
  void onAudioFocusGained() {
    playPause();
  }


  @override
  void onAudioFocusLost() {
    playPause();
  }

  @override
  void onAudioFocusLostTransient() {
    playPause();
  }

  @override
  void onAudioFocusLostTransientCanDuck() {
    playPause();
  }

}
flutter audio service
1个回答
0
投票

您解决了这个问题吗?我也面临着同样的问题。

我可以从其他页面以这种方式调用audioplayerTask:

  void _audioPlayerTaskEntrypoint() async {

AudioServiceBackground.run(()=> AudioPlayerTask(queue,queue.length));}

使用此代码生成队列,

  for (var mp3 in data['data']){

      MediaItem songs = MediaItem(id:"\"${mp3.xsources_mp3}\"",
                  album: "\"${mp3.xtitle}\"",
                  title: "\"${mp3.xtitle}\"",
                  artist: "\"${mp3.xauthor}\"",
                  duration: int.parse(mp3.id)*4000,
                  artUri: "\"${mp3.ximage}\"");
     queue.add(songs);
} 

参数中的引号是我的想法,以使值与Audio_Servive的示例保持相似的格式,我也尝试了不使用引号的方式,但它不起作用。audio_service已启动,但无法识别音频。如果您已解决此问题,请告诉我。先感谢您。

© www.soinside.com 2019 - 2024. All rights reserved.