mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-18 20:29:10 +03:00
Compress video before sending (#442)
This commit is contained in:
parent
a377a595b9
commit
5e1c503d2e
8 changed files with 123 additions and 6 deletions
|
@ -7,6 +7,7 @@ Features ✨:
|
|||
Improvements 🙌:
|
||||
- Add ability to install APK from directly from Element (#2381)
|
||||
- Delete and react to stickers (#3250)
|
||||
- Compress video before sending (#442)
|
||||
|
||||
Bugfix 🐛:
|
||||
- Message states cosmetic changes (#3007)
|
||||
|
|
|
@ -45,9 +45,11 @@ allprojects {
|
|||
// PFLockScreen-Android
|
||||
includeGroupByRegex 'com\\.github\\.vector-im'
|
||||
|
||||
//Chat effects
|
||||
// Chat effects
|
||||
includeGroupByRegex 'com\\.github\\.jetradarmobile'
|
||||
includeGroupByRegex 'nl\\.dionsegijn'
|
||||
// LightCompressor
|
||||
includeGroupByRegex 'com\\.github\\.AbedElazizShe'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
|
|
|
@ -168,6 +168,9 @@ dependencies {
|
|||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
implementation 'com.facebook.stetho:stetho-okhttp3:1.6.0'
|
||||
|
||||
// Video compression
|
||||
implementation 'com.github.AbedElazizShe:LightCompressor:0.9.0'
|
||||
|
||||
// Phone number https://github.com/google/libphonenumber
|
||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.22'
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
@Inject lateinit var fileService: DefaultFileService
|
||||
@Inject lateinit var cancelSendTracker: CancelSendTracker
|
||||
@Inject lateinit var imageCompressor: ImageCompressor
|
||||
@Inject lateinit var videoCompressor: VideoCompressor
|
||||
@Inject lateinit var localEchoRepository: LocalEchoRepository
|
||||
|
||||
override fun injectWith(injector: SessionComponent) {
|
||||
|
@ -170,6 +171,18 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
}
|
||||
}
|
||||
.also { filesToDelete.add(it) }
|
||||
} else if (attachment.type == ContentAttachmentData.Type.VIDEO
|
||||
// Do not compress gif
|
||||
&& attachment.mimeType != MimeTypes.Gif
|
||||
&& params.compressBeforeSending) {
|
||||
fileToUpload = videoCompressor.compress(workingFile)
|
||||
.also { compressedFile ->
|
||||
// Get new Video size
|
||||
newAttachmentAttributes = NewAttachmentAttributes(
|
||||
newFileSize = compressedFile.length()
|
||||
)
|
||||
}
|
||||
.also { filesToDelete.add(it) }
|
||||
} else {
|
||||
fileToUpload = workingFile
|
||||
// Fix: OpenableColumns.SIZE may return -1 or 0
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 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 android.content.Context
|
||||
import com.abedelazizshe.lightcompressorlibrary.CompressionListener
|
||||
import com.abedelazizshe.lightcompressorlibrary.VideoCompressor
|
||||
import com.abedelazizshe.lightcompressorlibrary.VideoQuality
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class VideoCompressor @Inject constructor(private val context: Context) {
|
||||
suspend fun compress(videoFile: File,
|
||||
quality: VideoQuality = VideoQuality.MEDIUM,
|
||||
isMinBitRateEnabled: Boolean = false,
|
||||
keepOriginalResolution: Boolean = true): File {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val job = Job()
|
||||
val destinationFile = createDestinationFile()
|
||||
|
||||
// Sadly it does not return the Job, the API is not ideal
|
||||
VideoCompressor.start(
|
||||
context = null,
|
||||
srcUri = null,
|
||||
srcPath = videoFile.path,
|
||||
destPath = destinationFile.path,
|
||||
listener = object : CompressionListener {
|
||||
override fun onProgress(percent: Float) {
|
||||
Timber.d("Compressing: $percent%")
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
Timber.d("Compressing: start")
|
||||
}
|
||||
|
||||
override fun onSuccess() {
|
||||
Timber.d("Compressing: success")
|
||||
job.complete()
|
||||
}
|
||||
|
||||
override fun onFailure(failureMessage: String) {
|
||||
Timber.d("Compressing: failure: $failureMessage")
|
||||
job.completeExceptionally(Exception(failureMessage))
|
||||
}
|
||||
|
||||
override fun onCancelled() {
|
||||
Timber.d("Compressing: cancel")
|
||||
job.cancel()
|
||||
}
|
||||
},
|
||||
quality = quality,
|
||||
isMinBitRateEnabled = isMinBitRateEnabled,
|
||||
keepOriginalResolution = keepOriginalResolution
|
||||
)
|
||||
|
||||
job.join()
|
||||
destinationFile
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDestinationFile(): File {
|
||||
return File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir)
|
||||
}
|
||||
}
|
|
@ -21,15 +21,15 @@ import org.matrix.android.sdk.api.util.MimeTypes
|
|||
|
||||
private val listOfPreviewableMimeTypes = listOf(
|
||||
MimeTypes.Jpeg,
|
||||
MimeTypes.BadJpg,
|
||||
MimeTypes.Png,
|
||||
MimeTypes.Gif
|
||||
)
|
||||
|
||||
fun ContentAttachmentData.isPreviewable(): Boolean {
|
||||
// For now the preview only supports still image
|
||||
return type == ContentAttachmentData.Type.IMAGE
|
||||
&& listOfPreviewableMimeTypes.contains(getSafeMimeType() ?: "")
|
||||
// Preview supports image and video
|
||||
return (type == ContentAttachmentData.Type.IMAGE
|
||||
&& listOfPreviewableMimeTypes.contains(getSafeMimeType() ?: ""))
|
||||
|| type == ContentAttachmentData.Type.VIDEO
|
||||
}
|
||||
|
||||
data class GroupedContentAttachmentData(
|
||||
|
|
|
@ -139,7 +139,17 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
attachmentBigPreviewController.setData(state)
|
||||
views.attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex)
|
||||
views.attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex)
|
||||
views.attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size)
|
||||
views.attachmentPreviewerSendImageOriginalSize.text = getCheckboxText(state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCheckboxText(state: AttachmentsPreviewViewState): CharSequence {
|
||||
val nbImages = state.attachments.count { it.type == ContentAttachmentData.Type.IMAGE }
|
||||
val nbVideos = state.attachments.count { it.type == ContentAttachmentData.Type.VIDEO }
|
||||
return when {
|
||||
nbVideos == 0 -> resources.getQuantityString(R.plurals.send_images_with_original_size, nbImages)
|
||||
nbImages == 0 -> resources.getQuantityString(R.plurals.send_videos_with_original_size, nbVideos)
|
||||
else -> getString(R.string.send_images_and_video_with_original_size)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2785,6 +2785,11 @@
|
|||
<item quantity="one">Send image with the original size</item>
|
||||
<item quantity="other">Send images with the original size</item>
|
||||
</plurals>
|
||||
<plurals name="send_videos_with_original_size">
|
||||
<item quantity="one">Send video with the original size</item>
|
||||
<item quantity="other">Send videos with the original size</item>
|
||||
</plurals>
|
||||
<string name="send_images_and_video_with_original_size">Send media with the original size</string>
|
||||
|
||||
<string name="delete_event_dialog_title">Confirm Removal</string>
|
||||
<string name="delete_event_dialog_content">Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue