gpt4 book ai didi

带有音频播放器的 Flutter Bloc

转载 作者:行者123 更新时间:2023-12-03 02:43:00 25 4
gpt4 key购买 nike

几乎花了一天的时间来弄清楚如何去做,我需要你的帮助。
我创建了一个应用程序,该应用程序的状态为 audioplayers 实例并使用 flutter_bloc
问题:

  • 状态播放器播放但小部件 MusicPlayer 没有使用 BlocBuilder
  • 重建小部件
  • 我还试图获取我正在播放的音乐的 currentPositionduration 并使用 LinearPercentIndicator 包中的 linear_percent_indicator 显示它,但似乎无法找到解决方案,因为重建不起作用。
  • 我错过了什么?

  • 这是我到目前为止所拥有的:
    集团
    class AudioPlayerBloc extends Bloc<AudioPlayerEvents, MusicPlayerState> {
    @override
    MusicPlayerState get initialState => MusicPlayerState(
    player: AudioPlayer(),
    episode: Episode(),
    );

    @override
    Stream<MusicPlayerState> mapEventToState(AudioPlayerEvents event) async* {
    if (event is InitializePlayer) {
    this.currentState.episode = event.episode;
    this.dispatch(PlayPlayer());
    yield this.currentState;
    }

    if (event is PlayPlayer) {
    this.play(this.currentState.episode.source);
    }

    if (event is PlayRemote) {
    this.currentState.player.stop();

    this.currentState.player.play(event.remoteURL);
    yield this.currentState;
    }

    if (event is ShowPlayer) {
    yield this.currentState;
    }

    if (event is HidePlayer) {
    yield this.currentState;
    }
    }

    void play(String remoteURL) {
    this.dispatch(PlayRemote(remoteURL));
    }

    void stop() async {
    await this.currentState.player.stop();
    }

    void pause() async{
    await this.currentState.player.pause();
    }

    void resume(){
    this.currentState.player.resume();
    }

    @override
    void dispose() {
    super.dispose();
    }
    }
    事件
    abstract class AudioPlayerEvents {}

    class InitializePlayer extends AudioPlayerEvents {
    Episode episode;

    InitializePlayer(this.episode);
    }

    class PlayRemote extends AudioPlayerEvents {
    final String remoteURL;

    PlayRemote(this.remoteURL);
    }

    class PlayPlayer extends AudioPlayerEvents {}

    class ShowPlayer extends AudioPlayerEvents {}

    class HidePlayer extends AudioPlayerEvents {}
    状态
    import 'package:audioplayers/audioplayers.dart';

    class MusicPlayerState {
    AudioPlayer player;
    Episode episode; // My Custom Class

    MusicPlayerState({
    this.player,
    this.episode,
    });
    }

    main.dart
    @override
    Widget build(BuildContext context) {
    return MultiBlocProvider(
    providers: [
    BlocProvider<AudioPlayerBloc>(
    builder: (_) => AudioPlayerBloc(),
    )
    ],
    child: MaterialApp(
    navigatorObservers: [],
    initialRoute: HomeScreen.id,
    routes: {
    HomeScreen.id: (context) => HomeScreen(app: widget.app),
    },
    ),
    );
    }
    }
    MusicPlayer.dart <-- 我的播放器小部件
    class MusicPlayer extends StatelessWidget {

    @override
    Widget build(BuildContext context) {
    final AudioPlayerBloc audioPlayerBloc =
    BlocProvider.of<AudioPlayerBloc>(context);

    return BlocBuilder<AudioPlayerBloc, MusicPlayerState>(
    bloc: audioPlayerBloc,
    builder: (context, state) {
    return Container(
    height: 200.0,
    color: Colors.cyan[200],
    child: Padding(
    padding: const EdgeInsets.only(top: 20.0),
    child: Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
    Column(
    children: <Widget>[
    Text("${state.episode.name}"),
    Row(
    children: <Widget>[
    Expanded(
    flex: 1,
    child: FutureBuilder<int>(
    future: audioPlayerBloc.currentState.player.getCurrentPosition(),
    builder: (context, AsyncSnapshot<int> snapshot) {
    double seconds = snapshot.data / 1000;
    if (snapshot.hasData) {
    return Text("${printDuration(Duration(seconds: seconds.toInt()), abbreviated: true)}");
    } else {
    return Text('Calculating..');
    }
    },
    ),
    ),
    Expanded(
    flex: 3,
    child: LinearPercentIndicator(
    lineHeight: 7.0,
    // percent: this.currentPosition / this.fileDuration,
    percent: 0.3,
    backgroundColor: Colors.grey,
    progressColor: Colors.blue,
    ),
    ),
    Expanded(
    flex: 1,
    child: FutureBuilder<int>(
    future: audioPlayerBloc.currentState.player.getDuration(),
    builder: (context, AsyncSnapshot<int> snapshot) {
    double seconds = snapshot.data / 1000;
    if (snapshot.hasData) {
    return Text("${printDuration(Duration(seconds: seconds.toInt()), abbreviated: true)}");
    } else {
    return Text('Calculating..');
    }
    },
    ),
    ),
    ],
    ),
    Text(state.player.state.toString()),
    FlatButton(
    onPressed: () {
    print('close here');
    Navigator.of(context).pop();
    },
    child: Icon(
    Icons.close,
    color: Colors.black.withOpacity(0.5),
    ),
    ),
    Row(
    children: <Widget>[
    FlatButton(
    onPressed: () {
    audioPlayerBloc.pause();
    },
    child: Text('Pause Player'),
    ),
    FlatButton(
    onPressed: () {
    audioPlayerBloc.resume();
    },
    child: Text('Resume Player'),
    ),
    FlatButton(
    onPressed: () {
    audioPlayerBloc.stop();
    },
    child: Text('Stop Player'),
    ),
    ],
    )
    ],
    )
    ],
    ),
    ),
    );
    },
    );
    }
    }
    HomeScreen.dart <-- 我的第一个屏幕
    @override
    Widget build(BuildContext context) {

    final AudioPlayerBloc audioPlayerBloc = BlocProvider.of<AudioPlayerBloc>(context);

    return MultiBlocProvider(
    providers: [
    BlocProvider<AudioPlayerBloc>(
    builder: (_) => AudioPlayerBloc(),
    )
    ],
    child: Scaffold(
    appBar: AppBar(
    title: Text('Global Audio Player'),
    ),
    body: Container(
    child: BlocBuilder<AudioPlayerBloc, MusicPlayerState>(
    builder: (context, state) {
    return Column(
    children: <Widget>[
    Flexible(
    child: getListView(context)
    ),
    displayPlayer(state.player), // Here I'm trying to display the player when the AudioPlayerState is PLAYING
    ],
    );
    },
    ),
    ),
    ),
    );

    }
    全局函数
     Widget displayPlayer(AudioPlayer player){
    return MusicPlayer();
    if(player.state == AudioPlayerState.PLAYING) {
    return MusicPlayer();
    }
    return Container();
    }
    EpisodesScreen.dart <-- 剧集的 ListView
    class _EpisodesScreenState extends State<EpisodesScreen> {
    @override
    void initState() {
    super.initState();

    print(widget.series);
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: Text(widget.series.name)),
    body: Column(
    mainAxisAlignment: MainAxisAlignment.start,
    children: <Widget>[
    Expanded(
    flex: 0,
    child: Image.network(widget.series.image.original),
    ),
    Expanded(
    child: getListView(context),
    ),
    Expanded(
    child: BlocBuilder<AudioPlayerBloc, MusicPlayerState>(
    builder: (context, state) {
    return displayPlayer(state.player);
    },
    ),
    )
    ],
    ));
    }


    Widget getListView(BuildContext context) {
    List<Episode> episodesList = widget.series.episodes;

    final AudioPlayerBloc audioPlayerBloc =
    BlocProvider.of<AudioPlayerBloc>(context);

    var listView = ListView.separated(
    itemCount: episodesList.length,
    itemBuilder: (context, index) {
    return ListTile(
    title: Text(episodesList[index].name),
    trailing: BlocBuilder<AudioPlayerBloc, MusicPlayerState>(
    builder: (context, state) {
    return FlatButton(
    onPressed: () {
    audioPlayerBloc.dispatch(InitializePlayer(episodesList[index]));
    },
    child: Icon(
    Icons.play_arrow,
    color: Colors.black87,
    ),
    );
    },
    ),
    );
    },
    separatorBuilder: (BuildContext context, int index) {
    return Divider(
    height: 1.0,
    color: Colors.black12,
    );
    },
    );

    return listView;
    }
    }

    最佳答案

    我错过了它的 yield * 部分,现在它正在工作。

    Stream<Duration> currentPosition() async* {
    yield* this.currentState.audioPlayer.onAudioPositionChanged;
    }

    Stream<Duration> fileDuration() async* {
    yield* this.currentState.audioPlayer.onDurationChanged;
    }

    关于带有音频播放器的 Flutter Bloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57675959/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com