Skip to content

Instantly share code, notes, and snippets.

@shkcodes
Created July 25, 2021 15:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shkcodes/f675612063d92cf48d17623a1b01c92e to your computer and use it in GitHub Desktop.
Save shkcodes/f675612063d92cf48d17623a1b01c92e to your computer and use it in GitHub Desktop.
ExoPlayer in LazyColumn
@Composable
fun TweetList(state: TweetListState) {
val context = LocalContext.current
val listState = rememberLazyListState()
val exoPlayer = remember {
SimpleExoPlayer.Builder(context).build().apply {
repeatMode = Player.REPEAT_MODE_ALL
}
}
val currentlyPlayingItem = if (state.autoplayVideos) {
determineCurrentlyPlayingItem(listState, state.items)
} else {
null
}
updateCurrentlyPlayingItem(exoPlayer, currentlyPlayingItem)
LazyColumn(state = listState) {
items(state.items) {
TweetItem(it, exoPlayer, currentlyPlayingItem)
}
}
}
@Composable
private fun TweetItem(
tweetItem: TweetItem,
exoPlayer: SimpleExoPlayer,
currentlyPlayingItem: TweetItem?
) {
// rest of the content
Box {
AndroidView(
factory = { context ->
context.inflate<PlayerView>(R.layout.player_view).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
player = exoPlayer
}
}
)
}
}
private fun determineCurrentlyPlayingItem(listState: LazyListState, items: TweetItems): TweetItem? {
val layoutInfo = listState.layoutInfo
val visibleTweets = layoutInfo.visibleItemsInfo.map { items[it.index] }
val tweetsWithVideo = visibleTweets.filter { it.hasAnimatedMedia }
return if (tweetsWithVideo.size == 1) {
tweetsWithVideo.first()
} else {
val midPoint = (layoutInfo.viewportStartOffset + layoutInfo.viewportEndOffset) / 2
val itemsFromCenter =
layoutInfo.visibleItemsInfo.sortedBy { abs((it.offset + it.size / 2) - midPoint) }
itemsFromCenter.map { items[it.index] }.firstOrNull { it.hasAnimatedMedia }
}
}
@Composable
private fun updateCurrentlyPlayingItem(exoPlayer: SimpleExoPlayer, tweet: TweetItem?) {
val context = LocalContext.current
LaunchedEffect(tweet) {
exoPlayer.apply {
if (tweet != null) {
val dataSourceFactory = DefaultDataSourceFactory(
context,
Util.getUserAgent(context, context.packageName)
)
val source = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(Uri.parse(tweet.media.url)))
setMediaSource(source)
prepare()
playWhenReady = true
} else {
stop()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment