mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-05-07 20:12:28 +00:00
Redesign RTMPConnecitonDelegate and RTMPStreamDelegate.
This commit is contained in:
@@ -31,6 +31,8 @@ final class LiveViewController: UIViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
rtmpConnection.delegate = self
|
||||
|
||||
pipIntentView.layer.borderWidth = 1.0
|
||||
pipIntentView.layer.borderColor = UIColor.white.cgColor
|
||||
pipIntentView.bounds = MultiCamCaptureSettings.default.regionOfInterest
|
||||
@@ -41,7 +43,6 @@ final class LiveViewController: UIViewController {
|
||||
if let orientation = DeviceUtil.videoOrientation(by: UIApplication.shared.statusBarOrientation) {
|
||||
rtmpStream.videoOrientation = orientation
|
||||
}
|
||||
rtmpStream.delegate = self
|
||||
rtmpStream.videoSettings.videoSize = .init(width: 720, height: 1280)
|
||||
rtmpStream.mixer.recorder.delegate = self
|
||||
videoBitrateSlider?.value = Float(VideoCodecSettings.default.bitRate) / 1000
|
||||
@@ -280,6 +281,26 @@ final class LiveViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
extension LiveViewController: RTMPConnectionDelegate {
|
||||
func connection(_ connection: RTMPConnection, publishInsufficientBWOccured stream: RTMPStream) {
|
||||
// Adaptive bitrate streaming exsample. Please feedback me your good algorithm. :D
|
||||
videoBitRate -= 32 * 1000
|
||||
stream.videoSettings.bitRate = max(videoBitRate, 64 * 1000)
|
||||
}
|
||||
|
||||
func connection(_ connection: RTMPConnection, publishSufficientBWOccured stream: RTMPStream) {
|
||||
videoBitRate += 32 * 1000
|
||||
stream.videoSettings.bitRate = min(videoBitRate, VideoCodecSettings.default.bitRate)
|
||||
}
|
||||
|
||||
func connection(_ connection: RTMPConnection, updateStats stream: RTMPStream) {
|
||||
}
|
||||
|
||||
func connection(_ connection: RTMPConnection, didClear stream: RTMPStream) {
|
||||
videoBitRate = VideoCodecSettings.default.bitRate
|
||||
}
|
||||
}
|
||||
|
||||
extension LiveViewController: IORecorderDelegate {
|
||||
// MARK: IORecorderDelegate
|
||||
func recorder(_ recorder: IORecorder, errorOccured error: IORecorder.Error) {
|
||||
@@ -298,42 +319,3 @@ extension LiveViewController: IORecorderDelegate {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
extension LiveViewController: RTMPStreamDelegate {
|
||||
// MARK: RTMPStreamDelegate
|
||||
func rtmpStream(_ stream: RTMPStream, publishInsufficientBWOccured connection: RTMPConnection) {
|
||||
// Adaptive bitrate streaming exsample. Please feedback me your good algorithm. :D
|
||||
videoBitRate -= 32 * 1000
|
||||
stream.videoSettings.bitRate = max(videoBitRate, 64 * 1000)
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, publishSufficientBWOccured connection: RTMPConnection) {
|
||||
videoBitRate += 32 * 1000
|
||||
stream.videoSettings.bitRate = min(videoBitRate, VideoCodecSettings.default.bitRate)
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, didOutput audio: AVAudioBuffer, presentationTimeStamp: CMTime) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, didOutput video: CMSampleBuffer) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, updatedStats connection: RTMPConnection) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, audioCodecErrorOccurred error: HaishinKit.AudioCodec.Error) {
|
||||
}
|
||||
|
||||
func rtmpStream(_ stream: RTMPStream, videoCodecErrorOccurred error: VideoCodec.Error) {
|
||||
}
|
||||
|
||||
func rtmpStreamDidClear(_ stream: RTMPStream) {
|
||||
videoBitRate = VideoCodecSettings.default.bitRate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,24 @@ import CoreMedia
|
||||
import ScreenCaptureKit
|
||||
#endif
|
||||
|
||||
/// The interface a NetStream uses to inform its delegate.
|
||||
public protocol NetStreamDelegate: AnyObject {
|
||||
/// Tells the receiver to playback an audio packet incoming.
|
||||
func stream(_ stream: NetStream, didOutput audio: AVAudioBuffer, presentationTimeStamp: CMTime)
|
||||
/// Tells the receiver to playback a video packet incoming.
|
||||
func stream(_ stream: NetStream, didOutput video: CMSampleBuffer)
|
||||
#if os(iOS)
|
||||
/// Tells the receiver to session was interrupted.
|
||||
func stream(_ stream: NetStream, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason)
|
||||
/// Tells the receiver to session interrupted ended.
|
||||
func stream(_ stream: NetStream, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason)
|
||||
#endif
|
||||
/// Tells the receiver to video codec error occured.
|
||||
func stream(_ stream: NetStream, videoCodecErrorOccurred error: VideoCodec.Error)
|
||||
/// Tells the receiver to audio codec error occured.
|
||||
func stream(_ stream: NetStream, audioCodecErrorOccurred error: AudioCodec.Error)
|
||||
}
|
||||
|
||||
/// The `NetStream` class is the foundation of a RTMPStream, HTTPStream.
|
||||
open class NetStream: NSObject {
|
||||
/// The lockQueue.
|
||||
@@ -19,6 +37,8 @@ open class NetStream: NSObject {
|
||||
|
||||
/// The mixer object.
|
||||
public private(set) var mixer = IOMixer()
|
||||
/// Specifies the delegate of the NetStream.
|
||||
public weak var delegate: NetStreamDelegate?
|
||||
|
||||
/// Specifies the context object.
|
||||
public var context: CIContext {
|
||||
|
||||
@@ -25,6 +25,18 @@ open class RTMPResponder {
|
||||
}
|
||||
}
|
||||
|
||||
/// The interface a RTMPConnectionDelegate uses to inform its delegate.
|
||||
public protocol RTMPConnectionDelegate: AnyObject {
|
||||
/// Tells the receiver to publish insufficient bandwidth occured.
|
||||
func connection(_ connection: RTMPConnection, publishInsufficientBWOccured stream: RTMPStream)
|
||||
/// Tells the receiver to publish sufficient bandwidth occured.
|
||||
func connection(_ connection: RTMPConnection, publishSufficientBWOccured stream: RTMPStream)
|
||||
/// Tells the receiver to update statistics.
|
||||
func connection(_ connection: RTMPConnection, updateStats stream: RTMPStream)
|
||||
/// Tells the receiver to the stream opend.
|
||||
func connection(_ connection: RTMPConnection, didClear stream: RTMPStream)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
/// The RTMPConneciton class create a two-way RTMP connection.
|
||||
open class RTMPConnection: EventDispatcher {
|
||||
@@ -203,6 +215,8 @@ open class RTMPConnection: EventDispatcher {
|
||||
public var totalStreamsCount: Int {
|
||||
streams.count
|
||||
}
|
||||
/// Specifies the delegate of the NetStream.
|
||||
public weak var delegate: RTMPConnectionDelegate?
|
||||
/// The statistics of outgoing queue bytes per second.
|
||||
@objc open private(set) dynamic var previousQueueBytesOut: [Int64] = []
|
||||
/// The statistics of incoming bytes per second.
|
||||
@@ -469,17 +483,17 @@ open class RTMPConnection: EventDispatcher {
|
||||
}
|
||||
if total == measureInterval - 1 {
|
||||
for stream in streams {
|
||||
stream.delegate?.rtmpStream(stream, publishInsufficientBWOccured: self)
|
||||
delegate?.connection(self, publishInsufficientBWOccured: stream)
|
||||
}
|
||||
} else if total == 0 {
|
||||
for stream in streams {
|
||||
stream.delegate?.rtmpStream(stream, publishSufficientBWOccured: self)
|
||||
delegate?.connection(self, publishSufficientBWOccured: stream)
|
||||
}
|
||||
}
|
||||
previousQueueBytesOut.removeFirst()
|
||||
}
|
||||
for stream in streams {
|
||||
stream.delegate?.rtmpStream(stream, updatedStats: self)
|
||||
delegate?.connection(self, didClear: stream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,5 @@
|
||||
import AVFoundation
|
||||
|
||||
/// The interface a RTMPStream uses to inform its delegate.
|
||||
public protocol RTMPStreamDelegate: AnyObject {
|
||||
/// Tells the receiver to publish insufficient bandwidth occured.
|
||||
func rtmpStream(_ stream: RTMPStream, publishInsufficientBWOccured connection: RTMPConnection)
|
||||
/// Tells the receiver to publish sufficient bandwidth occured.
|
||||
func rtmpStream(_ stream: RTMPStream, publishSufficientBWOccured connection: RTMPConnection)
|
||||
/// Tells the receiver to playback an audio packet incoming.
|
||||
func rtmpStream(_ stream: RTMPStream, didOutput audio: AVAudioBuffer, presentationTimeStamp: CMTime)
|
||||
/// Tells the receiver to playback a video packet incoming.
|
||||
func rtmpStream(_ stream: RTMPStream, didOutput video: CMSampleBuffer)
|
||||
/// Tells the receiver to update statistics.
|
||||
func rtmpStream(_ stream: RTMPStream, updatedStats connection: RTMPConnection)
|
||||
#if os(iOS)
|
||||
/// Tells the receiver to session was interrupted.
|
||||
func rtmpStream(_ stream: RTMPStream, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason)
|
||||
/// Tells the receiver to session interrupted ended.
|
||||
func rtmpStream(_ stream: RTMPStream, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason)
|
||||
#endif
|
||||
/// Tells the receiver to video codec error occured.
|
||||
func rtmpStream(_ stream: RTMPStream, videoCodecErrorOccurred error: VideoCodec.Error)
|
||||
/// Tells the receiver to audio codec error occured.
|
||||
func rtmpStream(_ stream: RTMPStream, audioCodecErrorOccurred error: AudioCodec.Error)
|
||||
/// Tells the receiver to the stream opend.
|
||||
func rtmpStreamDidClear(_ stream: RTMPStream)
|
||||
}
|
||||
|
||||
/// An object that provides the interface to control a one-way channel over a RtmpConnection.
|
||||
open class RTMPStream: NetStream {
|
||||
/// NetStatusEvent#info.code for NetStream
|
||||
@@ -185,8 +159,6 @@ open class RTMPStream: NetStream {
|
||||
}
|
||||
|
||||
static let defaultID: UInt32 = 0
|
||||
/// Specifies the delegate of the RTMPStream.
|
||||
public weak var delegate: RTMPStreamDelegate?
|
||||
/// The NetStreamInfo object whose properties contain data.
|
||||
public internal(set) var info = RTMPStreamInfo()
|
||||
/// The object encoding (AMF). Framework supports AMF0 only.
|
||||
@@ -479,7 +451,6 @@ open class RTMPStream: NetStream {
|
||||
currentFPS = 0
|
||||
frameCount = 0
|
||||
info.clear()
|
||||
delegate?.rtmpStreamDidClear(self)
|
||||
for message in messages {
|
||||
rtmpConnection.currentTransactionId += 1
|
||||
message.streamId = id
|
||||
@@ -618,11 +589,11 @@ extension RTMPStream: RTMPMuxerDelegate {
|
||||
}
|
||||
|
||||
func muxer(_ muxer: RTMPMuxer, videoCodecErrorOccurred error: VideoCodec.Error) {
|
||||
delegate?.rtmpStream(self, videoCodecErrorOccurred: error)
|
||||
delegate?.stream(self, videoCodecErrorOccurred: error)
|
||||
}
|
||||
|
||||
func muxer(_ muxer: RTMPMuxer, audioCodecErrorOccurred error: AudioCodec.Error) {
|
||||
delegate?.rtmpStream(self, audioCodecErrorOccurred: error)
|
||||
delegate?.stream(self, audioCodecErrorOccurred: error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,20 +601,20 @@ extension RTMPStream: IOMixerDelegate {
|
||||
// MARK: IOMixerDelegate
|
||||
func mixer(_ mixer: IOMixer, didOutput video: CMSampleBuffer) {
|
||||
frameCount += 1
|
||||
delegate?.rtmpStream(self, didOutput: video)
|
||||
delegate?.stream(self, didOutput: video)
|
||||
}
|
||||
|
||||
func mixer(_ mixer: IOMixer, didOutput audio: AVAudioPCMBuffer, presentationTimeStamp: CMTime) {
|
||||
delegate?.rtmpStream(self, didOutput: audio, presentationTimeStamp: presentationTimeStamp)
|
||||
delegate?.stream(self, didOutput: audio, presentationTimeStamp: presentationTimeStamp)
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
func mixer(_ mixer: IOMixer, sessionWasInterrupted session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) {
|
||||
delegate?.rtmpStream(self, sessionWasInterrupted: session, reason: reason)
|
||||
delegate?.stream(self, sessionWasInterrupted: session, reason: reason)
|
||||
}
|
||||
|
||||
func mixer(_ mixer: IOMixer, sessionInterruptionEnded session: AVCaptureSession, reason: AVCaptureSession.InterruptionReason) {
|
||||
delegate?.rtmpStream(self, sessionInterruptionEnded: session, reason: reason)
|
||||
delegate?.stream(self, sessionInterruptionEnded: session, reason: reason)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user