From 3db36d8c67a49a0a5f5dde0725c8c3ad214c1cf6 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 11 Sep 2024 09:04:44 +0200 Subject: [PATCH] added skipping of media compressor when quality is UNCOMPRESSED added media compressor logging --- .../amethyst/ui/actions/NewMediaView.kt | 9 +- .../amethyst/ui/actions/NewPostView.kt | 9 +- .../amethyst/ui/components/MediaCompressor.kt | 193 ++++++++++-------- 3 files changed, 117 insertions(+), 94 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt index cdce79368..11de73a0d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt @@ -105,7 +105,9 @@ fun NewMediaView( var showRelaysDialog by remember { mutableStateOf(false) } var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() } - var mediaQualitySlider by remember { mutableIntStateOf(1) } // 0 = Low, 1 = Medium, 2 = High + + // 0 = Low, 1 = Medium, 2 = High, 3=UNCOMPRESSED + var mediaQualitySlider by remember { mutableIntStateOf(1) } Dialog( onDismissRequest = { onClose() }, @@ -225,6 +227,7 @@ fun NewMediaView( 0 -> stringRes(R.string.media_compression_quality_low) 1 -> stringRes(R.string.media_compression_quality_medium) 2 -> stringRes(R.string.media_compression_quality_high) + 3 -> "UNCOMPRESSED" else -> stringRes(R.string.media_compression_quality_medium) }, modifier = Modifier.align(Alignment.Center), @@ -234,8 +237,8 @@ fun NewMediaView( Slider( value = mediaQualitySlider.toFloat(), onValueChange = { mediaQualitySlider = it.toInt() }, - valueRange = 0f..2f, - steps = 1, + valueRange = 0f..3f, + steps = 2, ) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index 7fd0e1e62..4e7a53ef2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -1735,7 +1735,9 @@ fun ImageVideoDescription( } var message by remember { mutableStateOf("") } var sensitiveContent by remember { mutableStateOf(false) } - var mediaQualitySlider by remember { mutableIntStateOf(1) } // 0 = Low, 1 = Medium, 2 = High + + // 0 = Low, 1 = Medium, 2 = High, 3=UNCOMPRESSED + var mediaQualitySlider by remember { mutableIntStateOf(1) } Column( modifier = @@ -1953,6 +1955,7 @@ fun ImageVideoDescription( 0 -> stringRes(R.string.media_compression_quality_low) 1 -> stringRes(R.string.media_compression_quality_medium) 2 -> stringRes(R.string.media_compression_quality_high) + 3 -> "UNCOMPRESSED" else -> stringRes(R.string.media_compression_quality_medium) }, modifier = Modifier.align(Alignment.Center), @@ -1962,8 +1965,8 @@ fun ImageVideoDescription( Slider( value = mediaQualitySlider.toFloat(), onValueChange = { mediaQualitySlider = it.toInt() }, - valueRange = 0f..2f, - steps = 1, + valueRange = 0f..3f, + steps = 2, ) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MediaCompressor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MediaCompressor.kt index bf53e718d..1f4726898 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MediaCompressor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MediaCompressor.kt @@ -49,99 +49,113 @@ class MediaCompressor { onError: (Int) -> Unit, mediaQuality: CompressorQuality, ) { - checkNotInMainThread() + if (mediaQuality != CompressorQuality.UNCOMPRESSED) { + checkNotInMainThread() - if (contentType?.startsWith("video", true) == true) { - val videoQuality = - when (mediaQuality) { - CompressorQuality.VERY_LOW -> VideoQuality.VERY_LOW - CompressorQuality.LOW -> VideoQuality.LOW - CompressorQuality.MEDIUM -> VideoQuality.MEDIUM - CompressorQuality.HIGH -> VideoQuality.HIGH - CompressorQuality.VERY_HIGH -> VideoQuality.VERY_HIGH - } - Log.d("MediaCompressor", "Using video compression $mediaQuality") - VideoCompressor.start( - // => This is required - context = applicationContext, - // => Source can be provided as content uris - uris = listOf(uri), - isStreamable = false, - // THIS STORAGE - // sharedStorageConfiguration = SharedStorageConfiguration( - // saveAt = SaveLocation.movies, // => default is movies - // videoName = "compressed_video" // => required name - // ), - // OR AND NOT BOTH - appSpecificStorageConfiguration = AppSpecificStorageConfiguration(), - configureWith = - Configuration( - quality = videoQuality, - // => required name - videoNames = listOf(UUID.randomUUID().toString()), - ), - listener = - object : CompressionListener { - override fun onProgress( - index: Int, - percent: Float, - ) {} - - override fun onStart(index: Int) { - // Compression start - } - - override fun onSuccess( - index: Int, - size: Long, - path: String?, - ) { - if (path != null) { - onReady(Uri.fromFile(File(path)), contentType, size) - } else { - onError(R.string.compression_returned_null) - } - } - - override fun onFailure( - index: Int, - failureMessage: String, - ) { - // keeps going with original video - onReady(uri, contentType, null) - } - - override fun onCancelled(index: Int) { - onError(R.string.compression_cancelled) - } - }, - ) - } else if ( - contentType?.startsWith("image", true) == true && - !contentType.contains("gif") && - !contentType.contains("svg") - ) { - val imageQuality = - when (mediaQuality) { - CompressorQuality.VERY_LOW -> 40 - CompressorQuality.LOW -> 50 - CompressorQuality.MEDIUM -> 60 - CompressorQuality.HIGH -> 80 - CompressorQuality.VERY_HIGH -> 90 - } - try { - Log.d("MediaCompressor", "Using image compression $mediaQuality") - val compressedImageFile = - Compressor.compress(applicationContext, from(uri, contentType, applicationContext)) { - default(width = 640, format = Bitmap.CompressFormat.JPEG, quality = imageQuality) + if (contentType?.startsWith("video", true) == true) { + val videoQuality = + when (mediaQuality) { + CompressorQuality.VERY_LOW -> VideoQuality.VERY_LOW + CompressorQuality.LOW -> VideoQuality.LOW + CompressorQuality.MEDIUM -> VideoQuality.MEDIUM + CompressorQuality.HIGH -> VideoQuality.HIGH + CompressorQuality.VERY_HIGH -> VideoQuality.VERY_HIGH + else -> VideoQuality.MEDIUM // dodgy } - onReady(compressedImageFile.toUri(), contentType, compressedImageFile.length()) - } catch (e: Exception) { - if (e is CancellationException) throw e - e.printStackTrace() + Log.d("MediaCompressor", "Using video compression $mediaQuality") + VideoCompressor.start( + // => This is required + context = applicationContext, + // => Source can be provided as content uris + uris = listOf(uri), + isStreamable = false, + // THIS STORAGE + // sharedStorageConfiguration = SharedStorageConfiguration( + // saveAt = SaveLocation.movies, // => default is movies + // videoName = "compressed_video" // => required name + // ), + // OR AND NOT BOTH + appSpecificStorageConfiguration = AppSpecificStorageConfiguration(), + configureWith = + Configuration( + quality = videoQuality, + // => required name + videoNames = listOf(UUID.randomUUID().toString()), + ), + listener = + object : CompressionListener { + override fun onProgress( + index: Int, + percent: Float, + ) { + } + + override fun onStart(index: Int) { + // Compression start + } + + override fun onSuccess( + index: Int, + size: Long, + path: String?, + ) { + if (path != null) { + Log.d("MediaCompressor", "Video compression success. Compressed size [$size]") + onReady(Uri.fromFile(File(path)), contentType, size) + } else { + Log.d("MediaCompressor", "Video compression successful, but returned null path") + onError(R.string.compression_returned_null) + } + } + + override fun onFailure( + index: Int, + failureMessage: String, + ) { + // keeps going with original video + Log.d("MediaCompressor", "Video compression failed: $failureMessage") + onReady(uri, contentType, null) + } + + override fun onCancelled(index: Int) { + onError(R.string.compression_cancelled) + } + }, + ) + } else if ( + contentType?.startsWith("image", true) == true && + !contentType.contains("gif") && + !contentType.contains("svg") + ) { + val imageQuality = + when (mediaQuality) { + CompressorQuality.VERY_LOW -> 40 + CompressorQuality.LOW -> 50 + CompressorQuality.MEDIUM -> 60 + CompressorQuality.HIGH -> 80 + CompressorQuality.VERY_HIGH -> 90 + else -> 60 + } + try { + Log.d("MediaCompressor", "Using image compression $mediaQuality") + val tempFile = from(uri, contentType, applicationContext) + val compressedImageFile = + Compressor.compress(applicationContext, tempFile) { + default(width = 640, format = Bitmap.CompressFormat.JPEG, quality = imageQuality) + } + Log.d("MediaCompressor", "Image compression success. Original size [${tempFile.length()}], new size [${compressedImageFile.length()}]") + onReady(compressedImageFile.toUri(), contentType, compressedImageFile.length()) + } catch (e: Exception) { + Log.d("MediaCompressor", "Image compression failed: ${e.message}") + if (e is CancellationException) throw e + e.printStackTrace() + onReady(uri, contentType, null) + } + } else { onReady(uri, contentType, null) } } else { + Log.d("MediaCompressor", "UNCOMPRESSED quality selected, skip compression and continue with original media.") onReady(uri, contentType, null) } } @@ -188,6 +202,7 @@ class MediaCompressor { 0 -> CompressorQuality.LOW 1 -> CompressorQuality.MEDIUM 2 -> CompressorQuality.HIGH + 3 -> CompressorQuality.UNCOMPRESSED else -> CompressorQuality.MEDIUM } @@ -196,6 +211,7 @@ class MediaCompressor { CompressorQuality.LOW -> 0 CompressorQuality.MEDIUM -> 1 CompressorQuality.HIGH -> 2 + CompressorQuality.UNCOMPRESSED -> 3 else -> 1 } } @@ -206,4 +222,5 @@ enum class CompressorQuality { MEDIUM, HIGH, VERY_HIGH, + UNCOMPRESSED, }