V1.3.2: 音量控制只作用于 App 内部输出, 不再修改系统音量

三处入口全部收敛到 applyPlaybackMode():
- 播放界面-调音(全屏音量面板 showFullScreenVolumeDialog() 与调音弹窗
  showAudioControlDialog() 的音乐音量滑杆)
- 声音设置-歌曲最大音量
- 远程控制-音乐音量(mobile PATCH /api/v1/player/audio -> remoteAudio())

musicVolume(0-100) 作为 App 内部输出音量, 按线性系数施加到主播放器
(KtvVideoView.setPlaybackVolume / selectAudioChannel)与副音轨播放器
(vocalPlayer / embeddedVocalEngine); 删除 applySystemMusicVolume() 及其 4 处调用,
AudioManager.setStreamVolume / getStreamMaxVolume 已全部移除。

副作用修正: 原先 App 音量 70% 时既把系统音量压到 70%、又把播放器衰减到 70%,
实际响度只有约 49%(重复衰减); 现在只衰减一次, 100% 即 unity gain。

版本号 1.3.1 -> 1.3.2(versionCode 7 -> 8)。按约定本次不发布 Release, 仅本地打包测试。
This commit is contained in:
zijunchiang
2026-09-14 03:20:17 +08:00
parent 221516f319
commit 0549f910a6
3 changed files with 21 additions and 14 deletions
+9 -1
View File
@@ -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)
+2 -2
View File
@@ -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,否则
+10 -11
View File
@@ -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)