Providing a thumbnail when sending a media is now optional.

This commit is contained in:
Benoit Marty 2023-12-19 10:41:44 +01:00
parent 4dc0ddcb80
commit ee766ecf26
7 changed files with 47 additions and 37 deletions

View file

@ -137,7 +137,7 @@ class AndroidMediaPreProcessor @Inject constructor(
resizeMode = ResizeMode.Approximate(IMAGE_SCALE_REF_SIZE, IMAGE_SCALE_REF_SIZE),
orientation = orientation,
).getOrThrow()
val thumbnailResult: ThumbnailResult = thumbnailFactory.createImageThumbnail(compressionResult.file)
val thumbnailResult = thumbnailFactory.createImageThumbnail(compressionResult.file)
val imageInfo = compressionResult.toImageInfo(
mimeType = mimeType,
thumbnailResult = thumbnailResult
@ -146,13 +146,13 @@ class AndroidMediaPreProcessor @Inject constructor(
return MediaUploadInfo.Image(
file = compressionResult.file,
imageInfo = imageInfo,
thumbnailFile = thumbnailResult.file
thumbnailFile = thumbnailResult?.file
)
}
suspend fun processImageWithoutCompression(): MediaUploadInfo {
val file = copyToTmpFile(uri)
val thumbnailResult: ThumbnailResult = thumbnailFactory.createImageThumbnail(file)
val thumbnailResult = thumbnailFactory.createImageThumbnail(file)
val imageInfo = contentResolver.openInputStream(uri).use { input ->
val bitmap = BitmapFactory.decodeStream(input, null, null)!!
ImageInfo(
@ -160,16 +160,16 @@ class AndroidMediaPreProcessor @Inject constructor(
height = bitmap.height.toLong(),
mimetype = mimeType,
size = file.length(),
thumbnailInfo = thumbnailResult.info,
thumbnailInfo = thumbnailResult?.info,
thumbnailSource = null,
blurhash = thumbnailResult.blurhash,
blurhash = thumbnailResult?.blurhash,
)
}
removeSensitiveImageMetadata(file)
return MediaUploadInfo.Image(
file = file,
imageInfo = imageInfo,
thumbnailFile = thumbnailResult.file
thumbnailFile = thumbnailResult?.file
)
}
@ -197,7 +197,7 @@ class AndroidMediaPreProcessor @Inject constructor(
return MediaUploadInfo.Video(
file = resultFile,
videoInfo = videoInfo,
thumbnailFile = thumbnailInfo.file
thumbnailFile = thumbnailInfo?.file
)
}
@ -235,7 +235,7 @@ class AndroidMediaPreProcessor @Inject constructor(
}
}
private fun extractVideoMetadata(file: File, mimeType: String?, thumbnailResult: ThumbnailResult): VideoInfo =
private fun extractVideoMetadata(file: File, mimeType: String?, thumbnailResult: ThumbnailResult?): VideoInfo =
MediaMetadataRetriever().runAndRelease {
setDataSource(context, Uri.fromFile(file))
VideoInfo(
@ -244,10 +244,10 @@ class AndroidMediaPreProcessor @Inject constructor(
height = extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toLong() ?: 0L,
mimetype = mimeType,
size = file.length(),
thumbnailInfo = thumbnailResult.info,
thumbnailInfo = thumbnailResult?.info,
// Will be computed by the rust sdk
thumbnailSource = null,
blurhash = thumbnailResult.blurhash,
blurhash = thumbnailResult?.blurhash,
)
}
@ -257,15 +257,15 @@ class AndroidMediaPreProcessor @Inject constructor(
}
}
fun ImageCompressionResult.toImageInfo(mimeType: String, thumbnailResult: ThumbnailResult) = ImageInfo(
private fun ImageCompressionResult.toImageInfo(mimeType: String, thumbnailResult: ThumbnailResult?) = ImageInfo(
width = width.toLong(),
height = height.toLong(),
mimetype = mimeType,
size = size,
thumbnailInfo = thumbnailResult.info,
thumbnailInfo = thumbnailResult?.info,
// Will be computed by the rust sdk
thumbnailSource = null,
blurhash = thumbnailResult.blurhash,
blurhash = thumbnailResult?.blurhash,
)
private fun MediaMetadataRetriever.extractDuration(): Duration {

View file

@ -61,7 +61,7 @@ class ThumbnailFactory @Inject constructor(
) {
@SuppressLint("NewApi")
suspend fun createImageThumbnail(file: File): ThumbnailResult {
suspend fun createImageThumbnail(file: File): ThumbnailResult? {
return createThumbnail { cancellationSignal ->
// This API works correctly with GIF
if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.Q)) {
@ -80,7 +80,7 @@ class ThumbnailFactory @Inject constructor(
}
}
suspend fun createVideoThumbnail(file: File): ThumbnailResult {
suspend fun createVideoThumbnail(file: File): ThumbnailResult? {
return createThumbnail {
MediaMetadataRetriever().runAndRelease {
setDataSource(context, file.toUri())
@ -89,32 +89,33 @@ class ThumbnailFactory @Inject constructor(
}
}
private suspend fun createThumbnail(bitmapFactory: (CancellationSignal) -> Bitmap?): ThumbnailResult = suspendCancellableCoroutine { continuation ->
private suspend fun createThumbnail(bitmapFactory: (CancellationSignal) -> Bitmap?): ThumbnailResult? = suspendCancellableCoroutine { continuation ->
val cancellationSignal = CancellationSignal()
continuation.invokeOnCancellation {
cancellationSignal.cancel()
}
val bitmapThumbnail: Bitmap? = bitmapFactory(cancellationSignal)
if (bitmapThumbnail == null) {
continuation.resume(null)
return@suspendCancellableCoroutine
}
val thumbnailFile = context.createTmpFile(extension = "jpeg")
thumbnailFile.outputStream().use { outputStream ->
bitmapThumbnail?.compress(Bitmap.CompressFormat.JPEG, 80, outputStream)
}
val blurhash = bitmapThumbnail?.let {
BlurHash.encode(it, 3, 3)
bitmapThumbnail.compress(Bitmap.CompressFormat.JPEG, 80, outputStream)
}
val blurhash = BlurHash.encode(bitmapThumbnail, 3, 3)
val thumbnailResult = ThumbnailResult(
file = thumbnailFile,
info = ThumbnailInfo(
height = bitmapThumbnail?.height?.toLong(),
width = bitmapThumbnail?.width?.toLong(),
height = bitmapThumbnail.height.toLong(),
width = bitmapThumbnail.width.toLong(),
mimetype = MimeTypes.Jpeg,
size = thumbnailFile.length()
),
blurhash = blurhash
)
bitmapThumbnail?.recycle()
bitmapThumbnail.recycle()
continuation.resume(thumbnailResult)
}
}