1717package io.getstream.chat.android.ui.common.helper.internal
1818
1919import android.content.Context
20+ import android.graphics.BitmapFactory
21+ import android.media.MediaMetadataRetriever
2022import android.net.Uri
2123import androidx.annotation.WorkerThread
24+ import io.getstream.chat.android.client.utils.attachment.isImage
25+ import io.getstream.chat.android.client.utils.attachment.isVideo
2226import io.getstream.chat.android.core.internal.InternalStreamChatApi
2327import io.getstream.chat.android.models.Attachment
2428import io.getstream.chat.android.ui.common.helper.internal.AttachmentStorageHelper.Companion.EXTRA_SOURCE_URI
2529import io.getstream.chat.android.ui.common.state.messages.composer.AttachmentMetaData
2630import io.getstream.log.taggedLogger
31+ import java.io.File
2732
2833/* *
2934 * Handles querying device storage for attachment metadata and converting between
@@ -111,9 +116,17 @@ public class AttachmentStorageHelper(
111116 logger.w { " [resolveAttachmentFiles] Failed to resolve file for URI: $sourceUri " }
112117 return @mapNotNull null
113118 }
119+
120+ val (width, height) = if (attachment.originalWidth == null && attachment.originalHeight == null ) {
121+ resolveLocalDimensions(file, attachment)
122+ } else {
123+ attachment.originalWidth to attachment.originalHeight
124+ }
114125 attachment.copy(
115126 upload = file,
116127 extraData = attachment.extraData - EXTRA_SOURCE_URI ,
128+ originalWidth = width,
129+ originalHeight = height,
117130 )
118131 }
119132
@@ -127,6 +140,37 @@ public class AttachmentStorageHelper(
127140 public fun resolveMetadata (uris : List <Uri >): List <AttachmentMetaData > =
128141 storageHelper.getAttachmentsFromUriList(context, uris).let (attachmentFilter::filterAttachments)
129142
143+ @Suppress(" MagicNumber" )
144+ private fun resolveLocalDimensions (file : File , attachment : Attachment ): Pair <Int ?, Int ?> = when {
145+ attachment.isImage() -> {
146+ val options = BitmapFactory .Options ().apply { inJustDecodeBounds = true }
147+ BitmapFactory .decodeFile(file.absolutePath, options)
148+ val w = options.outWidth.takeIf { it > 0 }
149+ val h = options.outHeight.takeIf { it > 0 }
150+ w to h
151+ }
152+
153+ attachment.isVideo() -> {
154+ val retriever = MediaMetadataRetriever ()
155+ try {
156+ retriever.setDataSource(file.absolutePath)
157+ val w = retriever.extractMetadata(MediaMetadataRetriever .METADATA_KEY_VIDEO_WIDTH )
158+ ?.toIntOrNull()?.takeIf { it > 0 }
159+ val h = retriever.extractMetadata(MediaMetadataRetriever .METADATA_KEY_VIDEO_HEIGHT )
160+ ?.toIntOrNull()?.takeIf { it > 0 }
161+ val rotation = retriever.extractMetadata(MediaMetadataRetriever .METADATA_KEY_VIDEO_ROTATION )
162+ ?.toIntOrNull() ? : 0
163+ if (rotation == 90 || rotation == 270 ) h to w else w to h
164+ } catch (_: Exception ) {
165+ null to null
166+ } finally {
167+ retriever.release()
168+ }
169+ }
170+
171+ else -> null to null
172+ }
173+
130174 public companion object {
131175 /* *
132176 * Key in [Attachment.extraData] holding the original content URI string
0 commit comments