From 2a411ccf6c746fa3a46162a038eb0b9f528012b6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 4 May 2021 23:12:58 +0200 Subject: [PATCH] Handle properly the case where the video compression is not necessary --- .../session/content/UploadContentWorker.kt | 48 +++++++++++-------- .../session/content/VideoCompressionResult.kt | 24 ++++++++++ .../session/content/VideoCompressor.kt | 28 +++++++++-- 3 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressionResult.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index 305d7b9e70..15c6d243d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -179,33 +179,41 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter // Do not compress gif && attachment.mimeType != MimeTypes.Gif && params.compressBeforeSending) { - fileToUpload = videoCompressor.compress(workingFile, object: ProgressListener { + fileToUpload = videoCompressor.compress(workingFile, object : ProgressListener { override fun onProgress(progress: Int, total: Int) { notifyTracker(params) { contentUploadStateTracker.setCompressingVideo(it, progress.toFloat()) } } }) - .also { compressedFile -> - var compressedWidth = 0 - var compressedHeight = 0 + .let { videoCompressionResult -> + when (videoCompressionResult) { + is VideoCompressionResult.Success -> { + val compressedFile = videoCompressionResult.compressedFile + var compressedWidth: Int? = null + var compressedHeight: Int? = null - tryOrNull { - context.contentResolver.openFileDescriptor(compressedFile.toUri(), "r")?.use { pfd -> - val mediaMetadataRetriever = MediaMetadataRetriever() - mediaMetadataRetriever.setDataSource(pfd.fileDescriptor) - compressedWidth = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toInt() ?: 0 - compressedHeight = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toInt() - ?: 0 + tryOrNull { + context.contentResolver.openFileDescriptor(compressedFile.toUri(), "r")?.use { pfd -> + val mediaMetadataRetriever = MediaMetadataRetriever() + mediaMetadataRetriever.setDataSource(pfd.fileDescriptor) + compressedWidth = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toInt() + compressedHeight = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toInt() + } + } + + // Get new Video file size and dimensions + newAttachmentAttributes = newAttachmentAttributes.copy( + newFileSize = compressedFile.length(), + newWidth = compressedWidth ?: newAttachmentAttributes.newWidth, + newHeight = compressedHeight ?: newAttachmentAttributes.newHeight + ) + compressedFile + .also { filesToDelete.add(it) } + } + is VideoCompressionResult.CompressionNotNeeded -> { + workingFile } } - - // Get new Video file size and dimensions - newAttachmentAttributes = newAttachmentAttributes.copy( - newFileSize = compressedFile.length(), - newWidth = compressedWidth.takeIf { it != 0 } ?: newAttachmentAttributes.newWidth, - newHeight = compressedHeight.takeIf { it != 0 } ?: newAttachmentAttributes.newHeight - ) } - .also { filesToDelete.add(it) } } else { fileToUpload = workingFile // Fix: OpenableColumns.SIZE may return -1 or 0 @@ -371,7 +379,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter val updatedContent = when (messageContent) { is MessageImageContent -> messageContent.update(url, encryptedFileInfo, newAttachmentAttributes) is MessageVideoContent -> messageContent.update(url, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo, newAttachmentAttributes) - is MessageFileContent -> messageContent.update(url, encryptedFileInfo, newAttachmentAttributes.newFileSize) + is MessageFileContent -> messageContent.update(url, encryptedFileInfo, newAttachmentAttributes.newFileSize) is MessageAudioContent -> messageContent.update(url, encryptedFileInfo, newAttachmentAttributes.newFileSize) else -> messageContent } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressionResult.kt new file mode 100644 index 0000000000..b1362317ba --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressionResult.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.content + +import java.io.File + +internal sealed class VideoCompressionResult { + data class Success(val compressedFile: File) : VideoCompressionResult() + object CompressionNotNeeded : VideoCompressionResult() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressor.kt index 712ee94f2f..53113e2d86 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/VideoCompressor.kt @@ -29,8 +29,9 @@ import java.util.UUID import javax.inject.Inject internal class VideoCompressor @Inject constructor(private val context: Context) { + suspend fun compress(videoFile: File, - progressListener: ProgressListener?): File { + progressListener: ProgressListener?): VideoCompressionResult { val destinationFile = withContext(Dispatchers.IO) { createDestinationFile() } @@ -40,6 +41,7 @@ internal class VideoCompressor @Inject constructor(private val context: Context) Timber.d("Compressing: start") progressListener?.onProgress(0, 100) + var result: Int = -1 Transcoder.into(destinationFile.path) .addDataSource(videoFile.path) .setListener(object : TranscoderListener { @@ -49,8 +51,8 @@ internal class VideoCompressor @Inject constructor(private val context: Context) } override fun onTranscodeCompleted(successCode: Int) { - Timber.d("Compressing: success") - progressListener?.onProgress(100, 100) + Timber.d("Compressing: success: $successCode") + result = successCode job.complete() } @@ -60,14 +62,30 @@ internal class VideoCompressor @Inject constructor(private val context: Context) } override fun onTranscodeFailed(exception: Throwable) { - Timber.d("Compressing: failure: ${exception.localizedMessage}") + Timber.w(exception, "Compressing: failure") job.completeExceptionally(exception) } }) .transcode() job.join() - return destinationFile + + progressListener?.onProgress(100, 100) + + return when (result) { + Transcoder.SUCCESS_TRANSCODED -> { + VideoCompressionResult.Success(destinationFile) + } + Transcoder.SUCCESS_NOT_NEEDED -> { + // Delete now the temporary file + withContext(Dispatchers.IO) { + destinationFile.delete() + } + VideoCompressionResult.CompressionNotNeeded + } + else -> + throw IllegalStateException("Unknown result: $result") + } } private fun createDestinationFile(): File {