Intro
Vor kurzem hatte ich eine interessante Aufgabe zu erledigen, eine Anwendung für Video-Streaming zu erstellen, dies ist für ein Startup-ShopStory (ecomm Live-Streaming). Die erste Version der Anwendung wurde mithilfe der Open Source-Bibliothek für das RTMP-Streaming von HaishinKit implementiert . Und die zweite Version ist auf Larix SDK . In diesem Artikel werde ich analysieren, welche Probleme dabei aufgetreten sind.
Bedarf
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
( ). .
. , .
Die Auswahl einer kostenlosen Bibliothek für das Streaming unter iOS ist nicht sehr groß, und tatsächlich hängt alles von einer Option ab - HaishinKit
. Es hat zweifellos einen Vorteil - Open Source. Wenn Larix
wir Grafiken nicht ausrichten und die Stabilität erhöhen, werden wir in Open Source eintauchen und nach Orten suchen, die verbessert werden können.
Kaufen Sie ein kostenpflichtiges SDK - erwarten Sie nicht, dass es alle Ihre Probleme löst, vielleicht haben Sie mehr davon (lernen Sie vc über 2000 Zeilen).
Weitere globale Schlussfolgerungen können erst gezogen werden, nachdem wir die Assembly für eine größere Anzahl von Streams ausgeführt haben.