first commit
This commit is contained in:
commit
669f49b1d6
342 files changed
+320811
No files matched your search
@@ -0,0 +1,196 @@
|
||||
# 04_播放控制与音频焦点流程
|
||||
|
||||
## 页面按钮控制流程
|
||||
|
||||
```text
|
||||
1. 用户点击蓝牙音乐页面按钮
|
||||
↓
|
||||
2. BluetoothMusicActivity.onClick()
|
||||
↓
|
||||
3. 根据按钮 ID 判断动作
|
||||
↓
|
||||
4. 调用 BtMusicViewModel
|
||||
↓
|
||||
5. BtMusicViewModel 调用 BtMusicControlManager
|
||||
↓
|
||||
6. BtMusicControlManager 调用 BtMusicManager
|
||||
↓
|
||||
7. BtMusicManager 调用 BluetoothAvrcpClient
|
||||
↓
|
||||
8. BluetoothAvrcpClient 调用 MediaController.TransportControls
|
||||
↓
|
||||
9. 手机音乐 App 响应
|
||||
```
|
||||
|
||||
## 页面按钮映射
|
||||
|
||||
| 控件 ID | 方法 | 最终 AVRCP 控制 |
|
||||
|---|---|---|
|
||||
| `iv_bt_music_pre` | `preBtMusic()` | `skipToPrevious()` |
|
||||
| `iv_bt_music_state` | `playBtMusic()` / `pauseBtMusic()` | `play()` / `pause()` |
|
||||
| `iv_bt_music_next` | `nextBtMusic()` | `skipToNext()` |
|
||||
|
||||
## 播放命令详细链路
|
||||
|
||||
```text
|
||||
BluetoothMusicActivity.onClick()
|
||||
↓
|
||||
mViewModel.playBtMusic()
|
||||
↓
|
||||
BtMusicViewModel.playBtMusic()
|
||||
↓
|
||||
BtMusicControlManager.playBtMusic()
|
||||
↓
|
||||
BtMusicManager.requestFocus()
|
||||
↓
|
||||
BtMusicAudioManager.requestAudioFocus()
|
||||
↓
|
||||
BtMusicManager.playBtMusic()
|
||||
↓
|
||||
BluetoothAvrcpClient.play()
|
||||
↓
|
||||
TransportControls.play()
|
||||
```
|
||||
|
||||
## 暂停命令详细链路
|
||||
|
||||
```text
|
||||
BluetoothMusicActivity.onClick()
|
||||
↓
|
||||
mViewModel.pauseBtMusic()
|
||||
↓
|
||||
BtMusicViewModel.pauseBtMusic()
|
||||
↓
|
||||
BtMusicControlManager.pauseBtMusic()
|
||||
↓
|
||||
BtMusicManager.pauseBtMusic()
|
||||
↓
|
||||
BluetoothAvrcpClient.pause()
|
||||
↓
|
||||
TransportControls.pause()
|
||||
```
|
||||
|
||||
## 切歌命令详细链路
|
||||
|
||||
```text
|
||||
上一曲:
|
||||
BluetoothMusicActivity
|
||||
↓
|
||||
BtMusicViewModel.preBtMusic()
|
||||
↓
|
||||
BtMusicControlManager.preBtMusic()
|
||||
↓
|
||||
BtMusicManager.preBtMusic()
|
||||
↓
|
||||
BluetoothAvrcpClient.previous()
|
||||
↓
|
||||
TransportControls.skipToPrevious()
|
||||
|
||||
下一曲:
|
||||
BluetoothMusicActivity
|
||||
↓
|
||||
BtMusicViewModel.nextBtMusic()
|
||||
↓
|
||||
BtMusicControlManager.nextBtMusic()
|
||||
↓
|
||||
BtMusicManager.nextBtMusic()
|
||||
↓
|
||||
BluetoothAvrcpClient.next()
|
||||
↓
|
||||
TransportControls.skipToNext()
|
||||
```
|
||||
|
||||
## 音频焦点是什么
|
||||
|
||||
```text
|
||||
音频焦点 = 当前谁有资格出声
|
||||
|
||||
车机里可能同时有:
|
||||
蓝牙音乐
|
||||
收音机
|
||||
USB 音乐
|
||||
视频
|
||||
导航播报
|
||||
蓝牙电话
|
||||
|
||||
所以蓝牙音乐播放前必须申请焦点。
|
||||
```
|
||||
|
||||
## 焦点申请流程
|
||||
|
||||
```text
|
||||
1. 用户点击播放
|
||||
↓
|
||||
2. BtMusicManager.requestFocus()
|
||||
↓
|
||||
3. BtMusicAudioManager.requestAudioFocus()
|
||||
↓
|
||||
4. AudioManager.requestAudioFocus()
|
||||
↓
|
||||
5. 如果返回 AUDIOFOCUS_REQUEST_GRANTED
|
||||
↓
|
||||
6. setA2dpUnMute()
|
||||
↓
|
||||
7. isFocus = true
|
||||
↓
|
||||
8. setMediaButtonEvent()
|
||||
↓
|
||||
9. 允许执行 AVRCP play()
|
||||
```
|
||||
|
||||
## 焦点变化处理
|
||||
|
||||
| 焦点变化 | 处理 |
|
||||
|---|---|
|
||||
| `AUDIOFOCUS_GAIN` | 恢复 A2DP 出声,必要时恢复播放,通知语音当前是蓝牙音乐。 |
|
||||
| `AUDIOFOCUS_LOSS` | 释放焦点,暂停蓝牙音乐,清空 Launcher 蓝牙音乐信息。 |
|
||||
| `AUDIOFOCUS_LOSS_TRANSIENT` | 临时失焦,A2DP 静音,暂停蓝牙音乐。 |
|
||||
| `AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK` | 降低蓝牙音乐音量。 |
|
||||
|
||||
## 失焦流程
|
||||
|
||||
```text
|
||||
1. 其他音源抢焦点
|
||||
↓
|
||||
2. BtMusicAudioManager.mAudioFocusListener.onAudioFocusChange()
|
||||
↓
|
||||
3. 收到 AUDIOFOCUS_LOSS 或 AUDIOFOCUS_LOSS_TRANSIENT
|
||||
↓
|
||||
4. 记录当前是否正在播放
|
||||
↓
|
||||
5. setA2dpMute()
|
||||
↓
|
||||
6. BtMusicManager.pauseBtMusic()
|
||||
↓
|
||||
7. 手机音乐暂停
|
||||
```
|
||||
|
||||
## 恢复焦点流程
|
||||
|
||||
```text
|
||||
1. 蓝牙音乐重新获得焦点
|
||||
↓
|
||||
2. 收到 AUDIOFOCUS_GAIN
|
||||
↓
|
||||
3. isFocus = true
|
||||
↓
|
||||
4. setA2dpUnMute()
|
||||
↓
|
||||
5. 如果 isPlayingLossFocus == true
|
||||
↓
|
||||
6. BtMusicManager.playBtMusic()
|
||||
↓
|
||||
7. 手机音乐恢复播放
|
||||
```
|
||||
|
||||
## 注意点
|
||||
|
||||
`BluetoothA2dpSinkClient` 中这两个方法底层调用目前被注释:
|
||||
|
||||
```text
|
||||
setFluorideAudioTrackGain()
|
||||
setFluorideStreaming()
|
||||
```
|
||||
|
||||
所以焦点切换时,A2DP 静音/恢复是否真正生效,需要真机验证。
|
||||
|
||||
Reference in new issue
Block a user