0

I'm working on making a music playing app in Flutter and the current code I've got only works properly after hot restarting. In particular, after pressing play or as soon as I release the slider, the currentTime of the song gets reset back to zero. However, as soon as I hot restart the app, everything works perfectly as intended.

As I eventually hope to use this app on an iOS device, which does not have hot restart, this is a major issue.

I'm using audioplayers 0.20.1 as right now 4.1.0 isn't recognizing my mp3 files (another issue)

If the code below doesn't run it's because I removed some of the styling widgets to make it more readable but hopefully you can see all the relevant parts.

import 'package:pick_pro/main.dart';
import 'package:audioplayers/audioplayers.dart';


class Playback extends StatefulWidget {
  @override
  PlaybackState createState() => PlaybackState();
}

class PlaybackState extends State<Playback> {
  final player = AudioPlayer();

  late Duration songLength;
  late Duration currentTime;
  double playbackSpeed = 1;
  String assetPath = 'assets/sounds/demo_song.mp3';
  bool isPlaying = false;
  int bpm = 100;

  @override
  void initState() {
    super.initState();

    player.setReleaseMode(ReleaseMode.STOP);

    player.setUrl(assetPath, isLocal: true);
    currentTime = Duration.zero;
    songLength = const Duration(seconds: 259);

    // Listeners for changes in player states
    player.onPlayerStateChanged.listen((state) {
      setState(() {
        isPlaying = state == PlayerState.PLAYING;
      });
    });

    player.onDurationChanged.listen((newSongLength) {
      setState(() {
        songLength = newSongLength;
      });
    });

    player.onAudioPositionChanged.listen((newCurrentTime) {
      setState(() {
        currentTime = newCurrentTime;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: darkBlue,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Slider(
                min: 0,
                max: songLength.inSeconds.toDouble(),
                value: currentTime.inSeconds.toDouble(),
                onChanged: (value) {
                  final position = Duration(seconds: value.toInt());
                  player.pause();
                  player.seek(position);
                  setState(() {});
                }),
            const SizedBox(height: 20),
            IconButton(
              icon: Icon(isPlaying ? Icons.pause : Icons.play_arrow,
                  color: Colors.white),
              iconSize: 50,
              onPressed: () {
                if (isPlaying) {
                  player.pause();
                } else {
                  player.seek(currentTime);
                  player.resume();
                }
              },
            ),
            const SizedBox(height: 20),
            Slider(
                min: 0.5,
                max: 1.5,
                value: playbackSpeed,
                onChanged: (value) {
                  playbackSpeed = double.parse(value.toStringAsFixed(2));
                  player.pause();
                  player.setPlaybackRate(playbackSpeed);
                  setState(() {});
                }),
            Center(
              child: Text(
                'Speed: ${playbackSpeed}x',
                style: buttonText(),
              ),
            ),
            const SizedBox(
              height: 30,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    SizedBox(
                      width: 60.0,
                      height: 30.0,
                      child: TextField(
                        onSubmitted: (String value) {
                          _controller.clear();
                          try {
                            bpm = int.parse(value);
                            setState(() {});
                          } catch (e) {
                            ErrorPopup.show(
                                context, "The BPM you entered is invalid.");
                          }
                        },
                      ),
                    ),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    SizedBox(
                      width: 60.0,
                      height: 30.0,
                      child: TextField(
                        onSubmitted: (String value) {
                          _controller.clear();
                          try {
                            int newBPM = int.parse(value);
                            playbackSpeed =
                                double.parse((newBPM / bpm).toStringAsFixed(2));
                            player.pause();
                            player.setPlaybackRate(playbackSpeed);
                            setState(() {});
                          } catch (e) {
                            ErrorPopup.show(
                                context, "The BPM you entered is invalid.");
                          }
                        },
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ],
        ),
      ),
      drawer: MyDrawer(index: 3),
    );
  }
}

I don't know what to try with this, as it works perfectly after hot restarting. I just don't know how hot restart works so I don't know why the code works after a hot restart but not before.

babbid
  • 1

0 Answers0