194 lines
7.9 KiB
Kotlin
194 lines
7.9 KiB
Kotlin
package com.acitelight.aether.view
|
|
|
|
import android.app.Activity
|
|
import android.content.Context
|
|
import android.content.res.Configuration
|
|
import android.media.AudioManager
|
|
import android.view.View
|
|
import androidx.compose.animation.AnimatedVisibility
|
|
import androidx.compose.animation.fadeIn
|
|
import androidx.compose.animation.fadeOut
|
|
import androidx.compose.animation.slideInVertically
|
|
import androidx.compose.animation.slideOutVertically
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.material.icons.filled.Pause
|
|
import androidx.compose.material.icons.filled.PlayArrow
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.IconButton
|
|
import androidx.compose.material3.Slider
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.platform.LocalContext
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.viewinterop.AndroidView
|
|
import androidx.media3.exoplayer.ExoPlayer
|
|
import androidx.media3.ui.PlayerView
|
|
import androidx.navigation.NavHostController
|
|
import com.acitelight.aether.viewModel.VideoPlayerViewModel
|
|
|
|
import androidx.compose.foundation.gestures.detectDragGestures
|
|
import androidx.compose.foundation.gestures.detectTapGestures
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.Row
|
|
import androidx.compose.foundation.layout.Spacer
|
|
import androidx.compose.foundation.layout.fillMaxHeight
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.height
|
|
import androidx.compose.foundation.layout.heightIn
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.size
|
|
import androidx.compose.foundation.layout.width
|
|
import androidx.compose.foundation.layout.wrapContentWidth
|
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
import androidx.compose.foundation.lazy.LazyRow
|
|
import androidx.compose.foundation.lazy.items
|
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.automirrored.filled.VolumeUp
|
|
import androidx.compose.material.icons.filled.Brightness4
|
|
import androidx.compose.material.icons.filled.FastForward
|
|
import androidx.compose.material.icons.filled.Info
|
|
import androidx.compose.material.icons.filled.Lock
|
|
import androidx.compose.material.icons.filled.LockOpen
|
|
import androidx.compose.material.icons.filled.Share
|
|
import androidx.compose.material.icons.filled.Star
|
|
import androidx.compose.material.icons.filled.ThumbDown
|
|
import androidx.compose.material.icons.filled.ThumbUp
|
|
import androidx.compose.material3.Card
|
|
import androidx.compose.material3.CardColors
|
|
import androidx.compose.material3.CardDefaults
|
|
import androidx.compose.material3.DividerDefaults
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
import androidx.compose.material3.HorizontalDivider
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.SliderDefaults
|
|
import androidx.compose.material3.Tab
|
|
import androidx.compose.material3.TabRow
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableFloatStateOf
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.draw.alpha
|
|
import androidx.compose.ui.draw.clip
|
|
import androidx.compose.ui.geometry.Offset
|
|
import androidx.compose.ui.graphics.Brush
|
|
import androidx.compose.ui.graphics.Shadow
|
|
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
|
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|
import androidx.compose.ui.input.pointer.pointerInput
|
|
import androidx.compose.ui.layout.ContentScale
|
|
import androidx.compose.ui.layout.onGloballyPositioned
|
|
import androidx.compose.ui.platform.LocalConfiguration
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
import androidx.compose.ui.text.TextStyle
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import androidx.compose.ui.text.style.TextAlign
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.unit.Dp
|
|
import androidx.compose.ui.unit.TextUnit
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
|
import androidx.lifecycle.viewModelScope
|
|
import androidx.media3.common.text.Cue
|
|
import androidx.media3.common.util.UnstableApi
|
|
import coil3.ImageLoader
|
|
import coil3.compose.AsyncImage
|
|
import coil3.request.ImageRequest
|
|
import com.acitelight.aether.Global
|
|
import com.acitelight.aether.ToggleFullScreen
|
|
import com.acitelight.aether.model.KeyImage
|
|
import com.acitelight.aether.model.Video
|
|
import kotlinx.coroutines.launch
|
|
import kotlin.math.abs
|
|
import kotlin.math.exp
|
|
import kotlin.math.ln
|
|
import kotlin.math.pow
|
|
|
|
fun formatTime(ms: Long): String {
|
|
if (ms <= 0) return "00:00:00"
|
|
val totalSeconds = ms / 1000
|
|
val hours = totalSeconds / 3600
|
|
val minutes = (totalSeconds % 3600) / 60
|
|
val seconds = totalSeconds % 60
|
|
return String.format("%02d:%02d:%02d", hours, minutes, seconds)
|
|
}
|
|
|
|
fun moveBrit(db: Float, activity: Activity, videoPlayerViewModel: VideoPlayerViewModel) {
|
|
val attr = activity.window.attributes
|
|
|
|
val britUi = (videoPlayerViewModel.brit - db * 0.002f).coerceIn(0f, 1f)
|
|
videoPlayerViewModel.brit = britUi
|
|
|
|
val gamma = 2.2f
|
|
val britSystem = britUi.pow(gamma).coerceIn(0.001f, 1f)
|
|
|
|
attr.screenBrightness = britSystem
|
|
activity.window.attributes = attr
|
|
}
|
|
|
|
@Composable
|
|
fun isLandscape(): Boolean {
|
|
val configuration = LocalConfiguration.current
|
|
return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
|
}
|
|
|
|
@Composable
|
|
fun VideoPlayer(
|
|
videoPlayerViewModel: VideoPlayerViewModel = hiltViewModel<VideoPlayerViewModel>(),
|
|
videoId: String,
|
|
navController: NavHostController
|
|
) {
|
|
val colorScheme = MaterialTheme.colorScheme
|
|
videoPlayerViewModel.init(videoId)
|
|
|
|
if (videoPlayerViewModel.startPlaying) {
|
|
if (isLandscape()) {
|
|
Box {
|
|
VideoPlayerLandscape(videoPlayerViewModel)
|
|
AnimatedVisibility(
|
|
visible = videoPlayerViewModel.locked || videoPlayerViewModel.planeVisibility,
|
|
enter = fadeIn(
|
|
initialAlpha = 0f,
|
|
),
|
|
exit = fadeOut(
|
|
targetAlpha = 0f
|
|
),
|
|
modifier = Modifier.align(Alignment.CenterEnd)
|
|
) {
|
|
Card(
|
|
modifier = Modifier.padding(4.dp),
|
|
colors = CardDefaults.cardColors(
|
|
containerColor = colorScheme.primary.copy(
|
|
if (videoPlayerViewModel.locked) 0.2f else 1f
|
|
)
|
|
),
|
|
onClick = {
|
|
videoPlayerViewModel.locked = !videoPlayerViewModel.locked
|
|
}) {
|
|
Icon(
|
|
imageVector = if (videoPlayerViewModel.locked) Icons.Default.LockOpen else Icons.Default.Lock,
|
|
contentDescription = "Lock",
|
|
tint = Color.White.copy(if (videoPlayerViewModel.locked) 0.2f else 1f),
|
|
modifier = Modifier
|
|
.size(36.dp)
|
|
.padding(6.dp)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
VideoPlayerPortal(videoPlayerViewModel, navController)
|
|
}
|
|
}
|
|
}
|