Integrated JWPlayer
implemented playerView on both fragments theme 1 and theme 2 Full screen activity LiveStreamPlayerActivity
This commit is contained in:
@@ -47,6 +47,9 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
ext.jwPlayerVersion = '4.6.0'
|
||||
ext.exoplayerVersion = '2.19.1'
|
||||
|
||||
dependencies {
|
||||
implementation "com.airbnb.android:lottie:6.4.0"
|
||||
implementation "androidx.core:core-splashscreen:1.0.1"
|
||||
@@ -74,6 +77,10 @@ dependencies {
|
||||
// circle image view
|
||||
implementation 'de.hdodenhof:circleimageview:3.1.0'
|
||||
|
||||
// jwplayer
|
||||
implementation "com.jwplayer:jwplayer-core:$jwPlayerVersion"
|
||||
implementation "com.jwplayer:jwplayer-common:$jwPlayerVersion"
|
||||
|
||||
implementation libs.androidx.core.ktx
|
||||
implementation libs.androidx.appcompat
|
||||
implementation libs.material
|
||||
|
||||
@@ -15,11 +15,19 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Woka"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".players.LiveStreamPlayerActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:exported="false"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:theme="@style/FullScreenTheme" />
|
||||
<activity
|
||||
android:name=".home.ExploreWokaActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/TransparentActivity"
|
||||
android:screenOrientation="portrait"/>
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentActivity" />
|
||||
<activity
|
||||
android:name=".home.HomeActivity"
|
||||
android:exported="false"
|
||||
|
||||
@@ -26,6 +26,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.bumptech.glide.Glide
|
||||
import com.jwplayer.pub.api.license.LicenseUtil
|
||||
import com.woka.BuildConfig
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
@@ -128,6 +129,8 @@ class HomeActivity : WokaBaseActivity(),
|
||||
if (userPrefs?.userLiveData?.isInitialized == false){
|
||||
userPrefs?.loadUserData()
|
||||
}
|
||||
|
||||
LicenseUtil().setLicenseKey(this, "LkYoNusv+gSIVJIrXa5Bf59iBNlUMxeg82PM/l8JWk+cD4BE")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.woka.home.fragments
|
||||
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -8,16 +7,17 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_TIME_TICK
|
||||
import android.content.IntentFilter
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.databinding.FragmentHome1Binding
|
||||
@@ -25,11 +25,13 @@ import com.woka.home.HomeViewModel
|
||||
import com.woka.home.TimePeriod
|
||||
import com.woka.mvvm.userDataModels.UserDataResponse
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.players.LiveStreamPlayerActivity
|
||||
import com.woka.utils.UserType
|
||||
import com.woka.utils.hide
|
||||
import com.woka.utils.scaleAnimate
|
||||
import com.woka.utils.show
|
||||
|
||||
|
||||
class Home1Fragment : Fragment() {
|
||||
|
||||
private lateinit var binding: FragmentHome1Binding
|
||||
@@ -44,6 +46,8 @@ class Home1Fragment : Fragment() {
|
||||
private var star1Animator: ValueAnimator? = null
|
||||
private var star2Animator: ValueAnimator? = null
|
||||
|
||||
private lateinit var player: ExoPlayer
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -51,8 +55,11 @@ class Home1Fragment : Fragment() {
|
||||
binding = FragmentHome1Binding.inflate(inflater, container, false)
|
||||
activity?.let {
|
||||
viewModel = ViewModelProvider(it)[HomeViewModel::class.java]
|
||||
player = ExoPlayer.Builder(it).build()
|
||||
}
|
||||
|
||||
initPlayerView()
|
||||
|
||||
handleScaleAnimations()
|
||||
|
||||
updateBackground()
|
||||
@@ -77,6 +84,9 @@ class Home1Fragment : Fragment() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
handleAnimations()
|
||||
if (!player.isPlaying){
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
@@ -86,6 +96,26 @@ class Home1Fragment : Fragment() {
|
||||
if (cloud2Animator?.isRunning == true) cloud2Animator?.pause()
|
||||
if (star1Animator?.isRunning == true) star1Animator?.pause()
|
||||
if (star2Animator?.isRunning == true) star2Animator?.pause()
|
||||
|
||||
if (player.isPlaying) player.pause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
player.release()
|
||||
}
|
||||
|
||||
private fun initPlayerView() {
|
||||
binding.playerView.player = player
|
||||
|
||||
binding.playerView.useController = false
|
||||
player.volume = 0f
|
||||
|
||||
val videoUri = Uri.parse("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
val mediaItem = MediaItem.fromUri(videoUri)
|
||||
player.setMediaItem(mediaItem)
|
||||
player.playWhenReady = true
|
||||
player.prepare()
|
||||
}
|
||||
|
||||
private fun setObservers() {
|
||||
@@ -114,7 +144,11 @@ class Home1Fragment : Fragment() {
|
||||
|
||||
private fun clickEvents() {
|
||||
binding.apply {
|
||||
|
||||
blackImage.setOnClickListener {
|
||||
activity?.let {
|
||||
startActivity(Intent(it, LiveStreamPlayerActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +169,7 @@ class Home1Fragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleScaleAnimations(){
|
||||
private fun handleScaleAnimations() {
|
||||
binding.apply {
|
||||
webSeriesLl.post {
|
||||
webSeriesLl.scaleAnimate()
|
||||
@@ -164,67 +198,69 @@ class Home1Fragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun handleAnimations() {
|
||||
if (tvAnimator == null) {
|
||||
binding.tvView.post {
|
||||
val endMargin: Float =
|
||||
25f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
tvAnimator = ObjectAnimator.ofFloat(
|
||||
binding.tvView,
|
||||
"translationX",
|
||||
resources.displayMetrics.widthPixels - binding.tvView.width - (2 * endMargin)
|
||||
).apply {
|
||||
duration = 12000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
synchronized(this){
|
||||
if (tvAnimator == null) {
|
||||
binding.tvView.post {
|
||||
val endMargin: Float =
|
||||
25f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
tvAnimator = ObjectAnimator.ofFloat(
|
||||
binding.tvView,
|
||||
"translationX",
|
||||
resources.displayMetrics.widthPixels - binding.tvView.width - (2 * endMargin)
|
||||
).apply {
|
||||
duration = 12000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
}
|
||||
}
|
||||
} else if (tvAnimator?.isPaused == true) {
|
||||
tvAnimator?.resume()
|
||||
}
|
||||
} else if (tvAnimator?.isPaused == true){
|
||||
tvAnimator?.resume()
|
||||
}
|
||||
|
||||
if (cloud1Animator == null) {
|
||||
binding.cloud1.post {
|
||||
val cloud1Width: Float =
|
||||
900f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
cloud1Animator = ObjectAnimator.ofFloat(
|
||||
binding.cloud1,
|
||||
"translationX",
|
||||
-cloud1Width + resources.displayMetrics.widthPixels
|
||||
).apply {
|
||||
duration = 120_000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
if (cloud1Animator == null) {
|
||||
binding.cloud1.post {
|
||||
val cloud1Width: Float =
|
||||
900f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
cloud1Animator = ObjectAnimator.ofFloat(
|
||||
binding.cloud1,
|
||||
"translationX",
|
||||
-cloud1Width + resources.displayMetrics.widthPixels
|
||||
).apply {
|
||||
duration = 120_000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
}
|
||||
}
|
||||
} else if (cloud1Animator?.isPaused == true) {
|
||||
cloud1Animator?.resume()
|
||||
}
|
||||
} else if (cloud1Animator?.isPaused == true){
|
||||
cloud1Animator?.resume()
|
||||
}
|
||||
|
||||
if (cloud2Animator == null) {
|
||||
binding.cloud2.post {
|
||||
val cloud2Width: Float =
|
||||
900f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
cloud2Animator = ObjectAnimator.ofFloat(
|
||||
binding.cloud2,
|
||||
"translationX",
|
||||
cloud2Width - resources.displayMetrics.widthPixels
|
||||
).apply {
|
||||
duration = 120_000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
if (cloud2Animator == null) {
|
||||
binding.cloud2.post {
|
||||
val cloud2Width: Float =
|
||||
900f * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
cloud2Animator = ObjectAnimator.ofFloat(
|
||||
binding.cloud2,
|
||||
"translationX",
|
||||
cloud2Width - resources.displayMetrics.widthPixels
|
||||
).apply {
|
||||
duration = 120_000
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
start()
|
||||
}
|
||||
}
|
||||
} else if (cloud2Animator?.isPaused == true) {
|
||||
cloud2Animator?.resume()
|
||||
}
|
||||
} else if (cloud2Animator?.isPaused == true) {
|
||||
cloud2Animator?.resume()
|
||||
}
|
||||
|
||||
handleNightAnimations()
|
||||
handleNightAnimations()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNightAnimations(){
|
||||
private fun handleNightAnimations() {
|
||||
if (currentBackground == TimePeriod.NIGHT && star1Animator == null) {
|
||||
binding.star1.post {
|
||||
star1Animator = ObjectAnimator.ofFloat(binding.star1, "alpha", 0.3f, 1f).apply {
|
||||
@@ -234,7 +270,7 @@ class Home1Fragment : Fragment() {
|
||||
start()
|
||||
}
|
||||
}
|
||||
} else if (star1Animator?.isPaused == true){
|
||||
} else if (star1Animator?.isPaused == true) {
|
||||
star1Animator?.resume()
|
||||
}
|
||||
|
||||
@@ -338,7 +374,9 @@ class Home1Fragment : Fragment() {
|
||||
binding.moon.show()
|
||||
|
||||
currentBackground = timePeriod
|
||||
handleNightAnimations()
|
||||
synchronized(this){
|
||||
handleNightAnimations()
|
||||
}
|
||||
|
||||
binding.grass.setImageResource(R.drawable.img_grass_n)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
package com.woka.home.fragments
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp
|
||||
import com.woka.databinding.FragmentHome2Binding
|
||||
import com.woka.home.HomeViewModel
|
||||
import com.woka.mvvm.userDataModels.UserDataResponse
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.players.LiveStreamPlayerActivity
|
||||
import com.woka.utils.UserType
|
||||
import com.woka.utils.toast
|
||||
|
||||
@@ -21,6 +26,8 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
private lateinit var viewModel: HomeViewModel
|
||||
|
||||
private lateinit var player: ExoPlayer
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -29,8 +36,11 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
activity?.let {
|
||||
viewModel = ViewModelProvider(it)[HomeViewModel::class.java]
|
||||
player = ExoPlayer.Builder(it).build()
|
||||
}
|
||||
|
||||
initPlayerView()
|
||||
|
||||
setObservers()
|
||||
|
||||
clickEvents()
|
||||
@@ -38,10 +48,41 @@ class Home2Fragment : Fragment() {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (!player.isPlaying){
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (player.isPlaying) player.pause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
player.release()
|
||||
}
|
||||
|
||||
private fun initPlayerView() {
|
||||
binding.playerView.player = player
|
||||
|
||||
binding.playerView.useController = false
|
||||
player.volume = 0f
|
||||
|
||||
val videoUri = Uri.parse("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
val mediaItem = MediaItem.fromUri(videoUri)
|
||||
player.setMediaItem(mediaItem)
|
||||
player.playWhenReady = true
|
||||
|
||||
player.prepare()
|
||||
}
|
||||
|
||||
private fun clickEvents(){
|
||||
binding.apply {
|
||||
webSeries.setOnClickListener {
|
||||
toast("toast")
|
||||
playerCard.setOnClickListener {
|
||||
startActivity(Intent(activity, LiveStreamPlayerActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
87
app/src/main/java/com/woka/players/KeepScreenOnHandler.kt
Normal file
87
app/src/main/java/com/woka/players/KeepScreenOnHandler.kt
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.woka.players
|
||||
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import com.jwplayer.pub.api.JWPlayer
|
||||
import com.jwplayer.pub.api.events.AdCompleteEvent
|
||||
import com.jwplayer.pub.api.events.AdErrorEvent
|
||||
import com.jwplayer.pub.api.events.AdPauseEvent
|
||||
import com.jwplayer.pub.api.events.AdPlayEvent
|
||||
import com.jwplayer.pub.api.events.AdSkippedEvent
|
||||
import com.jwplayer.pub.api.events.CompleteEvent
|
||||
import com.jwplayer.pub.api.events.ErrorEvent
|
||||
import com.jwplayer.pub.api.events.EventType
|
||||
import com.jwplayer.pub.api.events.PauseEvent
|
||||
import com.jwplayer.pub.api.events.PlayEvent
|
||||
import com.jwplayer.pub.api.events.listeners.AdvertisingEvents.OnAdCompleteListener
|
||||
import com.jwplayer.pub.api.events.listeners.AdvertisingEvents.OnAdErrorListener
|
||||
import com.jwplayer.pub.api.events.listeners.AdvertisingEvents.OnAdPauseListener
|
||||
import com.jwplayer.pub.api.events.listeners.AdvertisingEvents.OnAdPlayListener
|
||||
import com.jwplayer.pub.api.events.listeners.AdvertisingEvents.OnAdSkippedListener
|
||||
import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents
|
||||
import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents.OnPauseListener
|
||||
import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents.OnPlayListener
|
||||
|
||||
class KeepScreenOnHandler(player: JWPlayer, window: Window) : OnPlayListener,
|
||||
OnPauseListener, VideoPlayerEvents.OnCompleteListener, VideoPlayerEvents.OnErrorListener,
|
||||
OnAdPlayListener, OnAdPauseListener, OnAdCompleteListener, OnAdSkippedListener,
|
||||
OnAdErrorListener {
|
||||
|
||||
private val mWindow: Window
|
||||
|
||||
init {
|
||||
player.addListener(EventType.PLAY, this)
|
||||
player.addListener(EventType.PAUSE, this)
|
||||
player.addListener(EventType.COMPLETE, this)
|
||||
player.addListener(EventType.ERROR, this)
|
||||
player.addListener(EventType.AD_PLAY, this)
|
||||
player.addListener(EventType.AD_PAUSE, this)
|
||||
player.addListener(EventType.AD_COMPLETE, this)
|
||||
player.addListener(EventType.AD_ERROR, this)
|
||||
mWindow = window
|
||||
}
|
||||
|
||||
private fun updateWakeLock(enable: Boolean) {
|
||||
if (enable) {
|
||||
mWindow.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else {
|
||||
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(errorEvent: ErrorEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onAdPlay(adPlayEvent: AdPlayEvent) {
|
||||
updateWakeLock(true)
|
||||
}
|
||||
|
||||
override fun onAdPause(adPauseEvent: AdPauseEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onAdComplete(adCompleteEvent: AdCompleteEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onAdSkipped(adSkippedEvent: AdSkippedEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onAdError(adErrorEvent: AdErrorEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onComplete(completeEvent: CompleteEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onPause(pauseEvent: PauseEvent) {
|
||||
updateWakeLock(false)
|
||||
}
|
||||
|
||||
override fun onPlay(playEvent: PlayEvent) {
|
||||
updateWakeLock(true)
|
||||
}
|
||||
}
|
||||
102
app/src/main/java/com/woka/players/LiveStreamPlayerActivity.kt
Normal file
102
app/src/main/java/com/woka/players/LiveStreamPlayerActivity.kt
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.woka.players
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.jwplayer.pub.api.JWPlayer
|
||||
import com.jwplayer.pub.api.configuration.PlayerConfig
|
||||
import com.jwplayer.pub.api.events.EventType
|
||||
import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents
|
||||
import com.jwplayer.pub.api.fullscreen.FullscreenHandler
|
||||
import com.jwplayer.pub.api.media.playlists.PlaylistItem
|
||||
import com.woka.databinding.ActivityLiveStreamPlayerBinding
|
||||
|
||||
class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
|
||||
|
||||
companion object{
|
||||
private const val TAG = "LiveStreamPlayerActivity_tag"
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityLiveStreamPlayerBinding
|
||||
|
||||
private lateinit var player: JWPlayer
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = ActivityLiveStreamPlayerBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
val windowInsetsController =
|
||||
WindowCompat.getInsetsController(window, window.decorView)
|
||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
|
||||
setUpPlayer()
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
player.stop()
|
||||
}
|
||||
|
||||
private fun setUpPlayer() {
|
||||
player = binding.playerView.player
|
||||
|
||||
player.setFullscreenHandler(this)
|
||||
|
||||
player.setFullscreen(true, false)
|
||||
|
||||
player.addListener(EventType.ERROR, VideoPlayerEvents.OnErrorListener {
|
||||
Log.d(TAG, "onError: ${it.errorCode}")
|
||||
Log.d(TAG, "onError: ${it.exception}")
|
||||
Log.d(TAG, "onError: ${it.message}")
|
||||
})
|
||||
|
||||
player.addListener(EventType.SETUP_ERROR, VideoPlayerEvents.OnSetupErrorListener {
|
||||
Log.d(TAG, "setUpPlayer: $it")
|
||||
})
|
||||
|
||||
// to keep up the screen om when video is being played
|
||||
KeepScreenOnHandler(player, window)
|
||||
|
||||
val playlistItem = PlaylistItem.Builder()
|
||||
.file("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
.mediaId("YR5pnlIM")
|
||||
.build()
|
||||
val playlist: MutableList<PlaylistItem> = ArrayList()
|
||||
playlist.add(playlistItem)
|
||||
|
||||
val config =
|
||||
PlayerConfig.Builder()
|
||||
.playlist(playlist)
|
||||
.build()
|
||||
player.setup(config)
|
||||
player.play()
|
||||
}
|
||||
|
||||
override fun onFullscreenRequested() {}
|
||||
|
||||
override fun onFullscreenExitRequested() {
|
||||
player.stop()
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onAllowRotationChanged(allowRotation: Boolean) {}
|
||||
|
||||
override fun updateLayoutParams(layoutParams: ViewGroup.LayoutParams?) {}
|
||||
|
||||
override fun setUseFullscreenLayoutFlags(flags: Boolean) {}
|
||||
|
||||
}
|
||||
16
app/src/main/res/layout/activity_live_stream_player.xml
Normal file
16
app/src/main/res/layout/activity_live_stream_player.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
tools:context=".players.LiveStreamPlayerActivity">
|
||||
|
||||
<com.jwplayer.pub.view.JWPlayerView
|
||||
android:id="@+id/playerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".LiveStreamPlayerActivity"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -113,25 +113,22 @@
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/player_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
|
||||
app:cardCornerRadius="10dp"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:cardBackgroundColor="@color/black"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/g1"
|
||||
app:layout_constraintTop_toBottomOf="@id/profile_image">
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:background="@android:color/holo_green_dark"
|
||||
|
||||
android:layout_margin="5dp"
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:resize_mode="fill"
|
||||
/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -141,7 +138,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.35"/>
|
||||
app:layout_constraintGuide_percent="0.4"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/g2"
|
||||
|
||||
@@ -185,8 +185,10 @@
|
||||
android:translationZ="1dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/black_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
android:layout_marginHorizontal="@dimen/_28sdp"
|
||||
android:layout_marginTop="@dimen/_44sdp"
|
||||
android:layout_marginBottom="@dimen/_10sdp"
|
||||
@@ -195,12 +197,26 @@
|
||||
android:contentDescription="@string/image"
|
||||
android:paddingHorizontal="@dimen/_15sdp"
|
||||
|
||||
android:src="@drawable/woka_logo_full"
|
||||
android:src="@color/black"
|
||||
|
||||
android:visibility="visible"
|
||||
|
||||
/>
|
||||
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
android:layout_marginHorizontal="@dimen/_35sdp"
|
||||
android:layout_marginTop="@dimen/_44sdp"
|
||||
android:layout_marginBottom="@dimen/_10sdp"
|
||||
|
||||
android:background="@color/black"
|
||||
|
||||
android:visibility="visible"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
|
||||
@@ -29,5 +29,12 @@
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
</style>
|
||||
|
||||
<!-- full screen view-->
|
||||
<style name="FullScreenTheme" parent="Theme.Material3.Light.NoActionBar">
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Woka" parent="Base.Theme.Woka" />
|
||||
</resources>
|
||||
@@ -21,6 +21,7 @@ kotlin.code.style=official
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
android.enableJetifier=true
|
||||
|
||||
|
||||
# BASE URLS
|
||||
|
||||
@@ -16,6 +16,9 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://mvn.jwplayer.com/content/repositories/releases/'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user