diff --git a/Sources/Media/IOMixer.swift b/Sources/Media/IOMixer.swift index f081a3f5b..8e6f1c8e2 100644 --- a/Sources/Media/IOMixer.swift +++ b/Sources/Media/IOMixer.swift @@ -19,6 +19,7 @@ protocol IOMixerDelegate: AnyObject { func mixer(_ mixer: IOMixer, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) func mixer(_ mixer: IOMixer, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) #endif + func mixerSessionWillResume(_ mixer: IOMixer) } /// An object that mixies audio and video for streaming. @@ -323,6 +324,11 @@ extension IOMixer: Running { isRunning.mutate { $0 = session.isRunning } } + func startCaptureSession() { + session.startRunning() + isRunning.mutate { $0 = session.isRunning } + } + private func addSessionObservers(_ session: AVCaptureSession) { NotificationCenter.default.addObserver(self, selector: #selector(sessionRuntimeError(_:)), name: .AVCaptureSessionRuntimeError, object: session) #if os(iOS) @@ -438,8 +444,7 @@ extension IOMixer: Running { guard isRunning.value && !session.isRunning else { return } - session.startRunning() - isRunning.mutate { $0 = session.isRunning } + delegate?.mixerSessionWillResume(self) } } #else diff --git a/Sources/Net/NetStream.swift b/Sources/Net/NetStream.swift index 24807733d..f1f8499df 100644 --- a/Sources/Net/NetStream.swift +++ b/Sources/Net/NetStream.swift @@ -40,7 +40,11 @@ open class NetStream: NSObject { private static let queueValue = UnsafeMutableRawPointer.allocate(byteCount: 1, alignment: 1) /// The mixer object. - public private(set) var mixer = IOMixer() + public private(set) lazy var mixer: IOMixer = { + let mixer = IOMixer() + mixer.delegate = self + return mixer + }() /// Specifies the delegate of the NetStream. public weak var delegate: (any NetStreamDelegate)? @@ -282,6 +286,33 @@ open class NetStream: NSObject { } } +extension NetStream: IOMixerDelegate { + // MARK: IOMixerDelegate + func mixer(_ mixer: IOMixer, didOutput video: CMSampleBuffer) { + delegate?.stream(self, didOutput: video) + } + + func mixer(_ mixer: IOMixer, didOutput audio: AVAudioPCMBuffer, presentationTimeStamp: CMTime) { + delegate?.stream(self, didOutput: audio, presentationTimeStamp: presentationTimeStamp) + } + + func mixerSessionWillResume(_ mixer: IOMixer) { + lockQueue.async { + mixer.startCaptureSession() + } + } + + #if os(iOS) + func mixer(_ mixer: IOMixer, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) { + delegate?.stream(self, sessionWasInterrupted: session, reason: reason) + } + + func mixer(_ mixer: IOMixer, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) { + delegate?.stream(self, sessionInterruptionEnded: session, reason: reason) + } + #endif +} + extension NetStream: IOScreenCaptureUnitDelegate { // MARK: IOScreenCaptureUnitDelegate public func session(_ session: any IOScreenCaptureUnit, didOutput pixelBuffer: CVPixelBuffer, presentationTime: CMTime) { diff --git a/Sources/RTMP/RTMPStream.swift b/Sources/RTMP/RTMPStream.swift index 312a801ab..db0471ccc 100644 --- a/Sources/RTMP/RTMPStream.swift +++ b/Sources/RTMP/RTMPStream.swift @@ -638,25 +638,3 @@ extension RTMPStream: RTMPMuxerDelegate { return delegate?.streamWillDropFrame(self) ?? false } } - -extension RTMPStream: IOMixerDelegate { - // MARK: IOMixerDelegate - func mixer(_ mixer: IOMixer, didOutput video: CMSampleBuffer) { - frameCount += 1 - delegate?.stream(self, didOutput: video) - } - - func mixer(_ mixer: IOMixer, didOutput audio: AVAudioPCMBuffer, presentationTimeStamp: CMTime) { - delegate?.stream(self, didOutput: audio, presentationTimeStamp: presentationTimeStamp) - } - - #if os(iOS) - func mixer(_ mixer: IOMixer, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) { - delegate?.stream(self, sessionWasInterrupted: session, reason: reason) - } - - func mixer(_ mixer: IOMixer, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) { - delegate?.stream(self, sessionInterruptionEnded: session, reason: reason) - } - #endif -}