diff --git a/AGENTS.md b/AGENTS.md index f18fe5c..04d8b80 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,7 +103,7 @@ $BT/apksigner verify 目标名.apk ### 版本号 -- `app/build.gradle`:`versionName "1.3.1"` / `versionCode 7` +- `app/build.gradle`:`versionName "1.3.2"` / `versionCode 8` - App 内显示统一用纯版本号(不加 `(versionCode)` 括号) ## 三、关键实现约束(避免踩坑) @@ -134,4 +134,12 @@ $BT/apksigner verify 目标名.apk 客户端为 `MiliLog`(有界队列 + 后台线程 + 失败重试),调用点 `MiliLog.info/notice/warn/error` 保持不变。启动上报(`reportDeviceBootInfo()`)只采集这 10 项:包名、版本号、安装时间、品牌、型号、 设备名、Android 版本、CPU 架构、内核版本、屏幕分辨率 +- **音量控制(只控 App 输出,不动系统音量)**:`musicVolume`(0-100) 是 **App 内部输出音量**, + 统一在 `applyPlaybackMode()` 内按线性系数施加到播放器(`KtvVideoView.setPlaybackVolume` / + `selectAudioChannel`)与副音轨播放器(`vocalPlayer` / `embeddedVocalEngine`)。 + **严禁调用 `AudioManager.setStreamVolume` / `adjustStreamVolume` 修改系统音量**。 + 三条入口必须全部收敛到 `applyPlaybackMode()`:播放界面-调音(`showFullScreenVolumeDialog()` 与 + `showAudioControlDialog()` 的音乐音量滑杆)、声音设置-歌曲最大音量、远程控制-音乐音量 + (`remoteAudio()` 的 `musicVolume`)。曲线是纯衰减(100% 即 unity gain),不做系统级增益; + 设备最终响度仍取决于系统音量,App 不再替用户改动它 - **仓库可见性**:Gitea 仓库保持 **public**(若后续把 App 更新/热更新端点迁到 Gitea,非 public 会导致 403) diff --git a/app/build.gradle b/app/build.gradle index 874685a..8018bb1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId "com.local.ktv" minSdk 21 targetSdk 25 - versionCode 7 - versionName "1.3.1" + versionCode 8 + versionName "1.3.2" ndk { // 双 ABI 打包:兼容 64 位(Exynos 1580 等 arm64-v8a)与 32 位设备(极米 Play 超越版 // 的 Amlogic 950X2/S905X2 采用 32 位 Android 用户态,必须包含 armeabi-v7a,否则 diff --git a/app/src/main/java/com/local/ktv/MainActivity.kt b/app/src/main/java/com/local/ktv/MainActivity.kt index 7fb5163..025a844 100644 --- a/app/src/main/java/com/local/ktv/MainActivity.kt +++ b/app/src/main/java/com/local/ktv/MainActivity.kt @@ -2474,7 +2474,7 @@ class MainActivity : AppCompatActivity() { indicator.alpha = 1f indicator.visibility = View.VISIBLE renderMuteButton() - applySystemMusicVolume() + // 只调 App 内部输出音量, 不改系统音量(见 applyPlaybackMode)。 applyPlaybackMode() saveState() main.removeCallbacks(hideFullScreenVolumeIndicatorRunnable) @@ -2631,7 +2631,6 @@ class MainActivity : AppCompatActivity() { } else { musicVolume = muteBeforeVol } - applySystemMusicVolume() applyPlaybackMode() seekMusicVol.setProgress(musicVolume) tvMusicVol.setText(musicVolume.toString()) @@ -2667,7 +2666,6 @@ class MainActivity : AppCompatActivity() { override fun onStartTrackingTouch(s: SeekBar?) {} override fun onStopTrackingTouch(s: SeekBar?) { - applySystemMusicVolume() applyPlaybackMode() saveState() } @@ -2680,7 +2678,6 @@ class MainActivity : AppCompatActivity() { seekMusicVol.setProgress(80) micVolume = 60 musicVolume = 80 - applySystemMusicVolume() applyPlaybackMode() saveState() tvMicVol.setText("60") @@ -4325,13 +4322,6 @@ class MainActivity : AppCompatActivity() { } } - private fun applySystemMusicVolume() { - if (audioManager == null) return - val max = audioManager!!.getStreamMaxVolume(AudioManager.STREAM_MUSIC) - val value = max(0, min(max, (musicVolume * max) / 100)) - audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, value, 0) - } - private fun clamp(value: Int, min: Int, max: Int): Int { return max(min, min(max, value)) } @@ -5397,6 +5387,15 @@ class MainActivity : AppCompatActivity() { persistRuntimeState() } + /** + * 应用原伴唱/声道与输出音量。 + * + * 音量语义:`musicVolume`(0-100) 是 **App 内部输出音量**,按线性系数施加到播放器 + * (`KtvVideoView.setPlaybackVolume` / `selectAudioChannel`) 与副音轨播放器上, + * **绝不修改系统音量**(不调用 `AudioManager.setStreamVolume`)。 + * 播放界面-调音、声音设置-歌曲最大音量、远程控制-音乐音量三处都收敛到这里, + * 保证三条入口行为一致且都不影响系统音量。 + */ private fun applyPlaybackMode() { val videoPlayer = player ?: return videoPlayer.setTone(tone)