Skip to content

Commit 06e2f93

Browse files
authored
Merge pull request #1641 from DimensionDev/feature/video_playback
optimize video playback
2 parents d099600 + f3a46ec commit 06e2f93

File tree

2 files changed

+104
-155
lines changed

2 files changed

+104
-155
lines changed

app/src/main/java/dev/dimension/flare/ui/screen/media/StatusMediaScreen.kt

Lines changed: 86 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import androidx.compose.material3.Surface
5151
import androidx.compose.material3.Text
5252
import androidx.compose.runtime.Composable
5353
import androidx.compose.runtime.CompositionLocalProvider
54-
import androidx.compose.runtime.DisposableEffect
5554
import androidx.compose.runtime.LaunchedEffect
5655
import androidx.compose.runtime.getValue
5756
import androidx.compose.runtime.mutableIntStateOf
@@ -180,6 +179,9 @@ internal fun StatusMediaScreen(
180179
}
181180
},
182181
)
182+
LaunchedEffect(pagerState.currentPage) {
183+
state.setCurrentPage(pagerState.currentPage)
184+
}
183185
FlareTheme(darkTheme = true) {
184186
val swiperState =
185187
rememberSwiperState(
@@ -197,40 +199,6 @@ internal fun StatusMediaScreen(
197199
Modifier
198200
.fillMaxSize(),
199201
) {
200-
state.medias.onSuccess { media ->
201-
var lastPage by remember {
202-
mutableIntStateOf(pagerState.currentPage)
203-
}
204-
LaunchedEffect(pagerState.currentPage) {
205-
state.setCurrentPage(pagerState.currentPage)
206-
if (lastPage != pagerState.currentPage) {
207-
val player = playerPool.peek(media[pagerState.currentPage].url)
208-
player?.play()
209-
val lastPlayer = playerPool.peek(media[lastPage].url)
210-
lastPlayer?.pause()
211-
212-
// handle pages around without lastPage
213-
if (lastPage == pagerState.currentPage - 1 && pagerState.currentPage + 1 < pagerState.pageCount) {
214-
val nextPlayer =
215-
playerPool.peek(media[pagerState.currentPage + 1].url)
216-
nextPlayer?.pause()
217-
} else if (lastPage == pagerState.currentPage + 1 && pagerState.currentPage - 1 >= 0) {
218-
val prevPlayer =
219-
playerPool.peek(media[pagerState.currentPage - 1].url)
220-
prevPlayer?.pause()
221-
}
222-
223-
lastPage = pagerState.currentPage
224-
}
225-
}
226-
// TODO: workaround: some video url might change after StatusPresenter load the status
227-
DisposableEffect(pagerState.currentPage) {
228-
val player = playerPool.peek(media[pagerState.currentPage].url)
229-
onDispose {
230-
player?.volume = 0f
231-
}
232-
}
233-
}
234202
Row {
235203
Box(
236204
modifier = Modifier.weight(1f),
@@ -264,114 +232,90 @@ internal fun StatusMediaScreen(
264232
) {
265233
it
266234
.onSuccess { medias ->
267-
when (val media = medias[index]) {
268-
is UiMedia.Audio ->
269-
VideoPlayer(
270-
uri = media.url,
271-
previewUri = null,
272-
contentDescription = media.description,
273-
autoPlay = false,
274-
modifier =
275-
Modifier
276-
.fillMaxSize(),
277-
onClick = {
278-
state.setShowUi(!state.showUi)
279-
},
280-
onLongClick = {
281-
hapticFeedback.performHapticFeedback(
282-
HapticFeedbackType.LongPress,
283-
)
284-
state.setShowSheet(true)
285-
},
286-
)
287-
288-
is UiMedia.Gif ->
289-
ImageItem(
290-
modifier =
291-
Modifier
292-
// .sharedElement(
293-
// rememberSharedContentState(media.previewUrl),
294-
// animatedVisibilityScope = this@AnimatedVisibilityScope,
295-
// )
296-
.fillMaxSize(),
297-
url = media.url,
298-
previewUrl = media.previewUrl,
299-
description = media.description,
300-
onClick = {
301-
state.setShowUi(!state.showUi)
302-
},
303-
setLockPager = {
304-
if (pagerState.currentPage == index) {
305-
if (!isBigScreen) {
306-
state.setShowUi(!it)
307-
}
308-
state.setLockPager(it)
309-
}
310-
},
311-
onLongClick = {
312-
hapticFeedback.performHapticFeedback(
313-
HapticFeedbackType.LongPress,
314-
)
315-
state.setShowSheet(true)
316-
},
317-
)
318-
319-
is UiMedia.Image -> {
320-
ImageItem(
321-
modifier =
322-
Modifier
323-
// .sharedElement(
324-
// rememberSharedContentState(media.previewUrl),
325-
// animatedVisibilityScope = this@AnimatedVisibilityScope,
326-
// )
327-
.fillMaxSize(),
328-
url = media.url,
329-
previewUrl = media.previewUrl,
330-
description = media.description,
331-
onClick = {
332-
state.setShowUi(!state.showUi)
333-
},
334-
setLockPager = {
335-
if (pagerState.currentPage == index) {
336-
if (!isBigScreen) {
337-
state.setShowUi(!it)
338-
}
339-
state.setLockPager(it)
340-
}
341-
},
342-
onLongClick = {
343-
hapticFeedback.performHapticFeedback(
344-
HapticFeedbackType.LongPress,
345-
)
346-
state.setShowSheet(true)
347-
},
348-
)
235+
val media = medias[index]
236+
val imageUrl =
237+
when (media) {
238+
is UiMedia.Audio -> media.previewUrl ?: media.url
239+
is UiMedia.Gif -> media.url
240+
is UiMedia.Image -> media.url
241+
is UiMedia.Video -> media.thumbnailUrl
349242
}
350-
351-
is UiMedia.Video ->
352-
VideoPlayer(
353-
uri = media.url,
354-
previewUri = media.thumbnailUrl,
355-
contentDescription = media.description,
356-
autoPlay = false,
357-
modifier =
358-
Modifier
359-
.fillMaxSize(),
360-
onClick = {
361-
state.setShowUi(!state.showUi)
362-
},
363-
aspectRatio = media.aspectRatio,
364-
showControls = true,
365-
keepScreenOn = true,
366-
muted = false,
367-
contentScale = ContentScale.Fit,
368-
onLongClick = {
369-
hapticFeedback.performHapticFeedback(
370-
HapticFeedbackType.LongPress,
371-
)
372-
state.setShowSheet(true)
373-
},
374-
)
243+
val previewUrl =
244+
when (media) {
245+
is UiMedia.Audio -> media.previewUrl ?: media.url
246+
is UiMedia.Gif -> media.previewUrl
247+
is UiMedia.Image -> media.previewUrl
248+
is UiMedia.Video -> media.thumbnailUrl
249+
}
250+
if (pagerState.currentPage != index || media is UiMedia.Image || media is UiMedia.Gif) {
251+
ImageItem(
252+
modifier =
253+
Modifier
254+
.fillMaxSize(),
255+
url = imageUrl,
256+
previewUrl = previewUrl,
257+
description = media.description,
258+
onClick = {
259+
state.setShowUi(!state.showUi)
260+
},
261+
setLockPager = {
262+
if (pagerState.currentPage == index) {
263+
if (!isBigScreen) {
264+
state.setShowUi(!it)
265+
}
266+
state.setLockPager(it)
267+
}
268+
},
269+
onLongClick = {
270+
hapticFeedback.performHapticFeedback(
271+
HapticFeedbackType.LongPress,
272+
)
273+
state.setShowSheet(true)
274+
},
275+
)
276+
} else if (media is UiMedia.Video) {
277+
VideoPlayer(
278+
uri = media.url,
279+
previewUri = media.thumbnailUrl,
280+
contentDescription = media.description,
281+
autoPlay = true,
282+
modifier =
283+
Modifier
284+
.fillMaxSize(),
285+
onClick = {
286+
state.setShowUi(!state.showUi)
287+
},
288+
aspectRatio = media.aspectRatio,
289+
showControls = true,
290+
keepScreenOn = true,
291+
muted = false,
292+
contentScale = ContentScale.Fit,
293+
onLongClick = {
294+
hapticFeedback.performHapticFeedback(
295+
HapticFeedbackType.LongPress,
296+
)
297+
state.setShowSheet(true)
298+
},
299+
)
300+
} else if (media is UiMedia.Audio) {
301+
VideoPlayer(
302+
uri = media.url,
303+
previewUri = null,
304+
contentDescription = media.description,
305+
autoPlay = false,
306+
modifier =
307+
Modifier
308+
.fillMaxSize(),
309+
onClick = {
310+
state.setShowUi(!state.showUi)
311+
},
312+
onLongClick = {
313+
hapticFeedback.performHapticFeedback(
314+
HapticFeedbackType.LongPress,
315+
)
316+
state.setShowSheet(true)
317+
},
318+
)
375319
}
376320
}.onLoading {
377321
if (preview != null) {

0 commit comments

Comments
 (0)