Streaming vidéo sur iOS via RTMP

Intro

Récemment, j'ai eu une tâche intéressante à travailler, faire une application pour le streaming vidéo, c'est pour une startup ShopStory (ecomm live streaming). La première version de l'application a été implémentée à l'aide de la bibliothèque Open Source pour le streaming RTMP HaishinKit . Et la deuxième version est sur le SDK Larix . Dans cet article, j'analyserai les problèmes survenus au cours du processus.





Conditions

 ShopStory.live - B2B live e-commerce, , . , , , , . ShopStory.live  , , beauty- live commerce .





ShopStory, LarixBroadcaster , Android iOS. :





  1. , , , LarixBroadcaster



    , . , , , .





  2. , , .





  3. .





  4. , (, , ).





:









  • ( , )





  • ABR - Adaptive BitRate ( )





  • , fps, ..





  • .





– . Larix SDK



– , .

, :





  • LFLiveKit – 4.2k , 2016. 115 issue, .





  • HaishinKit – 2.1k , 7 . 11 issues.





  • VideoCore – 1.5k , 2015. .





  • KSY Live iOS SDK – 0.8k , 22 2020. README .





HaishinKit. , , .





HaishinKit

, . . /, . AVCaptureSession, AVCaptureDevice, AVCaptureDeviceInput



. View



, attach



RTMPStream







:





protocol BroadcastService: AnyObject {
    func connect()
    func publish()
    func stop()
}
      
      



.





class HaishinBroadcastService: BroadcastService {}
      
      



ABR - Adaptive BitRate

, , ().





ABR, issue. RTMPStreamDelegate



.





extension HaishinBroadcastService: RTMPStreamDelegate {
    func rtmpStream(_ stream: RTMPStream, didPublishInsufficientBW connection: RTMPConnection) {
        guard self.config.adaptiveBitrate else { return }
        guard let bitrate = self.currentBitrate else {
            assertionFailure()
            return
        }
        let newBitrate = max(UInt32(Double(bitrate) * Constants.bitrateDown), Constants.minBitrate)
        self.rtmpStream.videoSettings[.bitrate] = newBitrate
    }

    func rtmpStream(_ stream: RTMPStream, didPublishSufficientBW connection: RTMPConnection) {
        guard self.config.adaptiveBitrate else { return }
        guard let currentBitrate = self.currentBitrate,
              currentBitrate < Constants.maxBitrate else {
            return
        }
        guard self.bitrateRetryCounter >= Constants.retrySecBeforeUpBitrate else {
            self.bitrateRetryCounter += 1
            return
        }

        self.bitrateRetryCounter = 0
        let newBitrate = min(Constants.maxBitrate, UInt32(Double(currentBitrate) * Constants.bitrateUp))
        if newBitrate == currentBitrate { return }

        self.rtmpStream.videoSettings[.bitrate] = newBitrate
    }
}

private struct Constants {
    static let bitrateDown: Double = 0.75
    static let bitrateUp: Double = 1.15
    static let retrySecBeforeUpBitrate = 20
}
      
      



issue – ( 2 ), . didPublishInsufficientBW



, .





:





  • , 0.75





  • , 20 ( ), 1.15





Live update resolution

, , . RTMP . VK Live . Instagram , rtmp , , , ( , ). ShopStory .





. Wi-Fi, LTE. Larix SDK



. LarixBroadcaster – .





Larix SDK

LarixBroadcaster



+ LarixDemo ( ), , StepByStepGuide.





:





  • ,





  • .





:









  • , - LarixBroadcaster



    ( , : over 2000 )









  • connect



    publish







-

… , LarixBroadcaster



ViewController



2100 , Streamer



1100 . SDK. … , . @Aquary ( ):





« " ". — - . , . — . , , .. , .»





, SDK . , . c HaishinKit



, .. ( HaishinKit



).





ABR, ( ), , . . LarixBroadcaster



3 StreamConditionerMode1, 2, 3,



. ABR? ABR ( ).





, . , status = disconnected



. , .





func connectionStateDidChangeId(_ connectionID: Int32, state: ConnectionState, status: ConnectionStatus, info: [AnyHashable: Any]) {}
      
      



Larix



.

: SDK StreamerEngineProxy



bytesSent



bytesDelivered



, , . , , .





Connect Publish

RTMP, publish



connect



, Larix



( ), . - BroadcastService



.





?





  • , , , , , .





  • . , publish



    , , , , ( ). publish



    ( ). .





. , .





Le choix d'une bibliothèque gratuite pour le streaming sur iOS n'est pas très large et en fait tout se résume à une seule option - HaishinKit



. Il a un avantage incontestable - l'open source, et si Larix



nous ne parvenons pas à aligner les graphiques et à augmenter la stabilité, nous plongerons dans l'open source et chercherons des endroits qui peuvent être améliorés.





Acheter un SDK payant - ne vous attendez pas à ce qu'il résoudra tous vos problèmes, peut-être en aurez-vous plus (apprenez vc sur 2000 lignes).





Et des conclusions plus globales ne peuvent être tirées qu'après avoir exécuté l'assembly sur un plus grand nombre de flux.








All Articles