Я использую приведенный ниже код для извлечения видеокадра с удаленного URL-адреса с помощью MediaMetadataRetriever
, но он отстает и приводит к очень низкой производительности пользовательского интерфейса. Как сделать это быстро и эффективно?
@Composable
private fun ContentItem(
modifier: Modifier = Modifier,
content: Content,
onClick: (Content) -> Unit
) {
when (content.type) {
ContentType.Image -> {
// handle image
}
ContentType.Video -> {
val bitmap = remember { mutableStateOf<Bitmap?>(null) }
LaunchedEffect(content) {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(content.url)
// Retrieve frame at 1 second
bitmap.value = retriever.getFrameAtTime(
1000000,
MediaMetadataRetriever.OPTION_CLOSEST_SYNC
)
retriever.release()
}
bitmap.value?.let {
Image(
modifier = modifier,
bitmap = it.asImageBitmap(),
contentDescription = null
)
}
}
}
}
что именно вы подразумеваете под отставанием и низкой производительностью пользовательского интерфейса? вы выполняете это много раз?
Вместо того, чтобы выполнять тяжелую работу в потоке пользовательского интерфейса, вы можете использовать withContext
и Dispatchers.Default
как
LaunchedEffect(content) {
withContext(Dispatchers.Default){
val retriever = MediaMetadataRetriever()
retriever.setDataSource(content.url)
// Retrieve frame at 1 second
bitmap.value = retriever.getFrameAtTime(
1000000,
MediaMetadataRetriever.OPTION_CLOSEST_SYNC
)
retriever.release()
}
}
В этой заметке, не должен ли я использовать Dispatchers.IO
вместо Dispatchers.Default
?
Если операция getFrameAtTime является вычислительной и большая часть времени тратится на вычисления, а не на блокировку, вы можете использовать Dispatchers.Default. Если файл открыт и inputStream занимает больше времени, вы можете использовать Dispatchers.IO. Dispatchers.IO - This dispatcher is optimized to perform disk or network I/O outside of the main thread. Examples include using the Room component, reading from or writing to files, and running any network operations.
Я знаю о поддержке видео Coil, но не знаю, как создать собственный
VideoFrameDecoder
, поскольку мой URL-адрес не содержит расширения файла.