Jetpack компонует получение видеокадра для сети, вызывая задержку

Я использую приведенный ниже код для извлечения видеокадра с удаленного 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
                )
            }
        }
    }
}

Я знаю о поддержке видео Coil, но не знаю, как создать собственный VideoFrameDecoder, поскольку мой URL-адрес не содержит расширения файла.

Annon 14.11.2022 17:45

что именно вы подразумеваете под отставанием и низкой производительностью пользовательского интерфейса? вы выполняете это много раз?

zjmo 14.11.2022 18:20
2
2
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вместо того, чтобы выполнять тяжелую работу в потоке пользовательского интерфейса, вы можете использовать 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?

Annon 14.11.2022 18:38

Если операция 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.

Thracian 14.11.2022 18:44

Другие вопросы по теме