clamp aspect ratio for embedded player
This commit is contained in:
parent
4d3eff9630
commit
f11d35818f
|
@ -0,0 +1,4 @@
|
||||||
|
kotlin version: 2.0.20-Beta2
|
||||||
|
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
|
||||||
|
1. Kotlin compile daemon is ready
|
||||||
|
|
|
@ -72,7 +72,7 @@ androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
||||||
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
||||||
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||||
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
newplayer = { group = "com.github.theScrabi", name = "NewPlayer", version.ref = "newplayer" }
|
newplayer = { group = "com.github.theScrabi.NewPlayer", name = "new-player", version.ref = "newplayer" }
|
||||||
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
|
|
|
@ -20,14 +20,31 @@
|
||||||
|
|
||||||
package net.newpipe.newplayer
|
package net.newpipe.newplayer
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.fragment.app.FragmentContainer
|
||||||
|
import androidx.fragment.app.FragmentContainerView
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import net.newpipe.newplayer.internal.VideoPlayerFragment
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VideoPlayerView : FrameLayout {
|
class VideoPlayerView : FrameLayout {
|
||||||
|
|
||||||
|
val videoPlayerFragment:VideoPlayerFragment
|
||||||
|
|
||||||
|
var maxLayoutRatio: Float
|
||||||
|
get() = videoPlayerFragment.maxLayoutRatio
|
||||||
|
set(value) {videoPlayerFragment.maxLayoutRatio=value}
|
||||||
|
|
||||||
|
|
||||||
|
var minLayoutRatio: Float
|
||||||
|
get() = videoPlayerFragment.minLayoutRatio
|
||||||
|
set(value) {videoPlayerFragment.maxLayoutRatio = value}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
constructor(
|
constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -35,5 +52,17 @@ class VideoPlayerView : FrameLayout {
|
||||||
defStyleAttr: Int = 0
|
defStyleAttr: Int = 0
|
||||||
) : super(context, attrs, defStyleAttr) {
|
) : super(context, attrs, defStyleAttr) {
|
||||||
val view = LayoutInflater.from(context).inflate(R.layout.video_player_view, this)
|
val view = LayoutInflater.from(context).inflate(R.layout.video_player_view, this)
|
||||||
|
|
||||||
|
videoPlayerFragment = VideoPlayerFragment()
|
||||||
|
when (context) {
|
||||||
|
is AppCompatActivity -> {
|
||||||
|
context.supportFragmentManager.beginTransaction()
|
||||||
|
.add(R.id.video_player_fragment_container, videoPlayerFragment).commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
throw Exception("The context that should host the NewPlayer Embedded VideoPlayerView is not an AppCompatActivity: $context")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
package net.newpipe.newplayer.internal
|
package net.newpipe.newplayer.internal
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -42,7 +43,36 @@ import net.newpipe.newplayer.internal.ui.theme.VideoPlayerTheme
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VideoPlayerFragment() : Fragment() {
|
class VideoPlayerFragment() : Fragment() {
|
||||||
|
|
||||||
|
private val TAG = "VideoPlayerFragment"
|
||||||
private val viewModel: VideoPlayerViewModel by viewModels<VideoPlayerViewModelImpl>()
|
private val viewModel: VideoPlayerViewModel by viewModels<VideoPlayerViewModelImpl>()
|
||||||
|
private var currentVideoRatio = 0F
|
||||||
|
private lateinit var composeView: ComposeView
|
||||||
|
|
||||||
|
var minLayoutRatio = 4F / 3F
|
||||||
|
set(value) {
|
||||||
|
if (value <= 0 && maxLayoutRatio < minLayoutRatio)
|
||||||
|
Log.e(
|
||||||
|
TAG,
|
||||||
|
"minLayoutRatio can not be 0 or smaller or bigger then maxLayoutRatio. Ignore: $value"
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
field = value
|
||||||
|
updateViewRatio()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxLayoutRatio = 16F / 9F
|
||||||
|
set(value) {
|
||||||
|
if (value <= 0 && value < minLayoutRatio)
|
||||||
|
Log.e(
|
||||||
|
TAG,
|
||||||
|
"maxLayoutRatio can not be 0 smaller ans smaller then minLayoutRatio. Ignore: $value"
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
field = value
|
||||||
|
updateViewRatio()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
@ -51,16 +81,16 @@ class VideoPlayerFragment() : Fragment() {
|
||||||
): View? {
|
): View? {
|
||||||
val window = activity?.window!!
|
val window = activity?.window!!
|
||||||
val insetsController = WindowCompat.getInsetsController(window, window.decorView)
|
val insetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||||
insetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
insetsController.systemBarsBehavior =
|
||||||
|
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
|
|
||||||
val view = inflater.inflate(R.layout.video_player_framgent, container, false)
|
val view = inflater.inflate(R.layout.video_player_framgent, container, false)
|
||||||
val composeView = view.findViewById<ComposeView>(R.id.player_copose_view)
|
composeView = view.findViewById(R.id.player_copose_view)
|
||||||
|
|
||||||
viewModel.listener = object : VideoPlayerViewModel.Listener {
|
viewModel.listener = object : VideoPlayerViewModel.Listener {
|
||||||
override fun requestUpdateLayoutRatio(ratio: Float) {
|
override fun requestUpdateLayoutRatio(videoRatio: Float) {
|
||||||
composeView.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
currentVideoRatio = videoRatio
|
||||||
dimensionRatio = "$ratio:1"
|
updateViewRatio()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,4 +107,11 @@ class VideoPlayerFragment() : Fragment() {
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateViewRatio() {
|
||||||
|
composeView.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
val ratio = currentVideoRatio.coerceIn(minLayoutRatio, maxLayoutRatio)
|
||||||
|
dimensionRatio = "$ratio:1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -166,7 +166,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
player.prepare()
|
player.prepare()
|
||||||
}
|
}
|
||||||
|
|
||||||
player.setMediaItem(MediaItem.fromUri(app.getString(R.string.ccc_chromebooks_video)))
|
player.setMediaItem(MediaItem.fromUri(app.getString(R.string.portrait_video_example)))
|
||||||
player.playWhenReady = true
|
player.playWhenReady = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/video_player_fragment"
|
android:id="@+id/video_player_fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="50dp"
|
android:minHeight="50dp" />
|
||||||
android:name="net.newpipe.newplayer.internal.VideoPlayerFragment" />
|
|
|
@ -23,4 +23,5 @@
|
||||||
<string name="ccc_6502_video">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/mp4-h264-HQ/27c3-4159-en-reverse_engineering_mos_6502.mp4</string>
|
<string name="ccc_6502_video">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/mp4-h264-HQ/27c3-4159-en-reverse_engineering_mos_6502.mp4</string>
|
||||||
<string name="ccc_6502_audio">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/ogg-audio-only/27c3-4159-en-reverse_engineering_mos_6502.ogg</string>
|
<string name="ccc_6502_audio">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/ogg-audio-only/27c3-4159-en-reverse_engineering_mos_6502.ogg</string>
|
||||||
<string name="ccc_chromebooks_video">https://ftp.fau.de/cdn.media.ccc.de/congress/2023/h264-hd/37c3-11929-eng-deu-swe-Turning_Chromebooks_into_regular_laptops_hd.mp4</string>
|
<string name="ccc_chromebooks_video">https://ftp.fau.de/cdn.media.ccc.de/congress/2023/h264-hd/37c3-11929-eng-deu-swe-Turning_Chromebooks_into_regular_laptops_hd.mp4</string>
|
||||||
|
<string name="portrait_video_example">https://videos.pexels.com/video-files/5512609/5512609-hd_1080_1920_25fps.mp4</string>
|
||||||
</resources>
|
</resources>
|
|
@ -27,6 +27,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import net.newpipe.newplayer.VideoPlayerView
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
@ -35,6 +36,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
val video_view = findViewById<VideoPlayerView>(R.id.new_player_video_view)
|
||||||
|
|
||||||
|
video_view.minLayoutRatio
|
||||||
|
|
||||||
//TODO: This is a dirty hack. Fix this later on
|
//TODO: This is a dirty hack. Fix this later on
|
||||||
if (getResources().configuration.orientation != Configuration.ORIENTATION_LANDSCAPE) {
|
if (getResources().configuration.orientation != Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
|
Loading…
Reference in New Issue