Skip to content

Commit

Permalink
feat (player): optional rotate button in player and setting to enable…
Browse files Browse the repository at this point in the history
… auto rotate based on video orientation (#813)

Co-authored-by: coxju <coxju>
  • Loading branch information
coxju authored Dec 19, 2023
1 parent db91552 commit a5f7920
Showing 8 changed files with 145 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -75,6 +75,7 @@ private const val SUBTITLE_DELAY_BUNDLE_KEY = "subtitle_delay"

// All the UI Logic for the player
open class FullScreenPlayer : AbstractPlayerFragment() {
private var isVerticalOrientation: Boolean = false
protected open var lockRotation = true
protected open var isFullScreenPlayer = true
protected open var isTv = false
@@ -111,6 +112,8 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
protected var playerResizeEnabled = false
protected var doubleTapEnabled = false
protected var doubleTapPauseEnabled = true
protected var playerRotateEnabled = false
protected var autoPlayerRotateEnabled = false

protected var subtitleDelay
set(value) = try {
@@ -286,31 +289,78 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
player.getCurrentPreferredSubtitle() == null
}

private fun restoreOrientationWithSensor(activity: Activity){
val currentOrientation = activity.resources.configuration.orientation
var orientation = 0
when (currentOrientation) {
Configuration.ORIENTATION_LANDSCAPE ->
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE

Configuration.ORIENTATION_SQUARE, Configuration.ORIENTATION_UNDEFINED ->
orientation = dynamicOrientation()

Configuration.ORIENTATION_PORTRAIT ->
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
}
activity.requestedOrientation = orientation
}

private fun toggleOrientationWithSensor(activity: Activity){
val currentOrientation = activity.resources.configuration.orientation
var orientation = 0
when (currentOrientation) {
Configuration.ORIENTATION_LANDSCAPE ->
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT

Configuration.ORIENTATION_SQUARE, Configuration.ORIENTATION_UNDEFINED ->
orientation = dynamicOrientation()

Configuration.ORIENTATION_PORTRAIT ->
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
activity.requestedOrientation = orientation
}

open fun lockOrientation(activity: Activity) {
val display =
(activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
val rotation = display.rotation
val currentOrientation = activity.resources.configuration.orientation
var orientation = 0
when (currentOrientation) {
Configuration.ORIENTATION_LANDSCAPE -> orientation =
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE else ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE

Configuration.ORIENTATION_SQUARE, Configuration.ORIENTATION_UNDEFINED, Configuration.ORIENTATION_PORTRAIT -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
//Configuration.ORIENTATION_PORTRAIT -> orientation =
// if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
Configuration.ORIENTATION_LANDSCAPE ->
orientation =
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
else
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE

Configuration.ORIENTATION_SQUARE, Configuration.ORIENTATION_UNDEFINED ->
orientation = dynamicOrientation()

Configuration.ORIENTATION_PORTRAIT ->
orientation =
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
else
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
}
activity.requestedOrientation = orientation
}

private fun updateOrientation() {
private fun updateOrientation(ignoreDynamicOrientation: Boolean = false) {
activity?.apply {
if(lockRotation) {
if(isLocked) {
lockOrientation(this)
}
else {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
if(ignoreDynamicOrientation){
// restore when lock is disabled
restoreOrientationWithSensor(this)
} else {
this.requestedOrientation = dynamicOrientation()
}
}
}
}
@@ -584,7 +634,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
}

isLocked = !isLocked
updateOrientation()
updateOrientation(true) // set true to ignore auto rotate to stay in current orientation

if (isLocked && isShowing) {
playerBinding?.playerHolder?.postDelayed({
@@ -1326,6 +1376,14 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
ctx.getString(R.string.playback_speed_enabled_key),
false
)
playerRotateEnabled = settingsManager.getBoolean(
ctx.getString(R.string.rotate_video_key),
false
)
autoPlayerRotateEnabled = settingsManager.getBoolean(
ctx.getString(R.string.auto_rotate_video_key),
false
)
playerResizeEnabled =
settingsManager.getBoolean(
ctx.getString(R.string.player_resize_enabled_key),
@@ -1362,6 +1420,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
playerBinding?.apply {
playerSpeedBtt.isVisible = playBackSpeedEnabled
playerResizeBtt.isVisible = playerResizeEnabled
playerRotateBtt.isVisible = playerRotateEnabled
}
} catch (e: Exception) {
logError(e)
@@ -1376,6 +1435,11 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
player.handleEvent(CSPlayerEvent.SkipCurrentChapter)
}

playerRotateBtt.setOnClickListener {
autoHide()
toggleRotate()
}

// init clicks
playerResizeBtt.setOnClickListener {
autoHide()
@@ -1481,4 +1545,28 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
logError(e)
}
}

@SuppressLint("SourceLockedOrientationActivity")
private fun toggleRotate() {
activity?.let {
toggleOrientationWithSensor(it)
}
}

override fun playerDimensionsLoaded(width: Int, height: Int) {
isVerticalOrientation = height > width
updateOrientation()
}

private fun dynamicOrientation(): Int {
return if (autoPlayerRotateEnabled) {
if (isVerticalOrientation) {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
} else {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
} else {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE // default orientation
}
}
}
Original file line number Diff line number Diff line change
@@ -1237,6 +1237,7 @@ class GeneratorPlayer : FullScreenPlayer() {
}

override fun playerDimensionsLoaded(width: Int, height: Int) {
super.playerDimensionsLoaded(width, height)
setPlayerDimen(width to height)
}

10 changes: 10 additions & 0 deletions app/src/main/res/drawable/screen_rotation.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/white">
<path
android:fillColor="@android:color/white"
android:pathData="M496,778L182,464Q159,441 159,410Q159,379 182,356L356,182Q379,159 410,159Q441,159 464,182L778,496Q801,519 801,550Q801,581 778,604L604,778Q581,801 550,801Q519,801 496,778ZM550,720Q550,720 550,720Q550,720 550,720L720,550Q720,550 720,550Q720,550 720,550L410,240Q410,240 410,240Q410,240 410,240L240,410Q240,410 240,410Q240,410 240,410L550,720ZM480,960Q381,960 293.5,922.5Q206,885 140.5,819.5Q75,754 37.5,666.5Q0,579 0,480L80,480Q80,551 104,616Q128,681 170.5,733Q213,785 272,821.5Q331,858 401,873L296,768L352,712L588,948Q562,954 534.5,957Q507,960 480,960ZM880,480Q880,409 856,344Q832,279 789.5,227Q747,175 688,138.5Q629,102 559,87L664,192L608,248L372,12Q398,6 425.5,3Q453,0 480,0Q579,0 666.5,37.5Q754,75 819.5,140.5Q885,206 922.5,293.5Q960,381 960,480L880,480ZM480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
11 changes: 10 additions & 1 deletion app/src/main/res/layout/player_custom_layout.xml
Original file line number Diff line number Diff line change
@@ -550,10 +550,19 @@
android:orientation="horizontal">

<com.google.android.material.button.MaterialButton
android:id="@+id/player_resize_btt"
android:id="@+id/player_rotate_btt"
style="@style/VideoButton"
android:nextFocusLeft="@id/player_lock"

android:nextFocusRight="@id/player_resize_btt"
android:text="@string/rotate_video"
app:icon="@drawable/screen_rotation" />

<com.google.android.material.button.MaterialButton
android:id="@+id/player_resize_btt"
style="@style/VideoButton"
android:nextFocusLeft="@id/player_rotate_btt"

android:nextFocusRight="@id/player_speed_btt"
android:text="@string/video_aspect_ratio_resize"
app:icon="@drawable/ic_baseline_aspect_ratio_24" />
5 changes: 5 additions & 0 deletions app/src/main/res/layout/player_custom_layout_tv.xml
Original file line number Diff line number Diff line change
@@ -638,6 +638,11 @@
app:icon="@drawable/video_locked" />
</FrameLayout>

<com.google.android.material.button.MaterialButton
android:id="@+id/player_rotate_btt"
style="@style/VideoButton"
android:visibility="gone"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/player_skip_op"
style="@style/VideoButtonTV"
4 changes: 4 additions & 0 deletions app/src/main/res/layout/trailer_custom_layout.xml
Original file line number Diff line number Diff line change
@@ -534,6 +534,10 @@
android:paddingTop="10dp"
android:paddingBottom="10dp">

<com.google.android.material.button.MaterialButton
android:id="@+id/player_rotate_btt"
style="@style/VideoButton"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/player_lock"
style="@style/VideoButton"
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -734,4 +734,10 @@
<string name="logged_account" formatted="true">Logged in as %s</string>
<string name="skip_startup_account_select_pref">Skip account selection at startup</string>
<string name="use_default_account">Use Default Account</string>
<string name="rotate_video">Rotate</string>
<string name="rotate_video_key">rotate_video_key</string>
<string name="rotate_video_desc">Display a toggle button for screen orientation</string>
<string name="auto_rotate_video_key">auto_rotate_video_key</string>
<string name="auto_rotate_video_desc">Enable automatic switching of screen orientation based on video orientation</string>
<string name="auto_rotate_video">Auto rotate</string>
</resources>
12 changes: 12 additions & 0 deletions app/src/main/res/xml/settings_player.xml
Original file line number Diff line number Diff line change
@@ -86,6 +86,18 @@
app:defaultValue="true"
android:summary="@string/enable_skip_op_from_database_des"
app:key="@string/enable_skip_op_from_database" />
<SwitchPreference
android:icon="@drawable/screen_rotation"
android:title="@string/rotate_video"
app:defaultValue="false"
android:summary="@string/rotate_video_desc"
app:key="@string/rotate_video_key" />
<SwitchPreference
android:icon="@drawable/screen_rotation"
android:title="@string/auto_rotate_video"
app:defaultValue="false"
android:summary="@string/auto_rotate_video_desc"
app:key="@string/auto_rotate_video_key" />
</PreferenceCategory>

<PreferenceCategory

0 comments on commit a5f7920

Please sign in to comment.