@@ -33,101 +33,6 @@ private final class ChunkMediaPlayerExternalSourceImpl: ChunkMediaPlayerSourceIm
3333}
3434
3535public final class ChunkMediaPlayerV2 : ChunkMediaPlayer {
36- public final class AudioContext {
37- fileprivate let audioSessionManager : ManagedAudioSession
38- private var audioSessionDisposable : Disposable ?
39- private( set) var hasAudioSession : Bool = false
40- private( set) var isAmbientMode : Bool = false
41- private( set) var isInitialized : Bool = false
42-
43- private var updatedListeners = Bag < ( ) -> Void > ( )
44-
45- public init (
46- audioSessionManager: ManagedAudioSession
47- ) {
48- self . audioSessionManager = audioSessionManager
49- }
50-
51- deinit {
52- self . audioSessionDisposable? . dispose ( )
53- }
54-
55- func onUpdated( _ f: @escaping ( ) -> Void ) -> Disposable {
56- let index = self . updatedListeners. add ( f)
57- return ActionDisposable { [ weak self] in
58- Queue . mainQueue ( ) . async {
59- guard let self else {
60- return
61- }
62- self . updatedListeners. remove ( index)
63- }
64- }
65- }
66-
67- func setIsAmbient( isAmbient: Bool ) {
68- self . hasAudioSession = false
69-
70- for f in self . updatedListeners. copyItems ( ) {
71- f ( )
72- }
73-
74- self . audioSessionDisposable? . dispose ( )
75- self . audioSessionDisposable = nil
76- }
77-
78- func update( type: ManagedAudioSessionType ? ) {
79- if let type {
80- if self . audioSessionDisposable == nil {
81- self . isInitialized = true
82-
83- self . audioSessionDisposable = self . audioSessionManager. push ( params: ManagedAudioSessionClientParams (
84- audioSessionType: type,
85- activateImmediately: false ,
86- manualActivate: { [ weak self] control in
87- control. setupAndActivate ( synchronous: false , { state in
88- Queue . mainQueue ( ) . async {
89- guard let self else {
90- return
91- }
92- self . hasAudioSession = true
93- for f in self . updatedListeners. copyItems ( ) {
94- f ( )
95- }
96- }
97- } )
98- } ,
99- deactivate: { [ weak self] _ in
100- return Signal { subscriber in
101- guard let self else {
102- subscriber. putCompletion ( )
103- return EmptyDisposable
104- }
105-
106- self . hasAudioSession = false
107- for f in self . updatedListeners. copyItems ( ) {
108- f ( )
109- }
110- subscriber. putCompletion ( )
111-
112- return EmptyDisposable
113- }
114- |> runOn ( . mainQueue( ) )
115- } ,
116- headsetConnectionStatusChanged: { _ in } ,
117- availableOutputsChanged: { _, _ in }
118- ) )
119- }
120- } else {
121- if let audioSessionDisposable = self . audioSessionDisposable {
122- self . audioSessionDisposable = nil
123- audioSessionDisposable. dispose ( )
124- }
125-
126- self . hasAudioSession = false
127- }
128- }
129- }
130-
13136 public enum SourceDescription {
13237 public final class ResourceDescription {
13338 public let postbox : Postbox
@@ -261,10 +166,10 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
261166 private let dataQueue : Queue
262167
263168 private let mediaDataReaderParams : MediaDataReaderParams
169+ private let audioSessionManager : ManagedAudioSession
264170 private let onSeeked : ( ( ) -> Void ) ?
265171 private weak var playerNode : MediaPlayerNode ?
266172
267- private let audioContext : AudioContext
268173 private let renderSynchronizer : AVSampleBufferRenderSynchronizer
269174 private var videoRenderer : AVSampleBufferDisplayLayer
270175 private var audioRenderer : AVSampleBufferAudioRenderer ?
@@ -293,20 +198,13 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
293198 }
294199
295200 public var actionAtEnd : MediaPlayerActionAtEnd = . stop
296- public weak var migrateToNextPlayerOnEnd : ChunkMediaPlayerV2 ? {
297- didSet {
298- if self . migrateToNextPlayerOnEnd !== oldValue {
299- self . updateInternalState ( )
300- }
301- }
302- }
303201
304202 private var didSeekOnce : Bool = false
305203 private var isPlaying : Bool = false
306204 private var baseRate : Double = 1.0
307205 private var isSoundEnabled : Bool
308206 private var isMuted : Bool
309- private var initialIsAmbient : Bool
207+ private var isAmbientMode : Bool
310208
311209 private var seekId : Int = 0
312210 private var seekTimestamp : Double = 0.0
@@ -325,11 +223,12 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
325223 private var partsStateDisposable : Disposable ?
326224 private var updateTimer : Foundation . Timer ?
327225
328- private var audioContextUpdatedDisposable : Disposable ?
226+ private var audioSessionDisposable : Disposable ?
227+ private var hasAudioSession : Bool = false
329228
330229 public init (
331230 params: MediaDataReaderParams ,
332- audioContext : AudioContext ,
231+ audioSessionManager : ManagedAudioSession ,
333232 source: SourceDescription ,
334233 video: Bool ,
335234 playAutomatically: Bool = false ,
@@ -348,7 +247,7 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
348247 self . dataQueue = ChunkMediaPlayerV2 . sharedDataQueue
349248
350249 self . mediaDataReaderParams = params
351- self . audioContext = audioContext
250+ self . audioSessionManager = audioSessionManager
352251 self . onSeeked = onSeeked
353252 self . playerNode = playerNode
354253
@@ -358,7 +257,7 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
358257
359258 self . isSoundEnabled = enableSound
360259 self . isMuted = soundMuted
361- self . initialIsAmbient = ambient
260+ self . isAmbientMode = ambient
362261 self . baseRate = baseRate
363262
364263 self . renderSynchronizer = AVSampleBufferRenderSynchronizer ( )
@@ -397,19 +296,12 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
397296 } else {
398297 self . renderSynchronizer. addRenderer ( self . videoRenderer)
399298 }
400-
401- self . audioContextUpdatedDisposable = self . audioContext. onUpdated ( { [ weak self] in
402- guard let self else {
403- return
404- }
405- self . updateInternalState ( )
406- } )
407299 }
408300
409301 deinit {
410302 self . partsStateDisposable? . dispose ( )
411303 self . updateTimer? . invalidate ( )
412- self . audioContextUpdatedDisposable ? . dispose ( )
304+ self . audioSessionDisposable ? . dispose ( )
413305
414306 if #available( iOS 17 . 0 , * ) {
415307 self . videoRenderer. sampleBufferRenderer. stopRequestingMediaData ( )
@@ -429,19 +321,51 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
429321 }
430322
431323 private func updateInternalState( ) {
432- var audioSessionType : ManagedAudioSessionType ?
433324 if self . isSoundEnabled && self . hasSound {
434- let isAmbient : Bool
435- if self . audioContext. isInitialized {
436- isAmbient = self . audioContext. isAmbientMode
437- } else {
438- isAmbient = self . initialIsAmbient
325+ if self . audioSessionDisposable == nil {
326+ self . audioSessionDisposable = self . audioSessionManager. push ( params: ManagedAudioSessionClientParams (
327+ audioSessionType: self . isAmbientMode ? . ambient : . play( mixWithOthers: false ) ,
328+ activateImmediately: false ,
329+ manualActivate: { [ weak self] control in
330+ control. setupAndActivate ( synchronous: false , { state in
331+ Queue . mainQueue ( ) . async {
332+ guard let self else {
333+ return
334+ }
335+ self . hasAudioSession = true
336+ self . updateInternalState ( )
337+ }
338+ } )
339+ } ,
340+ deactivate: { [ weak self] _ in
341+ return Signal { subscriber in
342+ guard let self else {
343+ subscriber. putCompletion ( )
344+ return EmptyDisposable
345+ }
346+
347+ self . hasAudioSession = false
348+ self . updateInternalState ( )
349+ subscriber. putCompletion ( )
350+
351+ return EmptyDisposable
352+ }
353+ |> runOn ( . mainQueue( ) )
354+ } ,
355+ headsetConnectionStatusChanged: { _ in } ,
356+ availableOutputsChanged: { _, _ in }
357+ ) )
439358 }
440- audioSessionType = isAmbient ? . ambient : . play( mixWithOthers: false )
359+ } else {
360+ if let audioSessionDisposable = self . audioSessionDisposable {
361+ self . audioSessionDisposable = nil
362+ audioSessionDisposable. dispose ( )
363+ }
364+
365+ self . hasAudioSession = false
441366 }
442- self . audioContext. update ( type: audioSessionType)
443367
444- if self . isSoundEnabled && self . hasSound && self . audioContext . hasAudioSession {
368+ if self . isSoundEnabled && self . hasSound && self . hasAudioSession {
445369 if self . audioRenderer == nil {
446370 let audioRenderer = AVSampleBufferAudioRenderer ( )
447371 audioRenderer. isMuted = self . isMuted
@@ -875,9 +799,13 @@ public final class ChunkMediaPlayerV2: ChunkMediaPlayer {
875799 }
876800
877801 public func continueWithOverridingAmbientMode( isAmbient: Bool ) {
878- if self . audioContext. isAmbientMode != isAmbient {
879- self . initialIsAmbient = isAmbient
880- self . audioContext. setIsAmbient ( isAmbient: isAmbient)
802+ if self . isAmbientMode != isAmbient {
803+ self . isAmbientMode = isAmbient
804+
805+ self . hasAudioSession = false
806+ self . updateInternalState ( )
807+ self . audioSessionDisposable? . dispose ( )
808+ self . audioSessionDisposable = nil
881809
882810 let currentTimestamp : CMTime
883811 if let pendingSeekTimestamp = self . pendingSeekTimestamp {
0 commit comments