mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-02 22:30:40 +00:00
improved vertical video detection and auto full screen for vertical videos
This commit is contained in:
parent
1564433e02
commit
cc0c400b28
2 changed files with 126 additions and 52 deletions
|
@ -96,7 +96,7 @@ class VideoDetailFragment : MainFragment {
|
||||||
|
|
||||||
detectWindowSize()
|
detectWindowSize()
|
||||||
|
|
||||||
val isLandscapeVideo: Boolean = _viewDetail?.isLandscapeVideo() ?: true
|
val isLandscapeVideo: Boolean = _viewDetail?.isLandscapeVideo() ?: false
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isSmallWindow
|
isSmallWindow
|
||||||
|
@ -117,13 +117,29 @@ class VideoDetailFragment : MainFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onStateChanged(state: State) {
|
private fun onStateChanged(state: State) {
|
||||||
if (isSmallWindow && state == State.MAXIMIZED && !isFullscreen && resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
if (
|
||||||
|
isSmallWindow
|
||||||
|
&& state == State.MAXIMIZED
|
||||||
|
&& !isFullscreen
|
||||||
|
&& resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
) {
|
||||||
_viewDetail?.setFullscreen(true)
|
_viewDetail?.setFullscreen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOrientation()
|
updateOrientation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onVideoChanged(videoWidth : Int, videoHeight: Int) {
|
||||||
|
if (
|
||||||
|
isSmallWindow
|
||||||
|
&& state == State.MAXIMIZED
|
||||||
|
&& !isFullscreen
|
||||||
|
&& videoHeight > videoWidth
|
||||||
|
) {
|
||||||
|
_viewDetail?.setFullscreen(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
fun updateOrientation() {
|
fun updateOrientation() {
|
||||||
val a = activity ?: return
|
val a = activity ?: return
|
||||||
|
@ -133,7 +149,7 @@ class VideoDetailFragment : MainFragment {
|
||||||
val isReversePortraitAllowed = Settings.instance.playback.reversePortrait
|
val isReversePortraitAllowed = Settings.instance.playback.reversePortrait
|
||||||
val rotationLock = StatePlayer.instance.rotationLock
|
val rotationLock = StatePlayer.instance.rotationLock
|
||||||
|
|
||||||
val isLandscapeVideo: Boolean = _viewDetail?.isLandscapeVideo() ?: true
|
val isLandscapeVideo: Boolean = _viewDetail?.isLandscapeVideo() ?: false
|
||||||
|
|
||||||
// For small windows if the device isn't landscape right now and full screen portrait isn't allowed then we should force landscape
|
// For small windows if the device isn't landscape right now and full screen portrait isn't allowed then we should force landscape
|
||||||
if (isSmallWindow && isFullscreen && !isFullScreenPortraitAllowed && resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT && !rotationLock && isLandscapeVideo) {
|
if (isSmallWindow && isFullscreen && !isFullScreenPortraitAllowed && resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT && !rotationLock && isLandscapeVideo) {
|
||||||
|
@ -247,6 +263,7 @@ class VideoDetailFragment : MainFragment {
|
||||||
_viewDetail = _view!!.findViewById<VideoDetailView>(R.id.fragview_videodetail).also {
|
_viewDetail = _view!!.findViewById<VideoDetailView>(R.id.fragview_videodetail).also {
|
||||||
it.applyFragment(this);
|
it.applyFragment(this);
|
||||||
it.onFullscreenChanged.subscribe(::onFullscreenChanged);
|
it.onFullscreenChanged.subscribe(::onFullscreenChanged);
|
||||||
|
it.onVideoChanged.subscribe(::onVideoChanged)
|
||||||
it.onMinimize.subscribe {
|
it.onMinimize.subscribe {
|
||||||
isMinimizing = true
|
isMinimizing = true
|
||||||
_view!!.transitionToStart();
|
_view!!.transitionToStart();
|
||||||
|
|
|
@ -80,6 +80,7 @@ import com.futo.platformplayer.casting.CastConnectionState
|
||||||
import com.futo.platformplayer.casting.StateCasting
|
import com.futo.platformplayer.casting.StateCasting
|
||||||
import com.futo.platformplayer.constructs.Event0
|
import com.futo.platformplayer.constructs.Event0
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.constructs.Event2
|
||||||
import com.futo.platformplayer.constructs.TaskHandler
|
import com.futo.platformplayer.constructs.TaskHandler
|
||||||
import com.futo.platformplayer.downloads.VideoLocal
|
import com.futo.platformplayer.downloads.VideoLocal
|
||||||
import com.futo.platformplayer.dp
|
import com.futo.platformplayer.dp
|
||||||
|
@ -300,6 +301,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
val onFullscreenChanged = Event1<Boolean>();
|
val onFullscreenChanged = Event1<Boolean>();
|
||||||
val onEnterPictureInPicture = Event0();
|
val onEnterPictureInPicture = Event0();
|
||||||
val onPlayChanged = Event1<Boolean>();
|
val onPlayChanged = Event1<Boolean>();
|
||||||
|
val onVideoChanged = Event2<Int, Int>()
|
||||||
|
|
||||||
var allowBackground : Boolean = false
|
var allowBackground : Boolean = false
|
||||||
private set;
|
private set;
|
||||||
|
@ -1205,6 +1207,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
switchContentView(_container_content_main);
|
switchContentView(_container_content_main);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
fun setVideoDetails(videoDetail: IPlatformVideoDetails, newVideo: Boolean = false) {
|
fun setVideoDetails(videoDetail: IPlatformVideoDetails, newVideo: Boolean = false) {
|
||||||
Logger.i(TAG, "setVideoDetails (${videoDetail.name})")
|
Logger.i(TAG, "setVideoDetails (${videoDetail.name})")
|
||||||
|
@ -1213,7 +1216,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
_autoplayVideo = null
|
_autoplayVideo = null
|
||||||
Logger.i(TAG, "Autoplay video cleared (setVideoDetails)")
|
Logger.i(TAG, "Autoplay video cleared (setVideoDetails)")
|
||||||
|
|
||||||
if(newVideo && this.video?.url == videoDetail.url)
|
if (newVideo && this.video?.url == videoDetail.url)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (newVideo) {
|
if (newVideo) {
|
||||||
|
@ -1222,8 +1225,13 @@ class VideoDetailView : ConstraintLayout {
|
||||||
_lastSubtitleSource = null;
|
_lastSubtitleSource = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(videoDetail.datetime != null && videoDetail.datetime!! > OffsetDateTime.now())
|
if (videoDetail.datetime != null && videoDetail.datetime!! > OffsetDateTime.now())
|
||||||
UIDialogs.toast(context, context.getString(R.string.planned_in) + " ${videoDetail.datetime?.toHumanNowDiffString(true)}")
|
UIDialogs.toast(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.planned_in) + " ${
|
||||||
|
videoDetail.datetime?.toHumanNowDiffString(true)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
if (!videoDetail.isLive) {
|
if (!videoDetail.isLive) {
|
||||||
_player.setPlaybackRate(Settings.instance.playback.getDefaultPlaybackSpeed());
|
_player.setPlaybackRate(Settings.instance.playback.getDefaultPlaybackSpeed());
|
||||||
|
@ -1232,26 +1240,25 @@ class VideoDetailView : ConstraintLayout {
|
||||||
val videoLocal: VideoLocal?;
|
val videoLocal: VideoLocal?;
|
||||||
val video: IPlatformVideoDetails?;
|
val video: IPlatformVideoDetails?;
|
||||||
|
|
||||||
if(videoDetail is VideoLocal) {
|
if (videoDetail is VideoLocal) {
|
||||||
videoLocal = videoDetail;
|
videoLocal = videoDetail;
|
||||||
video = videoDetail;
|
video = videoDetail;
|
||||||
this.video = video;
|
this.video = video;
|
||||||
val videoTask = StatePlatform.instance.getContentDetails(videoDetail.url);
|
val videoTask = StatePlatform.instance.getContentDetails(videoDetail.url);
|
||||||
videoTask.invokeOnCompletion { ex ->
|
videoTask.invokeOnCompletion { ex ->
|
||||||
if(ex != null) {
|
if (ex != null) {
|
||||||
Logger.e(TAG, "Failed to fetch live video for offline video", ex);
|
Logger.e(TAG, "Failed to fetch live video for offline video", ex);
|
||||||
return@invokeOnCompletion;
|
return@invokeOnCompletion;
|
||||||
}
|
}
|
||||||
val result = videoTask.getCompleted();
|
val result = videoTask.getCompleted();
|
||||||
if(this.video == videoDetail && result is IPlatformVideoDetails) {
|
if (this.video == videoDetail && result is IPlatformVideoDetails) {
|
||||||
this.video = result;
|
this.video = result;
|
||||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||||
updateQualitySourcesOverlay(result, videoLocal);
|
updateQualitySourcesOverlay(result, videoLocal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} else { //TODO: Update cached video if it exists with video
|
||||||
else { //TODO: Update cached video if it exists with video
|
|
||||||
videoLocal = StateDownloads.instance.getCachedVideo(videoDetail.id);
|
videoLocal = StateDownloads.instance.getCachedVideo(videoDetail.id);
|
||||||
video = videoDetail;
|
video = videoDetail;
|
||||||
}
|
}
|
||||||
|
@ -1259,7 +1266,9 @@ class VideoDetailView : ConstraintLayout {
|
||||||
this.video = video;
|
this.video = video;
|
||||||
cleanupPlaybackTracker();
|
cleanupPlaybackTracker();
|
||||||
|
|
||||||
if(video is JSVideoDetails) {
|
onVideoChanged.emit(video.video.videoSources[0].width, video.video.videoSources[0].height)
|
||||||
|
|
||||||
|
if (video is JSVideoDetails) {
|
||||||
val me = this;
|
val me = this;
|
||||||
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -1267,8 +1276,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
val chapters = null ?: StatePlatform.instance.getContentChapters(video.url);
|
val chapters = null ?: StatePlatform.instance.getContentChapters(video.url);
|
||||||
_player.setChapters(chapters);
|
_player.setChapters(chapters);
|
||||||
_cast.setChapters(chapters);
|
_cast.setChapters(chapters);
|
||||||
}
|
} catch (ex: Throwable) {
|
||||||
catch(ex: Throwable) {
|
|
||||||
Logger.e(TAG, "Failed to get chapters", ex);
|
Logger.e(TAG, "Failed to get chapters", ex);
|
||||||
_player.setChapters(null);
|
_player.setChapters(null);
|
||||||
_cast.setChapters(null);
|
_cast.setChapters(null);
|
||||||
|
@ -1278,7 +1286,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if(!StateApp.instance.privateMode) {
|
if (!StateApp.instance.privateMode) {
|
||||||
val stopwatch = com.futo.platformplayer.debug.Stopwatch()
|
val stopwatch = com.futo.platformplayer.debug.Stopwatch()
|
||||||
var tracker = video.getPlaybackTracker()
|
var tracker = video.getPlaybackTracker()
|
||||||
Logger.i(TAG, "video.getPlaybackTracker took ${stopwatch.elapsedMs}ms")
|
Logger.i(TAG, "video.getPlaybackTracker took ${stopwatch.elapsedMs}ms")
|
||||||
|
@ -1294,17 +1302,22 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
if (me.video == video)
|
if (me.video == video)
|
||||||
me._playbackTracker = tracker;
|
me._playbackTracker = tracker;
|
||||||
}
|
} else if (me.video == video)
|
||||||
else if(me.video == video)
|
|
||||||
me._playbackTracker = null;
|
me._playbackTracker = null;
|
||||||
}
|
} catch (ex: Throwable) {
|
||||||
catch(ex: Throwable) {
|
|
||||||
Logger.e(TAG, "Playback tracker failed", ex);
|
Logger.e(TAG, "Playback tracker failed", ex);
|
||||||
if(me.video?.isLive == true) withContext(Dispatchers.Main) {
|
if (me.video?.isLive == true) withContext(Dispatchers.Main) {
|
||||||
UIDialogs.toast(context, context.getString(R.string.failed_to_get_playback_tracker));
|
UIDialogs.toast(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.failed_to_get_playback_tracker)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
else withContext(Dispatchers.Main) {
|
else withContext(Dispatchers.Main) {
|
||||||
UIDialogs.showGeneralErrorDialog(context, context.getString(R.string.failed_to_get_playback_tracker), ex);
|
UIDialogs.showGeneralErrorDialog(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.failed_to_get_playback_tracker),
|
||||||
|
ex
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1321,8 +1334,11 @@ class VideoDetailView : ConstraintLayout {
|
||||||
if (Settings.instance.comments.recommendationsDefault && !Settings.instance.comments.hideRecommendations) {
|
if (Settings.instance.comments.recommendationsDefault && !Settings.instance.comments.hideRecommendations) {
|
||||||
setTabIndex(2, true)
|
setTabIndex(2, true)
|
||||||
} else {
|
} else {
|
||||||
when(Settings.instance.comments.defaultCommentSection) {
|
when (Settings.instance.comments.defaultCommentSection) {
|
||||||
0 -> if(Settings.instance.other.polycentricEnabled) setTabIndex(0, true) else setTabIndex(1, true);
|
0 -> if (Settings.instance.other.polycentricEnabled) setTabIndex(
|
||||||
|
0,
|
||||||
|
true
|
||||||
|
) else setTabIndex(1, true);
|
||||||
1 -> setTabIndex(1, true);
|
1 -> setTabIndex(1, true);
|
||||||
2 -> setTabIndex(StateMeta.instance.getLastCommentSection(), true)
|
2 -> setTabIndex(StateMeta.instance.getLastCommentSection(), true)
|
||||||
}
|
}
|
||||||
|
@ -1332,9 +1348,16 @@ class VideoDetailView : ConstraintLayout {
|
||||||
//UI
|
//UI
|
||||||
_title.text = video.name;
|
_title.text = video.name;
|
||||||
_channelName.text = video.author.name;
|
_channelName.text = video.author.name;
|
||||||
if(video.author.subscribers != null) {
|
if (video.author.subscribers != null) {
|
||||||
_channelMeta.text = if((video.author.subscribers ?: 0) > 0) video.author.subscribers!!.toHumanNumber() + " " + context.getString(R.string.subscribers) else "";
|
_channelMeta.text = if ((video.author.subscribers
|
||||||
(_channelName.layoutParams as MarginLayoutParams).setMargins(0, (DP_5 * -1).toInt(), 0, 0);
|
?: 0) > 0
|
||||||
|
) video.author.subscribers!!.toHumanNumber() + " " + context.getString(R.string.subscribers) else "";
|
||||||
|
(_channelName.layoutParams as MarginLayoutParams).setMargins(
|
||||||
|
0,
|
||||||
|
(DP_5 * -1).toInt(),
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
_channelMeta.text = "";
|
_channelMeta.text = "";
|
||||||
(_channelName.layoutParams as MarginLayoutParams).setMargins(0, (DP_2).toInt(), 0, 0);
|
(_channelName.layoutParams as MarginLayoutParams).setMargins(0, (DP_2).toInt(), 0, 0);
|
||||||
|
@ -1342,7 +1365,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
|
|
||||||
video.author.let {
|
video.author.let {
|
||||||
if(it is PlatformAuthorMembershipLink && !it.membershipUrl.isNullOrEmpty())
|
if (it is PlatformAuthorMembershipLink && !it.membershipUrl.isNullOrEmpty())
|
||||||
_monetization.setPlatformMembership(video.id.pluginId, it.membershipUrl);
|
_monetization.setPlatformMembership(video.id.pluginId, it.membershipUrl);
|
||||||
else
|
else
|
||||||
_monetization.setPlatformMembership(null, null);
|
_monetization.setPlatformMembership(null, null);
|
||||||
|
@ -1356,7 +1379,8 @@ class VideoDetailView : ConstraintLayout {
|
||||||
_creatorThumbnail.setThumbnail(video.author.thumbnail, false);
|
_creatorThumbnail.setThumbnail(video.author.thumbnail, false);
|
||||||
|
|
||||||
|
|
||||||
val cachedPolycentricProfile = PolycentricCache.instance.getCachedProfile(video.author.url, true);
|
val cachedPolycentricProfile =
|
||||||
|
PolycentricCache.instance.getCachedProfile(video.author.url, true);
|
||||||
if (cachedPolycentricProfile != null) {
|
if (cachedPolycentricProfile != null) {
|
||||||
setPolycentricProfile(cachedPolycentricProfile, animate = false);
|
setPolycentricProfile(cachedPolycentricProfile, animate = false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1365,13 +1389,19 @@ class VideoDetailView : ConstraintLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
_platform.setPlatformFromClientID(video.id.pluginId);
|
_platform.setPlatformFromClientID(video.id.pluginId);
|
||||||
val subTitleSegments : ArrayList<String> = ArrayList();
|
val subTitleSegments: ArrayList<String> = ArrayList();
|
||||||
if(video.viewCount > 0)
|
if (video.viewCount > 0)
|
||||||
subTitleSegments.add("${video.viewCount.toHumanNumber()} ${if(video.isLive) context.getString(R.string.watching_now) else context.getString(R.string.views)}");
|
subTitleSegments.add(
|
||||||
if(video.datetime != null) {
|
"${video.viewCount.toHumanNumber()} ${
|
||||||
|
if (video.isLive) context.getString(
|
||||||
|
R.string.watching_now
|
||||||
|
) else context.getString(R.string.views)
|
||||||
|
}"
|
||||||
|
);
|
||||||
|
if (video.datetime != null) {
|
||||||
val diff = video.datetime?.getNowDiffSeconds() ?: 0;
|
val diff = video.datetime?.getNowDiffSeconds() ?: 0;
|
||||||
val ago = video.datetime?.toHumanNowDiffString(true)
|
val ago = video.datetime?.toHumanNowDiffString(true)
|
||||||
if(diff >= 0)
|
if (diff >= 0)
|
||||||
subTitleSegments.add("${ago} ago");
|
subTitleSegments.add("${ago} ago");
|
||||||
else
|
else
|
||||||
subTitleSegments.add("available in ${ago}");
|
subTitleSegments.add("available in ${ago}");
|
||||||
|
@ -1384,20 +1414,27 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val queryReferencesResponse = ApiMethods.getQueryReferences(PolycentricCache.SERVER, ref, null,null,
|
val queryReferencesResponse = ApiMethods.getQueryReferences(
|
||||||
|
PolycentricCache.SERVER, ref, null, null,
|
||||||
arrayListOf(
|
arrayListOf(
|
||||||
Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder().setFromType(ContentType.OPINION.value).setValue(
|
Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder()
|
||||||
ByteString.copyFrom(Opinion.like.data)).build(),
|
.setFromType(ContentType.OPINION.value).setValue(
|
||||||
Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder().setFromType(ContentType.OPINION.value).setValue(
|
ByteString.copyFrom(Opinion.like.data)
|
||||||
ByteString.copyFrom(Opinion.dislike.data)).build()
|
).build(),
|
||||||
|
Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder()
|
||||||
|
.setFromType(ContentType.OPINION.value).setValue(
|
||||||
|
ByteString.copyFrom(Opinion.dislike.data)
|
||||||
|
).build()
|
||||||
),
|
),
|
||||||
extraByteReferences = listOfNotNull(extraBytesRef)
|
extraByteReferences = listOfNotNull(extraBytesRef)
|
||||||
);
|
);
|
||||||
|
|
||||||
val likes = queryReferencesResponse.countsList[0];
|
val likes = queryReferencesResponse.countsList[0];
|
||||||
val dislikes = queryReferencesResponse.countsList[1];
|
val dislikes = queryReferencesResponse.countsList[1];
|
||||||
val hasLiked = StatePolycentric.instance.hasLiked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasLiked(it) } ?: false*/;
|
val hasLiked =
|
||||||
val hasDisliked = StatePolycentric.instance.hasDisliked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasDisliked(it) } ?: false*/;
|
StatePolycentric.instance.hasLiked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasLiked(it) } ?: false*/;
|
||||||
|
val hasDisliked =
|
||||||
|
StatePolycentric.instance.hasDisliked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasDisliked(it) } ?: false*/;
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
_rating.visibility = View.VISIBLE;
|
_rating.visibility = View.VISIBLE;
|
||||||
|
@ -1421,7 +1458,11 @@ class VideoDetailView : ConstraintLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatePolycentric.instance.updateLikeMap(ref, args.hasLiked, args.hasDisliked)
|
StatePolycentric.instance.updateLikeMap(
|
||||||
|
ref,
|
||||||
|
args.hasLiked,
|
||||||
|
args.hasDisliked
|
||||||
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -1443,6 +1484,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
_textDislikes.visibility = View.VISIBLE;
|
_textDislikes.visibility = View.VISIBLE;
|
||||||
_textDislikes.text = r.dislikes.toHumanNumber();
|
_textDislikes.text = r.dislikes.toHumanNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
is RatingLikes -> {
|
is RatingLikes -> {
|
||||||
val r = video.rating as RatingLikes;
|
val r = video.rating as RatingLikes;
|
||||||
_layoutRating.visibility = View.VISIBLE;
|
_layoutRating.visibility = View.VISIBLE;
|
||||||
|
@ -1454,6 +1496,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
_imageDislikeIcon.visibility = View.GONE;
|
_imageDislikeIcon.visibility = View.GONE;
|
||||||
_textDislikes.visibility = View.GONE;
|
_textDislikes.visibility = View.GONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
_layoutRating.visibility = View.GONE;
|
_layoutRating.visibility = View.GONE;
|
||||||
}
|
}
|
||||||
|
@ -1465,6 +1508,7 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
|
|
||||||
//Set Mediasource
|
//Set Mediasource
|
||||||
|
|
||||||
val toResume = _videoResumePositionMilliseconds;
|
val toResume = _videoResumePositionMilliseconds;
|
||||||
|
@ -1481,9 +1525,22 @@ class VideoDetailView : ConstraintLayout {
|
||||||
val historyItem = getHistoryIndex(videoDetail) ?: return@launch;
|
val historyItem = getHistoryIndex(videoDetail) ?: return@launch;
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
_historicalPosition = StateHistory.instance.updateHistoryPosition(video, historyItem,false, (toResume.toFloat() / 1000.0f).toLong(), null, true);
|
_historicalPosition = StateHistory.instance.updateHistoryPosition(
|
||||||
Logger.i(TAG, "Historical position: $_historicalPosition, last position: $lastPositionMilliseconds");
|
video,
|
||||||
if (_historicalPosition > 60 && video.duration - _historicalPosition > 5 && Math.abs(_historicalPosition - lastPositionMilliseconds / 1000) > 5.0) {
|
historyItem,
|
||||||
|
false,
|
||||||
|
(toResume.toFloat() / 1000.0f).toLong(),
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Logger.i(
|
||||||
|
TAG,
|
||||||
|
"Historical position: $_historicalPosition, last position: $lastPositionMilliseconds"
|
||||||
|
);
|
||||||
|
if (_historicalPosition > 60 && video.duration - _historicalPosition > 5 && Math.abs(
|
||||||
|
_historicalPosition - lastPositionMilliseconds / 1000
|
||||||
|
) > 5.0
|
||||||
|
) {
|
||||||
_layoutResume.visibility = View.VISIBLE;
|
_layoutResume.visibility = View.VISIBLE;
|
||||||
_textResume.text = "Resume at ${_historicalPosition.toHumanTime(false)}";
|
_textResume.text = "Resume at ${_historicalPosition.toHumanTime(false)}";
|
||||||
|
|
||||||
|
@ -1509,10 +1566,10 @@ class VideoDetailView : ConstraintLayout {
|
||||||
|
|
||||||
_liveChat?.stop();
|
_liveChat?.stop();
|
||||||
_liveChat = null;
|
_liveChat = null;
|
||||||
if(video.isLive && video.live != null) {
|
if (video.isLive && video.live != null) {
|
||||||
loadLiveChat(video);
|
loadLiveChat(video);
|
||||||
}
|
}
|
||||||
if(video.isLive && video.live == null && !video.video.videoSources.any())
|
if (video.isLive && video.live == null && !video.video.videoSources.any())
|
||||||
startLiveTry(video);
|
startLiveTry(video);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2241,14 +2298,14 @@ class VideoDetailView : ConstraintLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isLandscapeVideo(): Boolean {
|
fun isLandscapeVideo(): Boolean? {
|
||||||
var videoSourceWidth = _player.exoPlayer?.player?.videoSize?.width
|
var videoSourceWidth = _player.exoPlayer?.player?.videoSize?.width
|
||||||
var videoSourceHeight = _player.exoPlayer?.player?.videoSize?.height
|
var videoSourceHeight = _player.exoPlayer?.player?.videoSize?.height
|
||||||
|
|
||||||
return if (videoSourceHeight != null && videoSourceWidth != null) {
|
return if (videoSourceWidth == null || videoSourceHeight == null || videoSourceWidth == 0 || videoSourceHeight == 0){
|
||||||
videoSourceWidth > videoSourceHeight
|
null
|
||||||
} else {
|
} else{
|
||||||
true
|
videoSourceWidth >= videoSourceHeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue