mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-09-11 03:56:23 +00:00
casting: add helper functions for dispatching to active backend
This commit is contained in:
parent
595904b48b
commit
58e08f5ea3
6 changed files with 236 additions and 293 deletions
|
@ -21,6 +21,7 @@ import com.futo.platformplayer.casting.ChromecastCastingDevice
|
|||
import com.futo.platformplayer.casting.FCastCastingDevice
|
||||
import com.futo.platformplayer.casting.StateCasting
|
||||
import com.futo.platformplayer.experimental_casting.ExpStateCasting
|
||||
import com.futo.platformplayer.experimental_casting.StateCastingDispatcher
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.VideoDetailFragment
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
|
@ -74,30 +75,18 @@ class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
|||
|
||||
_buttonPlay = findViewById(R.id.button_play);
|
||||
_buttonPlay.setOnClickListener {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.resumePlayback()
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.resumeVideo()
|
||||
}
|
||||
StateCastingDispatcher.resumeVideo()
|
||||
}
|
||||
|
||||
_buttonPause = findViewById(R.id.button_pause);
|
||||
_buttonPause.setOnClickListener {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.pausePlayback()
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.pauseVideo()
|
||||
}
|
||||
StateCastingDispatcher.pauseVideo()
|
||||
}
|
||||
|
||||
_buttonStop = findViewById(R.id.button_stop);
|
||||
_buttonStop.setOnClickListener {
|
||||
(ownerActivity as MainActivity?)?.getFragment<VideoDetailFragment>()?.closeVideoDetails()
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.stopPlayback()
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.stopVideo()
|
||||
}
|
||||
StateCastingDispatcher.stopVideo()
|
||||
}
|
||||
|
||||
_buttonNext = findViewById(R.id.button_next);
|
||||
|
@ -125,21 +114,7 @@ class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
|||
return@OnChangeListener
|
||||
}
|
||||
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val activeDevice = ExpStateCasting.instance.activeDevice ?: return@OnChangeListener;
|
||||
try {
|
||||
activeDevice.device.seek(value.toDouble());
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to seek.", e);
|
||||
}
|
||||
} else {
|
||||
val activeDevice = StateCasting.instance.activeDevice ?: return@OnChangeListener;
|
||||
try {
|
||||
activeDevice.seekVideo(value.toDouble());
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to seek.", e);
|
||||
}
|
||||
}
|
||||
StateCastingDispatcher.videoSeekTo(value.toDouble())
|
||||
});
|
||||
|
||||
//TODO: Check if volume slider is properly hidden in all cases
|
||||
|
@ -148,25 +123,7 @@ class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
|||
return@OnChangeListener
|
||||
}
|
||||
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val activeDevice = ExpStateCasting.instance.activeDevice ?: return@OnChangeListener;
|
||||
if (activeDevice.device.supportsFeature(DeviceFeature.SET_VOLUME)) {
|
||||
try {
|
||||
activeDevice.device.changeVolume(value.toDouble());
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to change volume.", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val activeDevice = StateCasting.instance.activeDevice ?: return@OnChangeListener;
|
||||
if (activeDevice.canSetVolume) {
|
||||
try {
|
||||
activeDevice.changeVolume(value.toDouble());
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to change volume.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
StateCastingDispatcher.changeVolume(value.toDouble())
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
|
|
|
@ -110,12 +110,17 @@ class CastingDeviceHandle {
|
|||
contentType: String,
|
||||
contentId: String,
|
||||
resumePosition: Double,
|
||||
duration: Double,
|
||||
speed: Double?,
|
||||
metadata: Metadata? = null
|
||||
) {
|
||||
try {
|
||||
device.load(LoadRequest.Video(contentType, contentId, resumePosition, speed, duration, metadata))
|
||||
device.load(LoadRequest.Video(
|
||||
contentType = contentType,
|
||||
url = contentId,
|
||||
resumePosition = resumePosition,
|
||||
speed = speed,
|
||||
metadata = metadata
|
||||
))
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to load video: $e")
|
||||
}
|
||||
|
@ -125,11 +130,15 @@ class CastingDeviceHandle {
|
|||
contentType: String,
|
||||
content: String,
|
||||
resumePosition: Double,
|
||||
duration: Double,
|
||||
speed: Double?
|
||||
) {
|
||||
try {
|
||||
device.load(LoadRequest.Content(contentType, content, resumePosition, duration, speed))
|
||||
device.load(LoadRequest.Content(
|
||||
contentType =contentType,
|
||||
content = content,
|
||||
resumePosition = resumePosition,
|
||||
speed = speed
|
||||
))
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to load content: $e")
|
||||
}
|
||||
|
|
|
@ -569,7 +569,6 @@ class ExpStateCasting {
|
|||
videoSource.container,
|
||||
videoUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
)
|
||||
|
@ -581,7 +580,6 @@ class ExpStateCasting {
|
|||
audioSource.container,
|
||||
audioUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -601,7 +599,6 @@ class ExpStateCasting {
|
|||
videoSource.container,
|
||||
videoSource.url,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -622,7 +619,6 @@ class ExpStateCasting {
|
|||
audioSource.container,
|
||||
audioSource.url,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -738,7 +734,6 @@ class ExpStateCasting {
|
|||
videoSource.container,
|
||||
videoUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -769,7 +764,6 @@ class ExpStateCasting {
|
|||
audioSource.container,
|
||||
audioUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -963,7 +957,6 @@ class ExpStateCasting {
|
|||
"application/vnd.apple.mpegurl",
|
||||
hlsUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
)
|
||||
|
@ -1043,7 +1036,6 @@ class ExpStateCasting {
|
|||
"application/dash+xml",
|
||||
dashUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -1139,7 +1131,6 @@ class ExpStateCasting {
|
|||
"application/dash+xml",
|
||||
content,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed
|
||||
);
|
||||
|
||||
|
@ -1319,7 +1310,6 @@ class ExpStateCasting {
|
|||
"application/vnd.apple.mpegurl",
|
||||
hlsUrl,
|
||||
hackfixResumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -1487,7 +1477,6 @@ class ExpStateCasting {
|
|||
"application/dash+xml",
|
||||
dashUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
@ -1756,7 +1745,6 @@ class ExpStateCasting {
|
|||
"application/dash+xml",
|
||||
dashUrl,
|
||||
resumePosition,
|
||||
video.duration.toDouble(),
|
||||
speed,
|
||||
metadataFromVideo(video)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
package com.futo.platformplayer.experimental_casting
|
||||
|
||||
import com.futo.platformplayer.Settings
|
||||
import com.futo.platformplayer.casting.CastConnectionState
|
||||
import com.futo.platformplayer.casting.StateCasting
|
||||
import com.futo.platformplayer.dialogs.ConnectedCastingDialog.Companion.TAG
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import org.fcast.sender_sdk.DeviceFeature
|
||||
|
||||
class StateCastingDispatcher {
|
||||
companion object {
|
||||
fun canActiveDeviceSetSpeed(): Boolean {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.supportsFeature(DeviceFeature.SET_SPEED) == true
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.canSetSpeed == true
|
||||
}
|
||||
}
|
||||
|
||||
fun getActiveDeviceSpeed(): Double? {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.speed
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.speed
|
||||
}
|
||||
}
|
||||
|
||||
fun activeDeviceSetSpeed(speed: Double) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.changeSpeed(speed)
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.changeSpeed(speed)
|
||||
}
|
||||
}
|
||||
|
||||
fun resumeVideo(): Boolean {
|
||||
return try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.resumeVideo()
|
||||
} else {
|
||||
StateCasting.instance.resumeVideo()
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun pauseVideo(): Boolean {
|
||||
return try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.pauseVideo()
|
||||
} else {
|
||||
StateCasting.instance.pauseVideo()
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun videoSeekTo(timeSeconds: Double): Boolean {
|
||||
return try {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.videoSeekTo(timeSeconds)
|
||||
} else {
|
||||
StateCasting.instance.videoSeekTo(timeSeconds)
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun stopVideo(): Boolean {
|
||||
return try {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.stopVideo()
|
||||
} else {
|
||||
StateCasting.instance.stopVideo()
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun isCasting(): Boolean {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.isCasting
|
||||
} else {
|
||||
StateCasting.instance.isCasting
|
||||
}
|
||||
}
|
||||
|
||||
fun isConnected(): Boolean {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.connectionState == com.futo.platformplayer.experimental_casting.CastConnectionState.CONNECTED
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.connectionState == CastConnectionState.CONNECTED
|
||||
}
|
||||
}
|
||||
|
||||
fun isPlaying(): Boolean {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.isPlaying == true
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.isPlaying == true
|
||||
}
|
||||
}
|
||||
|
||||
fun getExpectedCurrentTime(): Double? {
|
||||
return if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.expectedCurrentTime
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.expectedCurrentTime
|
||||
}
|
||||
}
|
||||
|
||||
fun changeVolume(volume: Double) {
|
||||
try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val activeDevice =
|
||||
ExpStateCasting.instance.activeDevice ?: return;
|
||||
if (activeDevice.device.supportsFeature(DeviceFeature.SET_VOLUME)) {
|
||||
activeDevice.device.changeVolume(volume);
|
||||
}
|
||||
} else {
|
||||
val activeDevice =
|
||||
StateCasting.instance.activeDevice ?: return;
|
||||
if (activeDevice.canSetVolume) {
|
||||
activeDevice.changeVolume(volume);
|
||||
}
|
||||
}
|
||||
} catch (_: Throwable) {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,6 +99,7 @@ import com.futo.platformplayer.engine.exceptions.ScriptReloadRequiredException
|
|||
import com.futo.platformplayer.engine.exceptions.ScriptUnavailableException
|
||||
import com.futo.platformplayer.exceptions.UnsupportedCastException
|
||||
import com.futo.platformplayer.experimental_casting.ExpStateCasting
|
||||
import com.futo.platformplayer.experimental_casting.StateCastingDispatcher
|
||||
import com.futo.platformplayer.fixHtmlLinks
|
||||
import com.futo.platformplayer.fixHtmlWhitespace
|
||||
import com.futo.platformplayer.getNowDiffSeconds
|
||||
|
@ -1217,12 +1218,8 @@ class VideoDetailView : ConstraintLayout {
|
|||
_onPauseCalled = true;
|
||||
_taskLoadVideo.cancel();
|
||||
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
if(ExpStateCasting.instance.isCasting)
|
||||
return;
|
||||
} else {
|
||||
if(StateCasting.instance.isCasting)
|
||||
return;
|
||||
if (StateCastingDispatcher.isCasting()) {
|
||||
return
|
||||
}
|
||||
|
||||
if(allowBackground)
|
||||
|
@ -2014,12 +2011,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
return;
|
||||
}
|
||||
|
||||
val isCasting = if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.isCasting
|
||||
} else {
|
||||
StateCasting.instance.isCasting
|
||||
}
|
||||
if (!isCasting) {
|
||||
if (!StateCastingDispatcher.isCasting()) {
|
||||
setCastEnabled(false);
|
||||
|
||||
val isLimitedVersion = StatePlatform.instance.getContentClientOrNull(video.url)?.let {
|
||||
|
@ -2303,11 +2295,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
}
|
||||
|
||||
val currentPlaybackRate = (if (_isCasting) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.speed
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.speed
|
||||
}
|
||||
StateCastingDispatcher.getActiveDeviceSpeed()
|
||||
} else _player.getPlaybackRate()) ?: 1.0
|
||||
_overlay_quality_selector?.groupItems?.firstOrNull { it is SlideUpMenuButtonList && it.id == "playback_rate" }?.let {
|
||||
(it as SlideUpMenuButtonList).setSelected(currentPlaybackRate.toString())
|
||||
|
@ -2426,18 +2414,12 @@ class VideoDetailView : ConstraintLayout {
|
|||
?.distinct()
|
||||
?.toList() ?: listOf() else audioSources?.toList() ?: listOf();
|
||||
|
||||
val canSetSpeed = !_isCasting || if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.device?.supportsFeature(DeviceFeature.SET_SPEED) == true
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.canSetSpeed == true
|
||||
}
|
||||
val canSetSpeed = !_isCasting || StateCastingDispatcher.canActiveDeviceSetSpeed();
|
||||
val currentPlaybackRate = if (_isCasting) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.speed
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.speed
|
||||
}
|
||||
} else _player.getPlaybackRate()
|
||||
StateCastingDispatcher.getActiveDeviceSpeed()
|
||||
} else {
|
||||
_player.getPlaybackRate()
|
||||
}
|
||||
val qualityPlaybackSpeedTitle = if (canSetSpeed) SlideUpMenuTitle(this.context).apply { setTitle(context.getString(R.string.playback_rate) + " (${String.format("%.2f", currentPlaybackRate)})"); } else null;
|
||||
_overlay_quality_selector = SlideUpMenuOverlay(this.context, _overlay_quality_container, context.getString(
|
||||
R.string.quality), null, true,
|
||||
|
@ -2452,11 +2434,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
setButtons(playbackLabels, String.format(Locale.US, format, currentPlaybackRate));
|
||||
onClick.subscribe { v ->
|
||||
val currentPlaybackSpeed = if (_isCasting) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.speed
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.speed
|
||||
}
|
||||
StateCastingDispatcher.getActiveDeviceSpeed()
|
||||
} else _player.getPlaybackRate();
|
||||
var playbackSpeedString = v;
|
||||
val stepSpeed = Settings.instance.playback.getPlaybackSpeedStep();
|
||||
|
@ -2465,26 +2443,10 @@ class VideoDetailView : ConstraintLayout {
|
|||
else if(v == "-")
|
||||
playbackSpeedString = String.format(Locale.US, "%.2f", Math.max(0.1, (currentPlaybackSpeed?.toDouble() ?: 1.0) - stepSpeed)).toString();
|
||||
val newPlaybackSpeed = playbackSpeedString.toDouble();
|
||||
if (_isCasting) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val ad = ExpStateCasting.instance.activeDevice ?: return@subscribe
|
||||
if (!ad.device.supportsFeature(DeviceFeature.SET_SPEED)) {
|
||||
return@subscribe
|
||||
}
|
||||
|
||||
qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format(Locale.US, "%.2f", newPlaybackSpeed)})");
|
||||
ad.device.changeSpeed(newPlaybackSpeed)
|
||||
setSelected(playbackSpeedString);
|
||||
} else {
|
||||
val ad = StateCasting.instance.activeDevice ?: return@subscribe
|
||||
if (!ad.canSetSpeed) {
|
||||
return@subscribe
|
||||
}
|
||||
|
||||
qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format(Locale.US, "%.2f", newPlaybackSpeed)})");
|
||||
ad.changeSpeed(newPlaybackSpeed)
|
||||
setSelected(playbackSpeedString);
|
||||
}
|
||||
if (_isCasting && StateCastingDispatcher.canActiveDeviceSetSpeed()) {
|
||||
qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format(Locale.US, "%.2f", newPlaybackSpeed)})");
|
||||
StateCastingDispatcher.activeDeviceSetSpeed(newPlaybackSpeed)
|
||||
setSelected(playbackSpeedString);
|
||||
} else {
|
||||
qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format(Locale.US, "%.2f", newPlaybackSpeed)})");
|
||||
_player.setPlaybackRate(playbackSpeedString.toFloat());
|
||||
|
@ -2599,14 +2561,8 @@ class VideoDetailView : ConstraintLayout {
|
|||
//Handlers
|
||||
private fun handlePlay() {
|
||||
Logger.i(TAG, "handlePlay")
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
if (!ExpStateCasting.instance.resumeVideo()) {
|
||||
_player.play()
|
||||
}
|
||||
} else {
|
||||
if (!StateCasting.instance.resumeVideo()) {
|
||||
_player.play();
|
||||
}
|
||||
if (!StateCastingDispatcher.resumeVideo()) {
|
||||
_player.play()
|
||||
}
|
||||
|
||||
//TODO: This was needed because handleLowerVolume was done.
|
||||
|
@ -2621,60 +2577,31 @@ class VideoDetailView : ConstraintLayout {
|
|||
|
||||
private fun handlePause() {
|
||||
Logger.i(TAG, "handlePause")
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
if (!ExpStateCasting.instance.pauseVideo()) {
|
||||
_player.pause()
|
||||
}
|
||||
} else {
|
||||
if (!StateCasting.instance.pauseVideo()) {
|
||||
_player.pause()
|
||||
}
|
||||
if (!StateCastingDispatcher.pauseVideo()) {
|
||||
_player.pause()
|
||||
}
|
||||
}
|
||||
private fun handleSeek(ms: Long) {
|
||||
Logger.i(TAG, "handleSeek(ms=$ms)")
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
if (!ExpStateCasting.instance.videoSeekTo(ms.toDouble() / 1000.0)) {
|
||||
_player.seekTo(ms)
|
||||
}
|
||||
} else {
|
||||
if (!StateCasting.instance.videoSeekTo(ms.toDouble() / 1000.0)) {
|
||||
_player.seekTo(ms)
|
||||
}
|
||||
if (!StateCastingDispatcher.videoSeekTo(ms.toDouble() / 1000.0)) {
|
||||
_player.seekTo(ms)
|
||||
}
|
||||
}
|
||||
private fun handleStop() {
|
||||
Logger.i(TAG, "handleStop")
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
if (!ExpStateCasting.instance.stopVideo()) {
|
||||
_player.stop()
|
||||
}
|
||||
} else {
|
||||
if (!StateCasting.instance.stopVideo()) {
|
||||
_player.stop()
|
||||
}
|
||||
if (!StateCastingDispatcher.stopVideo()) {
|
||||
_player.stop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePlayChanged(playing: Boolean) {
|
||||
Logger.i(TAG, "handlePlayChanged(playing=$playing)")
|
||||
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val ad = ExpStateCasting.instance.activeDevice;
|
||||
if (ad != null) {
|
||||
_cast.setIsPlaying(playing);
|
||||
} else {
|
||||
StatePlayer.instance.updateMediaSession( null);
|
||||
StatePlayer.instance.updateMediaSessionPlaybackState(_player.exoPlayer?.getPlaybackStateCompat() ?: PlaybackStateCompat.STATE_NONE, _player.exoPlayer?.player?.currentPosition ?: 0);
|
||||
}
|
||||
if (StateCastingDispatcher.isCasting()) {
|
||||
_cast.setIsPlaying(playing);
|
||||
} else {
|
||||
val ad = StateCasting.instance.activeDevice;
|
||||
if (ad != null) {
|
||||
_cast.setIsPlaying(playing);
|
||||
} else {
|
||||
StatePlayer.instance.updateMediaSession( null);
|
||||
StatePlayer.instance.updateMediaSessionPlaybackState(_player.exoPlayer?.getPlaybackStateCompat() ?: PlaybackStateCompat.STATE_NONE, _player.exoPlayer?.player?.currentPosition ?: 0);
|
||||
}
|
||||
StatePlayer.instance.updateMediaSession( null);
|
||||
StatePlayer.instance.updateMediaSessionPlaybackState(_player.exoPlayer?.getPlaybackStateCompat() ?: PlaybackStateCompat.STATE_NONE, _player.exoPlayer?.player?.currentPosition ?: 0);
|
||||
}
|
||||
|
||||
if(playing) {
|
||||
|
@ -2712,26 +2639,20 @@ class VideoDetailView : ConstraintLayout {
|
|||
|
||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val d = ExpStateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == com.futo.platformplayer.experimental_casting.CastConnectionState.CONNECTED)
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
videoSource,
|
||||
_lastAudioSource,
|
||||
_lastSubtitleSource,
|
||||
(d.expectedCurrentTime * 1000.0).toLong(),
|
||||
d.speed
|
||||
);
|
||||
else if(!_player.swapSources(videoSource, _lastAudioSource, true, true, true))
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
} else {
|
||||
val d = StateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == CastConnectionState.CONNECTED)
|
||||
castIfAvailable(context.contentResolver, video, videoSource, _lastAudioSource, _lastSubtitleSource, (d.expectedCurrentTime * 1000.0).toLong(), d.speed);
|
||||
else if(!_player.swapSources(videoSource, _lastAudioSource, true, true, true))
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
if (StateCastingDispatcher.isConnected()) {
|
||||
val expectedCurrentTime = StateCastingDispatcher.getExpectedCurrentTime() ?: 0.0
|
||||
val speed = StateCastingDispatcher.getActiveDeviceSpeed() ?: 1.0
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
videoSource,
|
||||
_lastAudioSource,
|
||||
_lastSubtitleSource,
|
||||
(expectedCurrentTime * 1000.0).toLong(),
|
||||
speed
|
||||
)
|
||||
} else if(!_player.swapSources(videoSource, _lastAudioSource, true, true, true)) {
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "handleSelectVideoTrack failed", e)
|
||||
|
@ -2749,34 +2670,20 @@ class VideoDetailView : ConstraintLayout {
|
|||
|
||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val d = ExpStateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == com.futo.platformplayer.experimental_casting.CastConnectionState.CONNECTED)
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
audioSource,
|
||||
_lastSubtitleSource,
|
||||
(d.expectedCurrentTime * 1000.0).toLong(),
|
||||
d.speed
|
||||
)
|
||||
else if (!_player.swapSources(_lastVideoSource, audioSource, true, true, true))
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
} else {
|
||||
val d = StateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == CastConnectionState.CONNECTED)
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
audioSource,
|
||||
_lastSubtitleSource,
|
||||
(d.expectedCurrentTime * 1000.0).toLong(),
|
||||
d.speed
|
||||
)
|
||||
else if (!_player.swapSources(_lastVideoSource, audioSource, true, true, true))
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
if (StateCastingDispatcher.isConnected()) {
|
||||
val expectedCurrentTime = StateCastingDispatcher.getExpectedCurrentTime() ?: 0.0
|
||||
val speed = StateCastingDispatcher.getActiveDeviceSpeed() ?: 1.0
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
audioSource,
|
||||
_lastSubtitleSource,
|
||||
(expectedCurrentTime * 1000.0).toLong(),
|
||||
speed
|
||||
)
|
||||
} else if (!_player.swapSources(_lastVideoSource, audioSource, true, true, true)) {
|
||||
_player.hideControls(false); //TODO: Disable player?
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "handleSelectAudioTrack failed", e)
|
||||
|
@ -2795,36 +2702,20 @@ class VideoDetailView : ConstraintLayout {
|
|||
|
||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val d = ExpStateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == com.futo.platformplayer.experimental_casting.CastConnectionState.CONNECTED)
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
_lastAudioSource,
|
||||
toSet,
|
||||
(d.expectedCurrentTime * 1000.0).toLong(),
|
||||
d.speed
|
||||
);
|
||||
else {
|
||||
_player.swapSubtitles(toSet);
|
||||
}
|
||||
if (StateCastingDispatcher.isConnected()) {
|
||||
val expectedCurrentTime = StateCastingDispatcher.getExpectedCurrentTime() ?: 0.0
|
||||
val speed = StateCastingDispatcher.getActiveDeviceSpeed() ?: 1.0
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
_lastAudioSource,
|
||||
toSet,
|
||||
(expectedCurrentTime * 1000.0).toLong(),
|
||||
speed
|
||||
)
|
||||
} else {
|
||||
val d = StateCasting.instance.activeDevice;
|
||||
if (d != null && d.connectionState == CastConnectionState.CONNECTED)
|
||||
castIfAvailable(
|
||||
context.contentResolver,
|
||||
video,
|
||||
_lastVideoSource,
|
||||
_lastAudioSource,
|
||||
toSet,
|
||||
(d.expectedCurrentTime * 1000.0).toLong(),
|
||||
d.speed
|
||||
);
|
||||
else {
|
||||
_player.swapSubtitles(toSet);
|
||||
}
|
||||
_player.swapSubtitles(toSet);
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "handleSelectSubtitleTrack failed", e)
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.futo.platformplayer.constructs.Event0
|
|||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.constructs.Event2
|
||||
import com.futo.platformplayer.experimental_casting.ExpStateCasting
|
||||
import com.futo.platformplayer.experimental_casting.StateCastingDispatcher
|
||||
import com.futo.platformplayer.formatDuration
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.states.StateHistory
|
||||
|
@ -142,13 +143,8 @@ class CastView : ConstraintLayout {
|
|||
}
|
||||
|
||||
_gestureControlView.onSeek.subscribe {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val d = ExpStateCasting.instance.activeDevice ?: return@subscribe;
|
||||
ExpStateCasting.instance.videoSeekTo(d.expectedCurrentTime + it / 1000);
|
||||
} else {
|
||||
val d = StateCasting.instance.activeDevice ?: return@subscribe;
|
||||
StateCasting.instance.videoSeekTo(d.expectedCurrentTime + it / 1000);
|
||||
}
|
||||
val expectedCurrentTime = StateCastingDispatcher.getExpectedCurrentTime() ?: return@subscribe
|
||||
StateCastingDispatcher.videoSeekTo(expectedCurrentTime + it / 1000)
|
||||
};
|
||||
|
||||
_buttonLoop.setOnClickListener {
|
||||
|
@ -159,45 +155,25 @@ class CastView : ConstraintLayout {
|
|||
|
||||
_timeBar.addListener(object : TimeBar.OnScrubListener {
|
||||
override fun onScrubStart(timeBar: TimeBar, position: Long) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.videoSeekTo(position.toDouble());
|
||||
} else {
|
||||
StateCasting.instance.videoSeekTo(position.toDouble());
|
||||
}
|
||||
StateCastingDispatcher.videoSeekTo(position.toDouble())
|
||||
}
|
||||
|
||||
override fun onScrubMove(timeBar: TimeBar, position: Long) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.videoSeekTo(position.toDouble());
|
||||
} else {
|
||||
StateCasting.instance.videoSeekTo(position.toDouble());
|
||||
}
|
||||
StateCastingDispatcher.videoSeekTo(position.toDouble())
|
||||
}
|
||||
|
||||
override fun onScrubStop(timeBar: TimeBar, position: Long, canceled: Boolean) {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.videoSeekTo(position.toDouble());
|
||||
} else {
|
||||
StateCasting.instance.videoSeekTo(position.toDouble());
|
||||
}
|
||||
StateCastingDispatcher.videoSeekTo(position.toDouble())
|
||||
}
|
||||
});
|
||||
|
||||
_buttonMinimize.setOnClickListener { onMinimizeClick.emit(); };
|
||||
_buttonSettings.setOnClickListener { onSettingsClick.emit(); };
|
||||
_buttonPlay.setOnClickListener {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.resumeVideo()
|
||||
} else {
|
||||
StateCasting.instance.resumeVideo()
|
||||
}
|
||||
StateCastingDispatcher.resumeVideo()
|
||||
}
|
||||
_buttonPause.setOnClickListener {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.pauseVideo()
|
||||
} else {
|
||||
StateCasting.instance.pauseVideo()
|
||||
}
|
||||
StateCastingDispatcher.pauseVideo()
|
||||
}
|
||||
|
||||
if (!isInEditMode) {
|
||||
|
@ -311,11 +287,7 @@ class CastView : ConstraintLayout {
|
|||
_buttonPlay.visibility = View.VISIBLE;
|
||||
}
|
||||
|
||||
val position = if (Settings.instance.casting.experimentalCasting) {
|
||||
ExpStateCasting.instance.activeDevice?.expectedCurrentTime?.times(1000.0)?.toLong()
|
||||
} else {
|
||||
StateCasting.instance.activeDevice?.expectedCurrentTime?.times(1000.0)?.toLong();
|
||||
}
|
||||
val position = StateCastingDispatcher.getExpectedCurrentTime()?.times(1000.0)?.toLong()
|
||||
if(StatePlayer.instance.hasMediaSession()) {
|
||||
StatePlayer.instance.updateMediaSession(null);
|
||||
StatePlayer.instance.updateMediaSessionPlaybackState(getPlaybackStateCompat(), (position ?: 0));
|
||||
|
@ -379,20 +351,12 @@ class CastView : ConstraintLayout {
|
|||
}
|
||||
|
||||
private fun getPlaybackStateCompat(): Int {
|
||||
if (Settings.instance.casting.experimentalCasting) {
|
||||
val d = ExpStateCasting.instance.activeDevice ?: return PlaybackState.STATE_NONE;
|
||||
|
||||
return when(d.isPlaying) {
|
||||
true -> PlaybackStateCompat.STATE_PLAYING;
|
||||
else -> PlaybackStateCompat.STATE_PAUSED;
|
||||
}
|
||||
} else {
|
||||
val d = StateCasting.instance.activeDevice ?: return PlaybackState.STATE_NONE;
|
||||
|
||||
return when(d.isPlaying) {
|
||||
true -> PlaybackStateCompat.STATE_PLAYING;
|
||||
else -> PlaybackStateCompat.STATE_PAUSED;
|
||||
}
|
||||
if (!StateCastingDispatcher.isConnected()) {
|
||||
return PlaybackState.STATE_NONE
|
||||
}
|
||||
return when(StateCastingDispatcher.isPlaying()) {
|
||||
true -> PlaybackStateCompat.STATE_PLAYING;
|
||||
else -> PlaybackStateCompat.STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue