draw to buffer

inline

scale video frame when possible

account for different dimensions
This commit is contained in:
mertalev
2025-07-21 13:29:50 +03:00
parent f9687888b0
commit a67374df75
8 changed files with 176 additions and 179 deletions

View File

@@ -59,7 +59,7 @@ private open class ThumbnailsPigeonCodec : StandardMessageCodec() {
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface ThumbnailApi {
fun setThumbnailToBuffer(pointer: Long, assetId: String, width: Long, height: Long, callback: (Result<Unit>) -> Unit)
fun setThumbnailToBuffer(pointer: Long, assetId: String, width: Long, height: Long, callback: (Result<Map<String, Long>>) -> Unit)
companion object {
/** The codec used by ThumbnailApi. */
@@ -79,12 +79,13 @@ interface ThumbnailApi {
val assetIdArg = args[1] as String
val widthArg = args[2] as Long
val heightArg = args[3] as Long
api.setThumbnailToBuffer(pointerArg, assetIdArg, widthArg, heightArg) { result: Result<Unit> ->
api.setThumbnailToBuffer(pointerArg, assetIdArg, widthArg, heightArg) { result: Result<Map<String, Long>> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(ThumbnailsPigeonUtils.wrapError(error))
} else {
reply.reply(ThumbnailsPigeonUtils.wrapResult(null))
val data = result.getOrNull()
reply.reply(ThumbnailsPigeonUtils.wrapResult(data))
}
}
}

View File

@@ -96,16 +96,25 @@ class ThumbnailsImpl(context: Context) : ThumbnailApi {
private fun decodeVideoThumbnail(assetId: String, targetWidth: Int, targetHeight: Int): Bitmap {
val uri =
ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, assetId.toLong())
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentResolver.loadThumbnail(uri, Size(targetWidth, targetHeight), null)
} else {
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(ctx, uri)
retriever.getFrameAtTime(0L) ?: throw RuntimeException("Failed to extract video frame")
} finally {
retriever.release()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return contentResolver.loadThumbnail(uri, Size(targetWidth, targetHeight), null)
}
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(ctx, uri)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
retriever.getScaledFrameAtTime(
0L,
MediaMetadataRetriever.OPTION_NEXT_SYNC,
targetWidth,
targetHeight
)
} else {
retriever.getFrameAtTime(0L)
} ?: throw RuntimeException("Failed to extract video frame")
} finally {
retriever.release()
}
}