-Improved null checks in player stream resolution.
-Improved naming in MediaSourceManager
This commit is contained in:
parent
52cdf96dfe
commit
0b1eda3050
|
@ -380,9 +380,10 @@ public final class BackgroundPlayer extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
|
public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
|
||||||
final int index = ListHelper.getDefaultAudioFormat(context, info.audio_streams);
|
final int index = ListHelper.getDefaultAudioFormat(context, info.audio_streams);
|
||||||
if (index < 0) return null;
|
if (index < 0 || index >= info.audio_streams.size()) return null;
|
||||||
|
|
||||||
final AudioStream audio = info.audio_streams.get(index);
|
final AudioStream audio = info.audio_streams.get(index);
|
||||||
return buildMediaSource(audio.url, MediaFormat.getSuffixById(audio.format));
|
return buildMediaSource(audio.url, MediaFormat.getSuffixById(audio.format));
|
||||||
|
|
|
@ -272,17 +272,18 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
|
public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
|
||||||
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false);
|
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false);
|
||||||
|
|
||||||
final VideoStream video;
|
final int index;
|
||||||
if (playbackQuality == null) {
|
if (playbackQuality == null) {
|
||||||
final int index = getDefaultResolutionIndex(videos);
|
index = getDefaultResolutionIndex(videos);
|
||||||
video = videos.get(index);
|
|
||||||
} else {
|
} else {
|
||||||
final int index = getOverrideResolutionIndex(videos, getPlaybackQuality());
|
index = getOverrideResolutionIndex(videos, getPlaybackQuality());
|
||||||
video = videos.get(index);
|
|
||||||
}
|
}
|
||||||
|
if (index < 0 || index >= videos.size()) return null;
|
||||||
|
final VideoStream video = videos.get(index);
|
||||||
|
|
||||||
final MediaSource streamSource = buildMediaSource(video.url, MediaFormat.getSuffixById(video.format));
|
final MediaSource streamSource = buildMediaSource(video.url, MediaFormat.getSuffixById(video.format));
|
||||||
final AudioStream audio = ListHelper.getHighestQualityAudio(info.audio_streams);
|
final AudioStream audio = ListHelper.getHighestQualityAudio(info.audio_streams);
|
||||||
|
|
|
@ -29,7 +29,7 @@ import io.reactivex.subjects.PublishSubject;
|
||||||
public class MediaSourceManager {
|
public class MediaSourceManager {
|
||||||
private final String TAG = "MediaSourceManager@" + Integer.toHexString(hashCode());
|
private final String TAG = "MediaSourceManager@" + Integer.toHexString(hashCode());
|
||||||
// One-side rolling window size for default loading
|
// One-side rolling window size for default loading
|
||||||
// Effectively loads windowSize * 2 + 1 streams, must be greater than 0
|
// Effectively loads windowSize * 2 + 1 streams per call to load, must be greater than 0
|
||||||
private final int windowSize;
|
private final int windowSize;
|
||||||
private final PlaybackListener playbackListener;
|
private final PlaybackListener playbackListener;
|
||||||
private final PlayQueue playQueue;
|
private final PlayQueue playQueue;
|
||||||
|
@ -38,7 +38,7 @@ public class MediaSourceManager {
|
||||||
// The higher it is, the less loading occurs during rapid noncritical timeline changes
|
// The higher it is, the less loading occurs during rapid noncritical timeline changes
|
||||||
// Not recommended to go below 100ms
|
// Not recommended to go below 100ms
|
||||||
private final long loadDebounceMillis;
|
private final long loadDebounceMillis;
|
||||||
private final PublishSubject<Long> loadSignal;
|
private final PublishSubject<Long> debouncedLoadSignal;
|
||||||
private final Disposable debouncedLoader;
|
private final Disposable debouncedLoader;
|
||||||
|
|
||||||
private final DeferredMediaSource.Callback sourceBuilder;
|
private final DeferredMediaSource.Callback sourceBuilder;
|
||||||
|
@ -69,7 +69,7 @@ public class MediaSourceManager {
|
||||||
this.loadDebounceMillis = loadDebounceMillis;
|
this.loadDebounceMillis = loadDebounceMillis;
|
||||||
|
|
||||||
this.syncReactor = new SerialDisposable();
|
this.syncReactor = new SerialDisposable();
|
||||||
this.loadSignal = PublishSubject.create();
|
this.debouncedLoadSignal = PublishSubject.create();
|
||||||
this.debouncedLoader = getDebouncedLoader();
|
this.debouncedLoader = getDebouncedLoader();
|
||||||
|
|
||||||
this.sourceBuilder = getSourceBuilder();
|
this.sourceBuilder = getSourceBuilder();
|
||||||
|
@ -101,7 +101,7 @@ public class MediaSourceManager {
|
||||||
* Dispose the manager and releases all message buses and loaders.
|
* Dispose the manager and releases all message buses and loaders.
|
||||||
* */
|
* */
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (loadSignal != null) loadSignal.onComplete();
|
if (debouncedLoadSignal != null) debouncedLoadSignal.onComplete();
|
||||||
if (debouncedLoader != null) debouncedLoader.dispose();
|
if (debouncedLoader != null) debouncedLoader.dispose();
|
||||||
if (playQueueReactor != null) playQueueReactor.cancel();
|
if (playQueueReactor != null) playQueueReactor.cancel();
|
||||||
if (syncReactor != null) syncReactor.dispose();
|
if (syncReactor != null) syncReactor.dispose();
|
||||||
|
@ -118,7 +118,7 @@ public class MediaSourceManager {
|
||||||
* Unblocks the player once the item at the current index is loaded.
|
* Unblocks the player once the item at the current index is loaded.
|
||||||
* */
|
* */
|
||||||
public void load() {
|
public void load() {
|
||||||
loadSignal.onNext(System.currentTimeMillis());
|
loadDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,14 +195,14 @@ public class MediaSourceManager {
|
||||||
case REORDER:
|
case REORDER:
|
||||||
case ERROR:
|
case ERROR:
|
||||||
case APPEND:
|
case APPEND:
|
||||||
loadInternal(); // low frequency, critical events
|
loadImmediate(); // low frequency, critical events
|
||||||
break;
|
break;
|
||||||
case REMOVE:
|
case REMOVE:
|
||||||
case SELECT:
|
case SELECT:
|
||||||
case MOVE:
|
case MOVE:
|
||||||
case RECOVERY:
|
case RECOVERY:
|
||||||
default:
|
default:
|
||||||
load(); // high frequency or noncritical events
|
loadDebounced(); // high frequency or noncritical events
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,11 @@ public class MediaSourceManager {
|
||||||
syncReactor.set(currentItem.getStream().subscribe(syncPlayback, onError));
|
syncReactor.set(currentItem.getStream().subscribe(syncPlayback, onError));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadInternal() {
|
private void loadDebounced() {
|
||||||
|
debouncedLoadSignal.onNext(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadImmediate() {
|
||||||
// The current item has higher priority
|
// The current item has higher priority
|
||||||
final int currentIndex = playQueue.getIndex();
|
final int currentIndex = playQueue.getIndex();
|
||||||
final PlayQueueItem currentItem = playQueue.getItem(currentIndex);
|
final PlayQueueItem currentItem = playQueue.getItem(currentIndex);
|
||||||
|
@ -307,13 +311,13 @@ public class MediaSourceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Disposable getDebouncedLoader() {
|
private Disposable getDebouncedLoader() {
|
||||||
return loadSignal
|
return debouncedLoadSignal
|
||||||
.debounce(loadDebounceMillis, TimeUnit.MILLISECONDS)
|
.debounce(loadDebounceMillis, TimeUnit.MILLISECONDS)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(new Consumer<Long>() {
|
.subscribe(new Consumer<Long>() {
|
||||||
@Override
|
@Override
|
||||||
public void accept(Long timestamp) throws Exception {
|
public void accept(Long timestamp) throws Exception {
|
||||||
loadInternal();
|
loadImmediate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ public interface PlaybackListener {
|
||||||
*
|
*
|
||||||
* May be called at any time.
|
* May be called at any time.
|
||||||
* */
|
* */
|
||||||
|
@Nullable
|
||||||
MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info);
|
MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue