Skip to content

Player immediately stops when using setUrl #178

@Tiamatmate

Description

@Tiamatmate

Describe the bug
After setUrl finishes player stops and I get this message: Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: com.ryanheise.just_audio.events.1581699118621454. Response ID: 0

Expected behavior
Expected the player to go from connecting to playing.

Runtime Environment (please complete the following information if relevant):

  • Device: Pixel 2
  • Android version: 10.0.0.

Flutter SDK version

v1.15.3-pre.37

Additional context

import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_radio/components/header-image.dart';
import 'package:flutter_radio/screens/player-screen/components/seekbar.dart';
import 'package:just_audio/just_audio.dart';

const ICON_HEIGHT = 25.0;

MediaControl playControl = MediaControl(
  androidIcon: 'mimap/ic_launcher',
  label: 'Play',
  action: MediaAction.play,
);
MediaControl pauseControl = MediaControl(
  androidIcon: 'mimap/ic_launcher',
  label: 'Pause',
  action: MediaAction.pause,
);
MediaControl stopControl = MediaControl(
  androidIcon: 'mimap/ic_launcher',
  label: 'Stop',
  action: MediaAction.stop,
);

class Player extends StatefulWidget {
  const Player({
    Key key,
  }) : super(key: key);
  _Player createState() => new _Player();
}

class _Player extends State<Player> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    connect();
  }

  @override
  void dispose() {
    disconnect();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        connect();
        break;
      case AppLifecycleState.paused:
        disconnect();
        break;
      default:
        break;
    }
  }

  void startPlayer() {
    AudioService.start(
      // When user clicks button to start playback
      backgroundTaskEntrypoint: audioPlayerTaskEntrypoint,
      androidNotificationChannelName: 'Music Player',
      notificationColor: 0xFF2196f3,
      androidNotificationIcon: "mipmap/ic_launcher",
    );
  }

  void playPausePlayer(basicState) {
    print(basicState.toString());
    if (basicState == BasicPlaybackState.playing) {
      AudioService.pause();
    } else if(basicState == BasicPlaybackState.paused) {
      AudioService.play();
    }
  }

  void connect() async {
    await AudioService.connect();
    startPlayer();
  }

  void disconnect() {
    AudioService.disconnect();
  }

  Widget build(BuildContext context) {
    //StreamBuilder with PlaybackState. If you need more items in StreamBuilder refer to: https://github.com/ryanheise/audio_service/blob/master/example/lib/main.dart
    return StreamBuilder<PlaybackState>(
        stream: AudioService.playbackStateStream,
        builder: (context, snapshot) {
          final state = snapshot.data;
          print(snapshot.data); //return null
          print('_____________');
          print(AudioServiceBackground.state.basicState); //returns BasicPlaybackState.none
          final basicState = state?.basicState ?? BasicPlaybackState.none;
          return Container(
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.03),
              borderRadius: BorderRadius.only(
                  bottomLeft: Radius.elliptical(700.0, 200.0),
                  bottomRight: Radius.elliptical(700.0, 200.0)),
            ),
            child: Column(
              children: <Widget>[
                HeaderImage(),
                new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(
                      "Tove Lo",
                      style: TextStyle(
                        color: Theme.of(context).hintColor,
                        fontSize: 14.0,
                      ),
                    ),
                    SizedBox(height: 5.0),
                    Text(
                      "Cool Girl",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17.0,
                      ),
                    )
                  ],
                ),
                SizedBox(height: 20.0),
                AudioSeekBar(),
                Padding(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 100.0, vertical: 20.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Image(
                        height: ICON_HEIGHT,
                        image: AssetImage('lib/assets/img/volume.png'),
                      ),
                      Stack(children: <Widget>[
                        Image(
                          height: 80.0,
                          image: AssetImage('lib/assets/img/wave.png'),
                        ),
                        Positioned.fill(
                            child: Align(
                          alignment: Alignment.center,
                          child: Image(
                            fit: BoxFit.fitHeight,
                            image: AssetImage('lib/assets/img/ellipse_1.png'),
                          ),
                        )),
                        Positioned.fill(
                            child: Align(
                          alignment: Alignment.center,
                          child: GestureDetector(
                            onTap: () => {playPausePlayer(basicState)},
                            child: Image(
                              height: ICON_HEIGHT,
                              image: AssetImage(
                                  basicState == BasicPlaybackState.playing
                                      ? 'lib/assets/img/pause.png'
                                      : 'lib/assets/img/play.png'),
                            ),
                          ),
                        )),
                      ]),
                      Image(
                        height: ICON_HEIGHT,
                        image: AssetImage('lib/assets/img/menu.png'),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        });
  }
}

void audioPlayerTaskEntrypoint() async {
  AudioServiceBackground.run(() => AudioPlayerTask());
}

class AudioPlayerTask extends BackgroundAudioTask {
  AudioPlayer _player = new AudioPlayer();
  bool _playing = true;

  BasicPlaybackState _stateToBasicState(AudioPlaybackState state) {
    switch (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 BasicPlaybackState.connecting;
      case AudioPlaybackState.completed:
        return BasicPlaybackState.stopped;
      default:
        throw Exception("Illegal state");
    }
  }

  @override
  Future<void> onStart() async {
    // Your custom dart code to start audio playback.
    // NOTE: The background audio task will shut down
    // as soon as this async function completes.
    await _player.setUrl("http://109.74.196.76:8021/stream");
    _player.play();

    _player.playbackEventStream.listen((event) {
      final state = _stateToBasicState(event.state);
      if (state != BasicPlaybackState.stopped) {
        print('State in listener');
        print(state);
        _setState(
          state: state,
        );
      }
    });
  }

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

  @override
  void onStop() {
    // Your custom dart code to stop audio playback.
  }

  @override
  void onPlay() {
    _playing = true;
    _player.play();
    print("A=");
  }

  @override
  void onPause() {
    _playing = false;
    _player.pause();
  }

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

  void _setState({@required BasicPlaybackState state, int position}) {
    if (position == null) {
      position = _player.playbackEvent.position.inMilliseconds;
    }
    AudioServiceBackground.setState(
      controls: getControls(state),
      basicState: state,
    );
  }

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions