mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-04 19:48:53 +00:00
android, desktop: catching decoding errors (#3314)
This commit is contained in:
+1
-1
@@ -200,7 +200,7 @@ actual class VideoPlayer actual constructor(
|
||||
private fun setPreviewAndDuration() {
|
||||
// It freezes main thread, doing it in IO thread
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val previewAndDuration = VideoPlayerHolder.previewsAndDurations.getOrPut(uri) { getBitmapFromVideo(uri) }
|
||||
val previewAndDuration = VideoPlayerHolder.previewsAndDurations.getOrPut(uri) { getBitmapFromVideo(uri, withAlertOnException = false) }
|
||||
withContext(Dispatchers.Main) {
|
||||
preview.value = previewAndDuration.preview ?: defaultPreview
|
||||
duration.value = (previewAndDuration.duration ?: 0)
|
||||
|
||||
+29
-35
@@ -233,17 +233,13 @@ actual fun getFileSize(uri: URI): Long? {
|
||||
|
||||
actual fun getBitmapFromUri(uri: URI, withAlertOnException: Boolean): ImageBitmap? {
|
||||
return if (Build.VERSION.SDK_INT >= 28) {
|
||||
val source = ImageDecoder.createSource(androidAppContext.contentResolver, uri.toUri())
|
||||
try {
|
||||
val source = ImageDecoder.createSource(androidAppContext.contentResolver, uri.toUri())
|
||||
ImageDecoder.decodeBitmap(source)
|
||||
} catch (e: android.graphics.ImageDecoder.DecodeException) {
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to decode the image: ${e.stackTraceToString()}")
|
||||
if (withAlertOnException) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.image_decoding_exception_title),
|
||||
text = generalGetString(MR.strings.image_decoding_exception_desc)
|
||||
)
|
||||
}
|
||||
if (withAlertOnException) showImageDecodingException()
|
||||
|
||||
null
|
||||
}
|
||||
} else {
|
||||
@@ -253,17 +249,13 @@ actual fun getBitmapFromUri(uri: URI, withAlertOnException: Boolean): ImageBitma
|
||||
|
||||
actual fun getBitmapFromByteArray(data: ByteArray, withAlertOnException: Boolean): ImageBitmap? {
|
||||
return if (Build.VERSION.SDK_INT >= 31) {
|
||||
val source = ImageDecoder.createSource(data)
|
||||
try {
|
||||
val source = ImageDecoder.createSource(data)
|
||||
ImageDecoder.decodeBitmap(source)
|
||||
} catch (e: android.graphics.ImageDecoder.DecodeException) {
|
||||
Log.e(TAG, "Unable to decode the image: ${e.stackTraceToString()}")
|
||||
if (withAlertOnException) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.image_decoding_exception_title),
|
||||
text = generalGetString(MR.strings.image_decoding_exception_desc)
|
||||
)
|
||||
}
|
||||
if (withAlertOnException) showImageDecodingException()
|
||||
|
||||
null
|
||||
}
|
||||
} else {
|
||||
@@ -273,17 +265,13 @@ actual fun getBitmapFromByteArray(data: ByteArray, withAlertOnException: Boolean
|
||||
|
||||
actual fun getDrawableFromUri(uri: URI, withAlertOnException: Boolean): Any? {
|
||||
return if (Build.VERSION.SDK_INT >= 28) {
|
||||
val source = ImageDecoder.createSource(androidAppContext.contentResolver, uri.toUri())
|
||||
try {
|
||||
val source = ImageDecoder.createSource(androidAppContext.contentResolver, uri.toUri())
|
||||
ImageDecoder.decodeDrawable(source)
|
||||
} catch (e: android.graphics.ImageDecoder.DecodeException) {
|
||||
if (withAlertOnException) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.image_decoding_exception_title),
|
||||
text = generalGetString(MR.strings.image_decoding_exception_desc)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error while decoding drawable: ${e.stackTraceToString()}")
|
||||
if (withAlertOnException) showImageDecodingException()
|
||||
|
||||
null
|
||||
}
|
||||
} else {
|
||||
@@ -304,23 +292,29 @@ actual suspend fun saveTempImageUncompressed(image: ImageBitmap, asPng: Boolean)
|
||||
ChatModel.filesToDelete.add(this)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Util.kt saveTempImageUncompressed error: ${e.message}")
|
||||
Log.e(TAG, "Utils.android saveTempImageUncompressed error: ${e.message}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
actual suspend fun getBitmapFromVideo(uri: URI, timestamp: Long?, random: Boolean): VideoPlayerInterface.PreviewAndDuration {
|
||||
val mmr = MediaMetadataRetriever()
|
||||
mmr.setDataSource(androidAppContext, uri.toUri())
|
||||
val durationMs = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong()
|
||||
val image = when {
|
||||
timestamp != null -> mmr.getFrameAtTime(timestamp * 1000, MediaMetadataRetriever.OPTION_CLOSEST)
|
||||
random -> mmr.frameAtTime
|
||||
else -> mmr.getFrameAtTime(0)
|
||||
actual suspend fun getBitmapFromVideo(uri: URI, timestamp: Long?, random: Boolean, withAlertOnException: Boolean): VideoPlayerInterface.PreviewAndDuration =
|
||||
try {
|
||||
val mmr = MediaMetadataRetriever()
|
||||
mmr.setDataSource(androidAppContext, uri.toUri())
|
||||
val durationMs = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong()
|
||||
val image = when {
|
||||
timestamp != null -> mmr.getFrameAtTime(timestamp * 1000, MediaMetadataRetriever.OPTION_CLOSEST)
|
||||
random -> mmr.frameAtTime
|
||||
else -> mmr.getFrameAtTime(0)
|
||||
}
|
||||
mmr.release()
|
||||
VideoPlayerInterface.PreviewAndDuration(image?.asImageBitmap(), durationMs, timestamp ?: 0)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Utils.android getBitmapFromVideo error: ${e.message}")
|
||||
if (withAlertOnException) showVideoDecodingException()
|
||||
|
||||
VideoPlayerInterface.PreviewAndDuration(null, 0, 0)
|
||||
}
|
||||
mmr.release()
|
||||
return VideoPlayerInterface.PreviewAndDuration(image?.asImageBitmap(), durationMs, timestamp ?: 0)
|
||||
}
|
||||
|
||||
actual fun ByteArray.toBase64StringForPassphrase(): String = Base64.encodeToString(this, Base64.DEFAULT)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user