Track Android video probing and clean rejected cache files
This commit is contained in:
1 parent
20322e7ecb
commit
8e108425ae
2 files changed
+31
-19
No files matched your search
+2
-1
@@ -62,7 +62,8 @@ fun ConversationComposer(target: ConversationTarget, viewModel: ChatViewModel, o
|
||||
}
|
||||
if (pinned == activeTarget) { selected = attachment; sendAsVideo = false; chooseVideo = attachment.video }
|
||||
else LogManager.addLog("INFO", "Attachment", "picker discarded after target change")
|
||||
} catch (e: Exception) { LogManager.addLog("ERROR", "Attachment", "picker failed: ${e.message}"); error = "Не удалось открыть вложение" }
|
||||
} catch (e: CancellationException) { throw e }
|
||||
catch (e: Exception) { LogManager.addLog("ERROR", "Attachment", "picker failed: ${e.message}"); error = "Не удалось открыть вложение" }
|
||||
}
|
||||
}
|
||||
Column {
|
||||
|
||||
@@ -320,7 +320,7 @@ class ChatViewModel : ViewModel() {
|
||||
}
|
||||
4 -> { if (repo != null) { LogManager.addLog("INFO", "VM", "CHANNEL_UPDATED — refreshChannels"); refreshChannels() } else { LogManager.addLog("WARN", "VM", "CHANNEL_UPDATED skipped — repo is NULL") } }
|
||||
12 -> LogManager.addLog("INFO", "VM", "service started")
|
||||
13 -> LogManager.addLog("INFO", "VM", "service stopped")
|
||||
13 -> { _attachmentPreparations.value = emptyMap(); LogManager.addLog("INFO", "VM", "service stopped") }
|
||||
16 -> { /* NODEINFO_UPDATED: [node_id:8][presence:1][up:1][best_rtt:2][bgp_rtt:2][bgp_nodes:2] */
|
||||
if (data == null || data.size < 12) return
|
||||
val ns = parseNodeStatus(data) ?: return
|
||||
@@ -1024,7 +1024,7 @@ class ChatViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun sendAttachment(filePath: String, target: ConversationTarget, name: String = File(filePath).name) {
|
||||
val r = repo ?: return
|
||||
val r = repo ?: throw IllegalStateException("Сервис чата остановлен")
|
||||
if (target is ConversationTarget.Pm) { NativeLib.dmSendFile(target.id, filePath, name); return }
|
||||
val chId = target.id
|
||||
val ext = filePath.substringAfterLast('.', "").lowercase()
|
||||
@@ -1057,26 +1057,37 @@ class ChatViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
/** Cache-файл передаётся native только после успешного чтения метаданных. */
|
||||
fun sendVideoMessage(filePath: String, target: ConversationTarget) {
|
||||
val r = repo ?: return
|
||||
val job = java.util.UUID.randomUUID().toString()
|
||||
preparationState(target.nativeId, job, 0)
|
||||
viewModelScope.launch {
|
||||
val meta = withContext(Dispatchers.IO) {
|
||||
var dur = 0; var w = 0; var h = 0
|
||||
val mmr = MediaMetadataRetriever()
|
||||
try {
|
||||
mmr.setDataSource(filePath)
|
||||
dur = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toIntOrNull() ?: 0
|
||||
w = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toIntOrNull() ?: 0
|
||||
h = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toIntOrNull() ?: 0
|
||||
} catch (e: Exception) {
|
||||
LogManager.addLog("WARN", "VM", "video metadata failed: ${e.message}")
|
||||
} finally {
|
||||
try { mmr.release() } catch (_: Exception) {}
|
||||
var accepted = false
|
||||
try {
|
||||
val r = repo ?: throw IllegalStateException("Сервис чата остановлен")
|
||||
val meta = withContext(Dispatchers.IO) {
|
||||
val mmr = MediaMetadataRetriever()
|
||||
try {
|
||||
mmr.setDataSource(filePath)
|
||||
Triple(
|
||||
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toIntOrNull() ?: 0,
|
||||
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toIntOrNull() ?: 0,
|
||||
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toIntOrNull() ?: 0
|
||||
)
|
||||
} finally { mmr.release() }
|
||||
}
|
||||
accepted = r.sendVideo(target.nativeId, filePath, meta.first, meta.second, meta.third)
|
||||
if (!accepted) throw IllegalStateException("Некорректное видео или сервис остановлен")
|
||||
LogManager.addLog("INFO", "VM", "video queued target=${target.nativeId} dur=${meta.first} ${meta.second}x${meta.third}")
|
||||
} catch (e: kotlinx.coroutines.CancellationException) { throw e }
|
||||
catch (e: Exception) { LogManager.addLog("ERROR", "VM", "video failed target=${target.nativeId}: ${e.message}") }
|
||||
finally {
|
||||
preparationState(target.nativeId, job, if (accepted) 1 else 2)
|
||||
if (!accepted) withContext(kotlinx.coroutines.NonCancellable + Dispatchers.IO) {
|
||||
if (!File(filePath).delete() && File(filePath).exists())
|
||||
LogManager.addLog("ERROR", "VM", "video cache cleanup failed: $filePath")
|
||||
}
|
||||
Triple(dur, w, h)
|
||||
}
|
||||
LogManager.addLog("INFO", "VM", "sendVideoMessage target=${target.nativeId} dur=${meta.first} ${meta.second}x${meta.third}")
|
||||
r.sendVideo(target.nativeId, filePath, meta.first, meta.second, meta.third)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user