Inhalt von Exoplayern überschneiden sich gegenseitigAndroid

Forum für diejenigen, die für Android programmieren
Anonymous
 Inhalt von Exoplayern überschneiden sich gegenseitig

Post by Anonymous »

Ich habe eine ähnliche Frage gestellt, die ungelöst ist. Ich frage noch einmal mit weiteren Informationen. In meiner Android -App gibt es eine Netzansicht, die aus Gitterartikeln besteht, die ein Video oder ein Bild sein können. Im Folgenden von 3 Elementen. Der erste und der 3. sind Videos. Die Ausrichtung des zweiten Videos ist Porträt, und sie überläuft den Rand seines übergeordneten Containers in das erste Video. nutzen. Ich stellte fest, dass es nur dann passiert, wenn sich zwei Exoplayer gegenseitig überlappen. Im folgenden Raster ist der 4. Element auch ein Porträtvideo. Das Element oben ist ein Bild und das Video, das es in seinem Container fein bleibt.

Code: Select all

@Composable
fun MediaPreviewGrid(
mediaItems: List,
viewModel: TweetViewModel,
onFullScreenVideo: ((String, MimeiId) -> Unit)? = null, // Callback for full-screen video
) {
val tweet by viewModel.tweetState.collectAsState()
val navController = LocalNavController.current
val maxItems = when (mediaItems.size) {
1 -> 1
2, 3 -> mediaItems.size
else -> 4
}

// Set up sequential playback for multiple videos
val videoMids = remember {
limitedMediaList.mapIndexedNotNull { index, item ->
if (inferMediaTypeFromAttachment(item) == MediaType.Video) item.mid else null
}
}

Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
) {
when (limitedMediaList.size) {
1 -> {
val aspectRatio = if (aspectRatioOf(limitedMediaList[0]) > 0.8f) {
aspectRatioOf(limitedMediaList[0])
} else {
0.8f
}
MediaItemView(
limitedMediaList,
modifier = Modifier
.fillMaxWidth()
.aspectRatio(aspectRatio)
.clipToBounds()
.clickable {
val params = MediaViewerParams(
mediaItems.map {
MediaItem(
getMediaUrl(it.mid, tweet.author?.baseUrl.orEmpty()).toString(),
it.type
)
}, 0, tweet.mid, tweet.authorId
)
navController.navigate(NavTweet.MediaViewer(params))
},
index = 0,
numOfHiddenItems = if (mediaItems.size > maxItems) mediaItems.size - maxItems else 0,
autoPlay = firstVideoIndex == 0,
inPreviewGrid = true,
viewModel = viewModel,
onFullScreenVideo = onFullScreenVideo
)
}
2 -> {}
3 -> {}
4 -> {}
}
}
}

