feat(android): 设置持久化(推流参数与连接信息)
This commit is contained in:
@@ -0,0 +1,94 @@
|
|||||||
|
package com.opendance.studio.data
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.content.edit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用设置(SharedPreferences)。
|
||||||
|
*
|
||||||
|
* 契约 websocket-keypoints.md §3.3 的 config 字段与这里的前四项一一对应。
|
||||||
|
*/
|
||||||
|
class AppSettings(context: Context) {
|
||||||
|
|
||||||
|
private val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
/** Windows 客户端主机地址 */
|
||||||
|
var host: String
|
||||||
|
get() = prefs.getString(KEY_HOST, DEFAULT_HOST) ?: DEFAULT_HOST
|
||||||
|
set(value) = prefs.edit { putString(KEY_HOST, value.trim()) }
|
||||||
|
|
||||||
|
var port: Int
|
||||||
|
get() = prefs.getInt(KEY_PORT, DEFAULT_PORT)
|
||||||
|
set(value) = prefs.edit { putInt(KEY_PORT, value.coerceIn(1, 65535)) }
|
||||||
|
|
||||||
|
/** 目标帧率(契约 config.targetFps) */
|
||||||
|
var targetFps: Int
|
||||||
|
get() = prefs.getInt(KEY_TARGET_FPS, DEFAULT_FPS)
|
||||||
|
set(value) = prefs.edit { putInt(KEY_TARGET_FPS, value.coerceIn(5, 60)) }
|
||||||
|
|
||||||
|
/** 是否镜像画面(契约 flags.bit0 / config.mirror) */
|
||||||
|
var mirror: Boolean
|
||||||
|
get() = prefs.getBoolean(KEY_MIRROR, true)
|
||||||
|
set(value) = prefs.edit { putBoolean(KEY_MIRROR, value) }
|
||||||
|
|
||||||
|
/** 仅上半身模式(契约 flags.bit2) */
|
||||||
|
var upperBodyOnly: Boolean
|
||||||
|
get() = prefs.getBoolean(KEY_UPPER_BODY, false)
|
||||||
|
set(value) = prefs.edit { putBoolean(KEY_UPPER_BODY, value) }
|
||||||
|
|
||||||
|
/** 分辨率档位,取值见 [Resolutions] */
|
||||||
|
var resolution: String
|
||||||
|
get() = prefs.getString(KEY_RESOLUTION, Resolutions.MEDIUM) ?: Resolutions.MEDIUM
|
||||||
|
set(value) = prefs.edit { putString(KEY_RESOLUTION, value) }
|
||||||
|
|
||||||
|
/** 上次连接的设备名(hello 上报用) */
|
||||||
|
var deviceLabel: String
|
||||||
|
get() = prefs.getString(KEY_DEVICE_LABEL, "") ?: ""
|
||||||
|
set(value) = prefs.edit { putString(KEY_DEVICE_LABEL, value) }
|
||||||
|
|
||||||
|
/** 自动重连 */
|
||||||
|
var autoReconnect: Boolean
|
||||||
|
get() = prefs.getBoolean(KEY_AUTO_RECONNECT, true)
|
||||||
|
set(value) = prefs.edit { putBoolean(KEY_AUTO_RECONNECT, value) }
|
||||||
|
|
||||||
|
fun webSocketUrl(): String = "ws://$host:$port/pose"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val PREFS_NAME = "opendance_settings"
|
||||||
|
const val DEFAULT_HOST = "192.168.1.100"
|
||||||
|
const val DEFAULT_PORT = 8765
|
||||||
|
const val DEFAULT_FPS = 30
|
||||||
|
|
||||||
|
private const val KEY_HOST = "host"
|
||||||
|
private const val KEY_PORT = "port"
|
||||||
|
private const val KEY_TARGET_FPS = "target_fps"
|
||||||
|
private const val KEY_MIRROR = "mirror"
|
||||||
|
private const val KEY_UPPER_BODY = "upper_body_only"
|
||||||
|
private const val KEY_RESOLUTION = "resolution"
|
||||||
|
private const val KEY_DEVICE_LABEL = "device_label"
|
||||||
|
private const val KEY_AUTO_RECONNECT = "auto_reconnect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 分辨率档位 —— 与契约 config.resolution 的取值格式一致 */
|
||||||
|
object Resolutions {
|
||||||
|
const val LOW = "480x360"
|
||||||
|
const val MEDIUM = "640x480"
|
||||||
|
const val HIGH = "1280x720"
|
||||||
|
|
||||||
|
val ALL = listOf(LOW, MEDIUM, HIGH)
|
||||||
|
|
||||||
|
/** 返回 (宽, 高) */
|
||||||
|
fun parse(value: String): Pair<Int, Int> {
|
||||||
|
val parts = value.split("x")
|
||||||
|
val w = parts.getOrNull(0)?.toIntOrNull() ?: 640
|
||||||
|
val h = parts.getOrNull(1)?.toIntOrNull() ?: 480
|
||||||
|
return w to h
|
||||||
|
}
|
||||||
|
|
||||||
|
fun label(value: String): String = when (value) {
|
||||||
|
LOW -> "低(480×360,最省电)"
|
||||||
|
HIGH -> "高(1280×720,最清晰)"
|
||||||
|
else -> "中(640×480,推荐)"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user