-
-
Notifications
You must be signed in to change notification settings - Fork 504
Closed
Labels
Description
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,
];
}
}
}