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. :
, , ,
LarixBroadcaster
, . , , , .
, , .
.
, (, , ).
:
( , )
ABR - Adaptive BitRate ( )
, fps, ..
.
– . Larix SDK
– , .
, :
LFLiveKit – 4.2k , 2016. 115 issue, .
HaishinKit – 2.1k , 7 . 11 issues.
-
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.