Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Audio Focus Handling | |
| 2 | |
| 3 Audio focus handling is part of the default media session on desktop, which | |
| 4 manages the mixing of MediaSessions. | |
|
whywhat
2016/09/27 17:54:17
Expand on what MediaSession is unless we have a do
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 5 | |
| 6 [TOC] | |
| 7 | |
| 8 ## Processing model | |
| 9 | |
| 10 ### Audio focus types | |
| 11 | |
| 12 There are "persistent" and "transient" audio focus types. Persistent audios | |
| 13 should not mix with each other and transient audio should play on top of | |
|
whywhat
2016/09/27 17:54:16
Audio playback with persistent audio focus stops o
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Elaborated a bit here. But we treat Pepper as Pers
| |
| 14 persistent audio. | |
| 15 | |
| 16 ### `MediaSession` | |
| 17 | |
| 18 Audio-producing objects should join `MediaSession` when they want to produce | |
| 19 sound. `MediaSession` has the following states: | |
| 20 | |
| 21 * ACTIVE: the `MediaSession` has audio focus and should be play normally. | |
|
whywhat
2016/09/27 17:54:16
s/be play/be played
What does "normally" mean? Ma
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 22 * SUSPENDED: the MediaSession does not has audio focus. All audio-producing | |
|
whywhat
2016/09/27 17:54:16
s/has/have
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 23 objects are paused and can be resumed when the session resumes. | |
|
whywhat
2016/09/27 17:54:16
s/resumes/gains audio focus or is resumed by user?
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 24 * INACTIVE: the MediaSession does not has audio focus, and there is no | |
|
whywhat
2016/09/27 17:54:16
s/has/have
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 25 audio-producing objects in this `MediaSession`. | |
| 26 | |
| 27 Besides, `MediaSession` has a `DUCKING` flag, which means its managed | |
| 28 audio-producing objects has lowered volume. The flag is orthogonal with | |
| 29 `MediaSession` state. | |
| 30 | |
| 31 ### `AudioFocusManager` | |
| 32 | |
| 33 `AudioFocusManager` is a global instance which manages the state of | |
| 34 `MediaSession`s. | |
| 35 | |
| 36 When an audio-producing object wants to play audio, it should join `MediaSession ` | |
| 37 and tell which kind of audio focus type it requires. `MediaSession` will then | |
| 38 request audio focus from `AudioFocusManager`, and will allow the object to play | |
| 39 sound if successful. `AudioFocusManager` will notify other `MediaSession`s if | |
| 40 their states are changed. | |
| 41 | |
| 42 When an audio-producing object stops playing audio, it should be removed from | |
| 43 its `MediaSession`, and `MediaSession` should abandon its audio focus if there | |
| 44 are no audio-producing object is managed by it. `AudioFocusManager` will notify | |
|
whywhat
2016/09/27 17:54:16
s/is// or maybe just say if it's empty?
Zhiqiang Zhang (Slow)
2016/09/28 16:12:17
Done.
| |
| 45 other `MediaSession`s of state change if necessary. | |
| 46 | |
| 47 ## The algorithm for handling audio focus | |
| 48 | |
| 49 `AudioFocusManager` uses a stack implementation. It keeps track of all | |
| 50 ACTIVE/SUSPENDED `MediaSession`s. When a `MediaSession` requests audio focus, it | |
| 51 will be put at the top of the stack, and will be removed from the stack when it | |
| 52 abandons audio focus. | |
| 53 | |
| 54 The algorithm is as follows: | |
| 55 | |
| 56 * When a `MediaSession` requests audio focus: | |
| 57 | |
| 58 * Remove it from the audio focus stack, and place it at the top of audio | |
|
whywhat
2016/09/27 17:54:16
"Remove it from the audio focus stack if it's alre
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
| 59 focus stack, grant focus to the session and let it play. | |
| 60 * If the session is persistent, suspend all sessions on the stack | |
|
whywhat
2016/09/27 17:54:16
s/all/all the other
Zhiqiang Zhang (Slow)
2016/09/28 16:12:17
Done.
| |
| 61 * If the session is transient: | |
| 62 | |
| 63 * If the next top entry is transient, do nothing. | |
| 64 * If the next top entry is persistent, let the next top entry start ducking. | |
|
whywhat
2016/09/27 17:54:16
Maybe clarify we took care of the remaining sessio
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Sorry, I'm not very sure of what you mean here. Ca
whywhat
2016/09/29 22:40:47
I meant, clarify why we only duck the top session,
| |
| 65 | |
| 66 * When a `MediaSession` abandons audio focus: | |
| 67 | |
| 68 * If the session is not on the top, just remove it from the stack. | |
| 69 * If the session is on the top, remove it from the stack. | |
| 70 | |
| 71 * If the stack becomes empty, do nothing. | |
| 72 * If the next top session is transient, do nothing. | |
| 73 * If the next top session is persistent, stop ducking it. | |
| 74 | |
| 75 ### Handling Pepper | |
| 76 | |
| 77 Pepper is different from media elements since it has a different model. Pepper | |
| 78 cannot be paused, but its volume can be changed. When considering Pepper, the | |
| 79 above algorithm must be modified. | |
| 80 | |
| 81 When Pepper joins `MediaSession`, it should request persistent focus type. When | |
| 82 AudioFocusManager wants to suspend a `MediaSession`, it must check whether the | |
| 83 session has Pepper instance, and if yes, it should duck the session instead. | |
| 84 | |
| 85 Also, whenever a session abandons focus, and the next top session is INACTIVE, | |
| 86 `AudioFocusManager` should find the next session having Pepper and unduck it. | |
| OLD | NEW |