Jasmin Fajkic
06/10/2024, 9:44 AMJasmin Fajkic
06/10/2024, 9:44 AMpackage com.example.digitalsignage
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.ContentScale
import androidx.media3.common.MediaMetadata
import androidx.media3.common.MimeTypes
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Surface
import coil.compose.AsyncImage
import com.example.digitalsignage.ui.theme.DigitalSignageTheme
import io.sanghun.compose.video.RepeatMode
import io.sanghun.compose.video.VideoPlayer
import io.sanghun.compose.video.controller.VideoPlayerControllerConfig
import io.sanghun.compose.video.uri.VideoPlayerMediaItem
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
enum class MediaType {
IMAGE, VIDEO
}
data class Media(
val url: String,
val type: MediaType,
val delay: Long
)
val media = listOf(
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000),
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000 ),
Media("<http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4>", MediaType.VIDEO, 16000),
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000),
Media("<http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4>", MediaType.VIDEO, 16000),
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000),
Media("<http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4>", MediaType.VIDEO, 16000),
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000),
Media("<http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4>", MediaType.VIDEO, 16000),
Media("<https://img.freepik.com/free-vector/flat-sale-landing-page-template_23-2149053848.jpg>", MediaType.IMAGE, 5000),
Media("<http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4>", MediaType.VIDEO, 16000),
)
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalTvMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DigitalSignageTheme {
Surface(
modifier = Modifier.fillMaxSize(),
shape = RectangleShape
) {
ContentPlayer()
}
}
}
}
}
@Composable
fun ContentPlayer() {
var currentIndex by rememberSaveable { mutableIntStateOf(0) }
val coroutineScope = rememberCoroutineScope()
fun switchToNextMedia() {
if (currentIndex == media.size - 1) currentIndex = 0
else currentIndex += 1
}
LaunchedEffect(currentIndex) {
coroutineScope.launch {
val currentMedia = media[currentIndex]
delay(currentMedia.delay)
switchToNextMedia()
}
}
Box(modifier = Modifier.fillMaxSize()) {
media.forEachIndexed { index, it ->
AnimatedVisibility(
visible = index == currentIndex,
enter = fadeIn(animationSpec = tween(durationMillis = 1500)),
exit = fadeOut(animationSpec = tween(durationMillis = 1500))
) {
if (it.type == MediaType.IMAGE) {
AsyncImage(
contentScale = ContentScale.FillBounds,
model = it.url,
contentDescription = null,
modifier = Modifier.fillMaxSize()
)
} else if (it.type == MediaType.VIDEO) {
VideoPlayer(
mediaItems = listOf(
VideoPlayerMediaItem.NetworkMediaItem(
url = it.url,
mediaMetadata = MediaMetadata.Builder().setTitle("Video").build(),
mimeType = MimeTypes.VIDEO_MP4,
)
),
handleLifecycle = true,
autoPlay = true,
usePlayerController = false,
enablePip = false,
handleAudioFocus = false,
controllerConfig = VideoPlayerControllerConfig.Default.copy(
showSpeedAndPitchOverlay = false,
showSubtitleButton = false,
showCurrentTimeAndTotalTime = true,
showBufferingProgress = false,
showForwardIncrementButton = false,
showBackwardIncrementButton = false,
showBackTrackButton = false,
showNextTrackButton = false,
showRepeatModeButton = false,
controllerShowTimeMilliSeconds = 5_000,
controllerAutoShow = false,
showFullScreenButton = false
),
volume = 0.5f,
repeatMode = RepeatMode.NONE,
modifier = Modifier.fillMaxSize()
)
}
}
}
}
}
Jasmin Fajkic
06/10/2024, 9:45 AM