Handle properly the case where the video compression is not necessary

This commit is contained in:
Benoit Marty 2021-05-04 23:12:58 +02:00
parent efc08b376b
commit 2a411ccf6c
3 changed files with 75 additions and 25 deletions

View File

@ -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
}

View File

@ -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()
}

View File

@ -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 {