@Composable
fun MediaItemView(
mediaItems: List,
modifier: Modifier = Modifier,
index: Int,
numOfHiddenItems: Int = 0,      // add a PLUS sign to indicate more items not shown
autoPlay: Boolean = false,      // autoplay first video item, index 0
inPreviewGrid: Boolean = true,  // use real aspectRatio when not displaying in preview grid.
viewModel: TweetViewModel,
onFullScreenVideo: ((String, MimeiId) -> Unit)? = null // Callback for full-screen video
) {
val tweet by viewModel.tweetState.collectAsState()
val attachments = mediaItems.map {
val inferredType = inferMediaTypeFromAttachment(it)
val mediaUrl = getMediaUrl(it.mid, tweet.author?.baseUrl.orEmpty()).toString()
MediaItem(mediaUrl, inferredType)
}
val attachment = attachments[index]
val navController = LocalNavController.current

Box(
modifier = modifier
.background(Color.Gray.copy(alpha = 0.1f))
.clipToBounds(),
contentAlignment = Alignment.Center
) {
when (attachment.type) {
MediaType.Image -> {
// Use a Box with clickable modifier to handle image clicks
Box(
modifier = modifier
.clipToBounds()
.clickable {
goto(index)
}
) {
ImageViewer(
attachment.url,
modifier = Modifier.fillMaxSize(),
enableLongPress = false // Disable long press to allow clickable to work
)
}
}
MediaType.Video ->  {
VideoPreview(
url = attachment.url,
modifier = modifier,
index = index,
autoPlay = autoPlay,
inPreviewGrid = inPreviewGrid,
aspectRatio = mediaItems[index].aspectRatio,
callback = { goto(index) },
videoMid = mediaItems[index].mid
)
}
MediaType.Audio -> {
val backgroundModifier = if (index % 2 != 0) { // Check if index is odd
modifier.background(Color.Black.copy(alpha = 0.05f)) // Slightly darker background
} else {
modifier
}
Box(
modifier = backgroundModifier
.clipToBounds()
.clickable {
goto(index)
}
) {
AudioPreview(mediaItems, index, Modifier.fillMaxSize(), tweet)
}
}
else -> {       // add link to download other file type
BlobLink(mediaItems[index], attachment.url, modifier)
}
}
if (numOfHiddenItems > 0) {
/**
* Show a PLUS sign and number to indicate more items not shown
* */
Box(
modifier = Modifier
.matchParentSize()
.background(Color(0x40FFFFFF)), // Lighter shaded background
contentAlignment = Alignment.Center
) {
Row(modifier = Modifier.align(Alignment.Center))
{
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = null,
tint = Color.White,
modifier = Modifier
.size(50.dp)
.alpha(0.8f)
)
Text(
text = numOfHiddenItems.toString(),
color = Color.White,
fontSize = 50.sp, // Adjust this value as needed
textAlign = TextAlign.Center,
modifier = Modifier
.alpha(0.8f)
)
}
}
}
}
}
< /code>
@Composable
fun VideoPreview(
url: String,
modifier: Modifier,
index: Int,
autoPlay: Boolean = false,
inPreviewGrid: Boolean = true,
aspectRatio: Float?,
callback: (Int) ->  Unit,
videoMid: MimeiId? = null
) {
val context = LocalContext.current
var isVideoVisible by remember { mutableStateOf(false) }
var isMuted by remember { mutableStateOf(preferenceHelper.getSpeakerMute()) }
var isLoading by remember {
mutableStateOf(videoMid?.let { !VideoManager.isVideoPreloaded(it) } ?: true)
}

val exoPlayer = remember(url, videoMid) {
if (videoMid != null) {
VideoManager.getVideoPlayer(context, videoMid, url)
} else {
createExoPlayer(context, url, MediaType.Video)
}
}

// Preload video if not already cached

Box(
modifier = modifier
.clipToBounds()
.background(MaterialTheme.colorScheme.surfaceVariant) // Material3 surface variant for loading background
.onGloballyPositioned { layoutCoordinates ->
isVideoVisible = isElementVisible(layoutCoordinates)
}
.clickable {
// Auto-start video in full screen
callback(index)
}
) {
AndroidView(
factory = {
PlayerView(context).apply {
player = exoPlayer
useController = false // No controls in preview mode
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
// Set background color to light gray (Material3 surface variant equivalent)
setBackgroundColor(android.graphics.Color.rgb(245, 245, 245))
// Show buffering indicator
setShowBuffering(PlayerView.SHOW_BUFFERING_ALWAYS)
}
},
modifier = Modifier.fillMaxWidth()
)

// Show loading indicator when video is loading
if (isLoading) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceVariant),
contentAlignment = androidx.compose.ui.Alignment.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(32.dp),
color = MaterialTheme.colorScheme.primary
)
}
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post
  • Wie können CSS -Übergänge sich gegenseitig durch JS -Trigger unterbrechen?
    by Guest » » in HTML
    0 Replies
    21 Views
    Last post by Guest
  • Maui - Tasten stören sich gegenseitig
    by Anonymous » » in C#
    0 Replies
    9 Views
    Last post by Anonymous
  • Maui - Tasten stören sich gegenseitig
    by Anonymous » » in C#
    0 Replies
    19 Views
    Last post by Anonymous
  • HTML - DIV überlappt sich mit Bootstrap gegenseitig
    by Anonymous » » in HTML
    0 Replies
    9 Views
    Last post by Anonymous
  • HTML - DIV überlappt sich mit Bootstrap gegenseitig
    by Anonymous » » in CSS
    0 Replies
    12 Views
    Last post by Anonymous