Broadcast how much has been buffered
This commit is contained in:
parent
338401b23f
commit
eebb343280
|
@ -40,7 +40,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
private volatile PlaybackState state;
|
private volatile PlaybackState state;
|
||||||
private long updateTime;
|
private long updateTime;
|
||||||
private long updatePosition;
|
private long updatePosition;
|
||||||
|
private long bufferedPosition;
|
||||||
private long duration;
|
private long duration;
|
||||||
private Long start;
|
private Long start;
|
||||||
private Long end;
|
private Long end;
|
||||||
|
@ -51,9 +51,31 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
private Result seekResult;
|
private Result seekResult;
|
||||||
private boolean seekProcessed;
|
private boolean seekProcessed;
|
||||||
private boolean buffering;
|
private boolean buffering;
|
||||||
|
private boolean justConnected;
|
||||||
private MediaSource mediaSource;
|
private MediaSource mediaSource;
|
||||||
|
|
||||||
private SimpleExoPlayer player;
|
private final SimpleExoPlayer player;
|
||||||
|
private final Handler handler = new Handler();
|
||||||
|
private final Runnable bufferWatcher = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long newBufferedPosition = Math.min(duration, player.getBufferedPosition());
|
||||||
|
if (newBufferedPosition != bufferedPosition) {
|
||||||
|
bufferedPosition = newBufferedPosition;
|
||||||
|
broadcastPlaybackEvent();
|
||||||
|
}
|
||||||
|
if (duration > 0 && newBufferedPosition >= duration) return;
|
||||||
|
if (buffering) {
|
||||||
|
handler.postDelayed(this, 200);
|
||||||
|
} else if (state == PlaybackState.playing) {
|
||||||
|
handler.postDelayed(this, 500);
|
||||||
|
} else if (state == PlaybackState.paused) {
|
||||||
|
handler.postDelayed(this, 1000);
|
||||||
|
} else if (justConnected) {
|
||||||
|
handler.postDelayed(this, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public AudioPlayer(final Registrar registrar, final String id) {
|
public AudioPlayer(final Registrar registrar, final String id) {
|
||||||
this.registrar = registrar;
|
this.registrar = registrar;
|
||||||
|
@ -79,12 +101,18 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
player.addListener(this);
|
player.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startWatchingBuffer() {
|
||||||
|
handler.removeCallbacks(bufferWatcher);
|
||||||
|
handler.post(bufferWatcher);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||||
switch (playbackState) {
|
switch (playbackState) {
|
||||||
case Player.STATE_READY:
|
case Player.STATE_READY:
|
||||||
if (prepareResult != null) {
|
if (prepareResult != null) {
|
||||||
duration = player.getDuration();
|
duration = player.getDuration();
|
||||||
|
justConnected = true;
|
||||||
prepareResult.success(duration);
|
prepareResult.success(duration);
|
||||||
prepareResult = null;
|
prepareResult = null;
|
||||||
transition(PlaybackState.stopped);
|
transition(PlaybackState.stopped);
|
||||||
|
@ -105,6 +133,9 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
if (notifyBuffering && (buffering != this.buffering)) {
|
if (notifyBuffering && (buffering != this.buffering)) {
|
||||||
this.buffering = buffering;
|
this.buffering = buffering;
|
||||||
broadcastPlaybackEvent();
|
broadcastPlaybackEvent();
|
||||||
|
if (buffering) {
|
||||||
|
startWatchingBuffer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +225,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
event.add(buffering);
|
event.add(buffering);
|
||||||
event.add(updatePosition = getCurrentPosition());
|
event.add(updatePosition = getCurrentPosition());
|
||||||
event.add(updateTime = System.currentTimeMillis());
|
event.add(updateTime = System.currentTimeMillis());
|
||||||
|
event.add(Math.max(updatePosition, bufferedPosition));
|
||||||
eventSink.success(event);
|
eventSink.success(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +246,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUrl(final String url, final Result result) throws IOException {
|
public void setUrl(final String url, final Result result) throws IOException {
|
||||||
|
justConnected = false;
|
||||||
abortExistingConnection();
|
abortExistingConnection();
|
||||||
prepareResult = result;
|
prepareResult = result;
|
||||||
transition(PlaybackState.connecting);
|
transition(PlaybackState.connecting);
|
||||||
|
@ -253,7 +286,9 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
case stopped:
|
case stopped:
|
||||||
case completed:
|
case completed:
|
||||||
case paused:
|
case paused:
|
||||||
|
justConnected = false;
|
||||||
transition(PlaybackState.playing);
|
transition(PlaybackState.playing);
|
||||||
|
startWatchingBuffer();
|
||||||
player.setPlayWhenReady(true);
|
player.setPlayWhenReady(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -124,14 +124,12 @@
|
||||||
_updatePosition = [self getCurrentPosition];
|
_updatePosition = [self getCurrentPosition];
|
||||||
_updateTime = now;
|
_updateTime = now;
|
||||||
_eventSink(@[
|
_eventSink(@[
|
||||||
// state
|
|
||||||
@(_state),
|
@(_state),
|
||||||
// buffering
|
|
||||||
@(_buffering),
|
@(_buffering),
|
||||||
// updatePosition
|
|
||||||
@(_updatePosition),
|
@(_updatePosition),
|
||||||
// updateTime
|
|
||||||
@(_updateTime),
|
@(_updateTime),
|
||||||
|
// TODO: buffer position
|
||||||
|
@(_updatePosition),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ class AudioPlayer {
|
||||||
buffering: false,
|
buffering: false,
|
||||||
updatePosition: Duration.zero,
|
updatePosition: Duration.zero,
|
||||||
updateTime: Duration.zero,
|
updateTime: Duration.zero,
|
||||||
|
bufferedPosition: Duration.zero,
|
||||||
speed: 1.0,
|
speed: 1.0,
|
||||||
duration: Duration.zero,
|
duration: Duration.zero,
|
||||||
);
|
);
|
||||||
|
@ -80,6 +81,8 @@ class AudioPlayer {
|
||||||
|
|
||||||
final _bufferingSubject = BehaviorSubject<bool>();
|
final _bufferingSubject = BehaviorSubject<bool>();
|
||||||
|
|
||||||
|
final _bufferedPositionSubject = BehaviorSubject<Duration>();
|
||||||
|
|
||||||
final _fullPlaybackStateSubject = BehaviorSubject<FullAudioPlaybackState>();
|
final _fullPlaybackStateSubject = BehaviorSubject<FullAudioPlaybackState>();
|
||||||
|
|
||||||
double _volume = 1.0;
|
double _volume = 1.0;
|
||||||
|
@ -102,6 +105,7 @@ class AudioPlayer {
|
||||||
buffering: data[1],
|
buffering: data[1],
|
||||||
updatePosition: Duration(milliseconds: data[2]),
|
updatePosition: Duration(milliseconds: data[2]),
|
||||||
updateTime: Duration(milliseconds: data[3]),
|
updateTime: Duration(milliseconds: data[3]),
|
||||||
|
bufferedPosition: Duration(milliseconds: data[4]),
|
||||||
speed: _speed,
|
speed: _speed,
|
||||||
duration: _duration,
|
duration: _duration,
|
||||||
));
|
));
|
||||||
|
@ -111,6 +115,8 @@ class AudioPlayer {
|
||||||
.addStream(playbackEventStream.map((state) => state.state).distinct());
|
.addStream(playbackEventStream.map((state) => state.state).distinct());
|
||||||
_bufferingSubject.addStream(
|
_bufferingSubject.addStream(
|
||||||
playbackEventStream.map((state) => state.buffering).distinct());
|
playbackEventStream.map((state) => state.buffering).distinct());
|
||||||
|
_bufferedPositionSubject.addStream(
|
||||||
|
playbackEventStream.map((state) => state.bufferedPosition).distinct());
|
||||||
_fullPlaybackStateSubject.addStream(
|
_fullPlaybackStateSubject.addStream(
|
||||||
Rx.combineLatest2<AudioPlaybackState, bool, FullAudioPlaybackState>(
|
Rx.combineLatest2<AudioPlaybackState, bool, FullAudioPlaybackState>(
|
||||||
playbackStateStream,
|
playbackStateStream,
|
||||||
|
@ -145,6 +151,10 @@ class AudioPlayer {
|
||||||
/// A stream of buffering state changes.
|
/// A stream of buffering state changes.
|
||||||
Stream<bool> get bufferingStream => _bufferingSubject.stream;
|
Stream<bool> get bufferingStream => _bufferingSubject.stream;
|
||||||
|
|
||||||
|
/// A stream of buffered positions.
|
||||||
|
Stream<Duration> get bufferedPositionStream =>
|
||||||
|
_bufferedPositionSubject.stream;
|
||||||
|
|
||||||
/// A stream of [FullAudioPlaybackState]s.
|
/// A stream of [FullAudioPlaybackState]s.
|
||||||
Stream<FullAudioPlaybackState> get fullPlaybackStateStream =>
|
Stream<FullAudioPlaybackState> get fullPlaybackStateStream =>
|
||||||
_fullPlaybackStateSubject.stream;
|
_fullPlaybackStateSubject.stream;
|
||||||
|
@ -325,6 +335,9 @@ class AudioPlaybackEvent {
|
||||||
/// The position at [updateTime].
|
/// The position at [updateTime].
|
||||||
final Duration updatePosition;
|
final Duration updatePosition;
|
||||||
|
|
||||||
|
/// The buffer position.
|
||||||
|
final Duration bufferedPosition;
|
||||||
|
|
||||||
/// The playback speed.
|
/// The playback speed.
|
||||||
final double speed;
|
final double speed;
|
||||||
|
|
||||||
|
@ -336,6 +349,7 @@ class AudioPlaybackEvent {
|
||||||
@required this.buffering,
|
@required this.buffering,
|
||||||
@required this.updateTime,
|
@required this.updateTime,
|
||||||
@required this.updatePosition,
|
@required this.updatePosition,
|
||||||
|
@required this.bufferedPosition,
|
||||||
@required this.speed,
|
@required this.speed,
|
||||||
@required this.duration,
|
@required this.duration,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue