Skip to content

Commit e53323b

Browse files
Added events and models for pausing video in low bandwidth (#887)
1 parent 0c4a127 commit e53323b

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed

Sources/StreamVideo/WebRTC/v2/SFU/Extensions/Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload+Payload.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ extension Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload {
6161
return payload as? T
6262
case let .changePublishOptions(payload):
6363
return payload as? T
64+
case let .inboundStateNotification(payload):
65+
return payload as? T
6466
}
6567
}
6668
}

Sources/StreamVideo/WebSockets/Events/Event.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ extension Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload: Event {
122122
case .participantUpdated: return "participantUpdated"
123123
case .participantMigrationComplete: return "participantMigrationComplete"
124124
case .changePublishOptions: return "changePublishOptions"
125+
case .inboundStateNotification: return "inboundStateNotification"
125126
}
126127
}
127128
}

Sources/StreamVideo/protobuf/sfu/event/events.pb.swift

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ struct Stream_Video_Sfu_Event_SfuEvent {
248248
set {eventPayload = .changePublishOptions(newValue)}
249249
}
250250

251+
/// InboundStateNotification
252+
var inboundStateNotification: Stream_Video_Sfu_Event_InboundStateNotification {
253+
get {
254+
if case .inboundStateNotification(let v)? = eventPayload {return v}
255+
return Stream_Video_Sfu_Event_InboundStateNotification()
256+
}
257+
set {eventPayload = .inboundStateNotification(newValue)}
258+
}
259+
251260
var unknownFields = SwiftProtobuf.UnknownStorage()
252261

253262
enum OneOf_EventPayload: Equatable {
@@ -317,6 +326,8 @@ struct Stream_Video_Sfu_Event_SfuEvent {
317326
case participantMigrationComplete(Stream_Video_Sfu_Event_ParticipantMigrationComplete)
318327
/// ChangePublishOptions is sent to signal the change in publish options such as a new codec or simulcast layers
319328
case changePublishOptions(Stream_Video_Sfu_Event_ChangePublishOptions)
329+
/// InboundStateNotification
330+
case inboundStateNotification(Stream_Video_Sfu_Event_InboundStateNotification)
320331

321332
#if !swift(>=4.1)
322333
static func ==(lhs: Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload, rhs: Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload) -> Bool {
@@ -412,6 +423,10 @@ struct Stream_Video_Sfu_Event_SfuEvent {
412423
guard case .changePublishOptions(let l) = lhs, case .changePublishOptions(let r) = rhs else { preconditionFailure() }
413424
return l == r
414425
}()
426+
case (.inboundStateNotification, .inboundStateNotification): return {
427+
guard case .inboundStateNotification(let l) = lhs, case .inboundStateNotification(let r) = rhs else { preconditionFailure() }
428+
return l == r
429+
}()
415430
default: return false
416431
}
417432
}
@@ -795,6 +810,11 @@ struct Stream_Video_Sfu_Event_JoinRequest {
795810
set {_uniqueStorage()._preferredSubscribeOptions = newValue}
796811
}
797812

813+
var capabilities: [Stream_Video_Sfu_Models_ClientCapability] {
814+
get {return _storage._capabilities}
815+
set {_uniqueStorage()._capabilities = newValue}
816+
}
817+
798818
var unknownFields = SwiftProtobuf.UnknownStorage()
799819

800820
init() {}
@@ -1217,6 +1237,36 @@ struct Stream_Video_Sfu_Event_CallEnded {
12171237
init() {}
12181238
}
12191239

1240+
struct Stream_Video_Sfu_Event_InboundStateNotification {
1241+
// SwiftProtobuf.Message conformance is added in an extension below. See the
1242+
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
1243+
// methods supported on all messages.
1244+
1245+
var inboundVideoStates: [Stream_Video_Sfu_Event_InboundVideoState] = []
1246+
1247+
var unknownFields = SwiftProtobuf.UnknownStorage()
1248+
1249+
init() {}
1250+
}
1251+
1252+
struct Stream_Video_Sfu_Event_InboundVideoState {
1253+
// SwiftProtobuf.Message conformance is added in an extension below. See the
1254+
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
1255+
// methods supported on all messages.
1256+
1257+
var userID: String = String()
1258+
1259+
var sessionID: String = String()
1260+
1261+
var trackType: Stream_Video_Sfu_Models_TrackType = .unspecified
1262+
1263+
var paused: Bool = false
1264+
1265+
var unknownFields = SwiftProtobuf.UnknownStorage()
1266+
1267+
init() {}
1268+
}
1269+
12201270
#if swift(>=5.5) && canImport(_Concurrency)
12211271
extension Stream_Video_Sfu_Event_SfuEvent: @unchecked Sendable {}
12221272
extension Stream_Video_Sfu_Event_SfuEvent.OneOf_EventPayload: @unchecked Sendable {}
@@ -1255,6 +1305,8 @@ extension Stream_Video_Sfu_Event_ChangePublishQuality: @unchecked Sendable {}
12551305
extension Stream_Video_Sfu_Event_CallGrantsUpdated: @unchecked Sendable {}
12561306
extension Stream_Video_Sfu_Event_GoAway: @unchecked Sendable {}
12571307
extension Stream_Video_Sfu_Event_CallEnded: @unchecked Sendable {}
1308+
extension Stream_Video_Sfu_Event_InboundStateNotification: @unchecked Sendable {}
1309+
extension Stream_Video_Sfu_Event_InboundVideoState: @unchecked Sendable {}
12581310
#endif // swift(>=5.5) && canImport(_Concurrency)
12591311

12601312
// MARK: - Code below here is support for the SwiftProtobuf runtime.
@@ -1286,6 +1338,7 @@ extension Stream_Video_Sfu_Event_SfuEvent: SwiftProtobuf.Message, SwiftProtobuf.
12861338
24: .standard(proto: "participant_updated"),
12871339
25: .standard(proto: "participant_migration_complete"),
12881340
27: .standard(proto: "change_publish_options"),
1341+
28: .standard(proto: "inbound_state_notification"),
12891342
]
12901343

12911344
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@@ -1580,6 +1633,19 @@ extension Stream_Video_Sfu_Event_SfuEvent: SwiftProtobuf.Message, SwiftProtobuf.
15801633
self.eventPayload = .changePublishOptions(v)
15811634
}
15821635
}()
1636+
case 28: try {
1637+
var v: Stream_Video_Sfu_Event_InboundStateNotification?
1638+
var hadOneofValue = false
1639+
if let current = self.eventPayload {
1640+
hadOneofValue = true
1641+
if case .inboundStateNotification(let m) = current {v = m}
1642+
}
1643+
try decoder.decodeSingularMessageField(value: &v)
1644+
if let v = v {
1645+
if hadOneofValue {try decoder.handleConflictingOneOf()}
1646+
self.eventPayload = .inboundStateNotification(v)
1647+
}
1648+
}()
15831649
default: break
15841650
}
15851651
}
@@ -1679,6 +1745,10 @@ extension Stream_Video_Sfu_Event_SfuEvent: SwiftProtobuf.Message, SwiftProtobuf.
16791745
guard case .changePublishOptions(let v)? = self.eventPayload else { preconditionFailure() }
16801746
try visitor.visitSingularMessageField(value: v, fieldNumber: 27)
16811747
}()
1748+
case .inboundStateNotification?: try {
1749+
guard case .inboundStateNotification(let v)? = self.eventPayload else { preconditionFailure() }
1750+
try visitor.visitSingularMessageField(value: v, fieldNumber: 28)
1751+
}()
16821752
case nil: break
16831753
}
16841754
try unknownFields.traverse(visitor: &visitor)
@@ -2297,6 +2367,7 @@ extension Stream_Video_Sfu_Event_JoinRequest: SwiftProtobuf.Message, SwiftProtob
22972367
7: .standard(proto: "reconnect_details"),
22982368
9: .standard(proto: "preferred_publish_options"),
22992369
10: .standard(proto: "preferred_subscribe_options"),
2370+
11: .same(proto: "capabilities"),
23002371
]
23012372

23022373
fileprivate class _StorageClass: @unchecked Sendable {
@@ -2310,6 +2381,7 @@ fileprivate class _StorageClass: @unchecked Sendable {
23102381
var _reconnectDetails: Stream_Video_Sfu_Event_ReconnectDetails? = nil
23112382
var _preferredPublishOptions: [Stream_Video_Sfu_Models_PublishOption] = []
23122383
var _preferredSubscribeOptions: [Stream_Video_Sfu_Models_SubscribeOption] = []
2384+
var _capabilities: [Stream_Video_Sfu_Models_ClientCapability] = []
23132385

23142386
static let defaultInstance = _StorageClass()
23152387

@@ -2326,6 +2398,7 @@ fileprivate class _StorageClass: @unchecked Sendable {
23262398
_reconnectDetails = source._reconnectDetails
23272399
_preferredPublishOptions = source._preferredPublishOptions
23282400
_preferredSubscribeOptions = source._preferredSubscribeOptions
2401+
_capabilities = source._capabilities
23292402
}
23302403
}
23312404

@@ -2354,6 +2427,7 @@ fileprivate class _StorageClass: @unchecked Sendable {
23542427
case 8: try { try decoder.decodeSingularStringField(value: &_storage._publisherSdp) }()
23552428
case 9: try { try decoder.decodeRepeatedMessageField(value: &_storage._preferredPublishOptions) }()
23562429
case 10: try { try decoder.decodeRepeatedMessageField(value: &_storage._preferredSubscribeOptions) }()
2430+
case 11: try { try decoder.decodeRepeatedEnumField(value: &_storage._capabilities) }()
23572431
default: break
23582432
}
23592433
}
@@ -2396,6 +2470,9 @@ fileprivate class _StorageClass: @unchecked Sendable {
23962470
if !_storage._preferredSubscribeOptions.isEmpty {
23972471
try visitor.visitRepeatedMessageField(value: _storage._preferredSubscribeOptions, fieldNumber: 10)
23982472
}
2473+
if !_storage._capabilities.isEmpty {
2474+
try visitor.visitPackedEnumField(value: _storage._capabilities, fieldNumber: 11)
2475+
}
23992476
}
24002477
try unknownFields.traverse(visitor: &visitor)
24012478
}
@@ -2415,6 +2492,7 @@ fileprivate class _StorageClass: @unchecked Sendable {
24152492
if _storage._reconnectDetails != rhs_storage._reconnectDetails {return false}
24162493
if _storage._preferredPublishOptions != rhs_storage._preferredPublishOptions {return false}
24172494
if _storage._preferredSubscribeOptions != rhs_storage._preferredSubscribeOptions {return false}
2495+
if _storage._capabilities != rhs_storage._capabilities {return false}
24182496
return true
24192497
}
24202498
if !storagesAreEqual {return false}
@@ -3299,3 +3377,85 @@ extension Stream_Video_Sfu_Event_CallEnded: SwiftProtobuf.Message, SwiftProtobuf
32993377
return true
33003378
}
33013379
}
3380+
3381+
extension Stream_Video_Sfu_Event_InboundStateNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
3382+
static let protoMessageName: String = _protobuf_package + ".InboundStateNotification"
3383+
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
3384+
1: .standard(proto: "inbound_video_states"),
3385+
]
3386+
3387+
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
3388+
while let fieldNumber = try decoder.nextFieldNumber() {
3389+
// The use of inline closures is to circumvent an issue where the compiler
3390+
// allocates stack space for every case branch when no optimizations are
3391+
// enabled. https://github.com/apple/swift-protobuf/issues/1034
3392+
switch fieldNumber {
3393+
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.inboundVideoStates) }()
3394+
default: break
3395+
}
3396+
}
3397+
}
3398+
3399+
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
3400+
if !self.inboundVideoStates.isEmpty {
3401+
try visitor.visitRepeatedMessageField(value: self.inboundVideoStates, fieldNumber: 1)
3402+
}
3403+
try unknownFields.traverse(visitor: &visitor)
3404+
}
3405+
3406+
static func ==(lhs: Stream_Video_Sfu_Event_InboundStateNotification, rhs: Stream_Video_Sfu_Event_InboundStateNotification) -> Bool {
3407+
if lhs.inboundVideoStates != rhs.inboundVideoStates {return false}
3408+
if lhs.unknownFields != rhs.unknownFields {return false}
3409+
return true
3410+
}
3411+
}
3412+
3413+
extension Stream_Video_Sfu_Event_InboundVideoState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
3414+
static let protoMessageName: String = _protobuf_package + ".InboundVideoState"
3415+
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
3416+
1: .standard(proto: "user_id"),
3417+
2: .standard(proto: "session_id"),
3418+
3: .standard(proto: "track_type"),
3419+
4: .same(proto: "paused"),
3420+
]
3421+
3422+
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
3423+
while let fieldNumber = try decoder.nextFieldNumber() {
3424+
// The use of inline closures is to circumvent an issue where the compiler
3425+
// allocates stack space for every case branch when no optimizations are
3426+
// enabled. https://github.com/apple/swift-protobuf/issues/1034
3427+
switch fieldNumber {
3428+
case 1: try { try decoder.decodeSingularStringField(value: &self.userID) }()
3429+
case 2: try { try decoder.decodeSingularStringField(value: &self.sessionID) }()
3430+
case 3: try { try decoder.decodeSingularEnumField(value: &self.trackType) }()
3431+
case 4: try { try decoder.decodeSingularBoolField(value: &self.paused) }()
3432+
default: break
3433+
}
3434+
}
3435+
}
3436+
3437+
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
3438+
if !self.userID.isEmpty {
3439+
try visitor.visitSingularStringField(value: self.userID, fieldNumber: 1)
3440+
}
3441+
if !self.sessionID.isEmpty {
3442+
try visitor.visitSingularStringField(value: self.sessionID, fieldNumber: 2)
3443+
}
3444+
if self.trackType != .unspecified {
3445+
try visitor.visitSingularEnumField(value: self.trackType, fieldNumber: 3)
3446+
}
3447+
if self.paused != false {
3448+
try visitor.visitSingularBoolField(value: self.paused, fieldNumber: 4)
3449+
}
3450+
try unknownFields.traverse(visitor: &visitor)
3451+
}
3452+
3453+
static func ==(lhs: Stream_Video_Sfu_Event_InboundVideoState, rhs: Stream_Video_Sfu_Event_InboundVideoState) -> Bool {
3454+
if lhs.userID != rhs.userID {return false}
3455+
if lhs.sessionID != rhs.sessionID {return false}
3456+
if lhs.trackType != rhs.trackType {return false}
3457+
if lhs.paused != rhs.paused {return false}
3458+
if lhs.unknownFields != rhs.unknownFields {return false}
3459+
return true
3460+
}
3461+
}

Sources/StreamVideo/protobuf/sfu/models/models.pb.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,49 @@ extension Stream_Video_Sfu_Models_AppleThermalState: CaseIterable {
746746

747747
#endif // swift(>=4.2)
748748

749+
/// ClientCapability defines a feature that client supports
750+
enum Stream_Video_Sfu_Models_ClientCapability: SwiftProtobuf.Enum {
751+
typealias RawValue = Int
752+
case unspecified // = 0
753+
754+
/// Enables SFU pausing inbound video
755+
case subscriberVideoPause // = 1
756+
case UNRECOGNIZED(Int)
757+
758+
init() {
759+
self = .unspecified
760+
}
761+
762+
init?(rawValue: Int) {
763+
switch rawValue {
764+
case 0: self = .unspecified
765+
case 1: self = .subscriberVideoPause
766+
default: self = .UNRECOGNIZED(rawValue)
767+
}
768+
}
769+
770+
var rawValue: Int {
771+
switch self {
772+
case .unspecified: return 0
773+
case .subscriberVideoPause: return 1
774+
case .UNRECOGNIZED(let i): return i
775+
}
776+
}
777+
778+
}
779+
780+
#if swift(>=4.2)
781+
782+
extension Stream_Video_Sfu_Models_ClientCapability: CaseIterable {
783+
// The compiler won't synthesize support with the UNRECOGNIZED case.
784+
static let allCases: [Stream_Video_Sfu_Models_ClientCapability] = [
785+
.unspecified,
786+
.subscriberVideoPause,
787+
]
788+
}
789+
790+
#endif // swift(>=4.2)
791+
749792
/// CallState is the current state of the call
750793
/// as seen by an SFU.
751794
struct Stream_Video_Sfu_Models_CallState {
@@ -1445,6 +1488,7 @@ extension Stream_Video_Sfu_Models_CallEndedReason: @unchecked Sendable {}
14451488
extension Stream_Video_Sfu_Models_WebsocketReconnectStrategy: @unchecked Sendable {}
14461489
extension Stream_Video_Sfu_Models_AndroidThermalState: @unchecked Sendable {}
14471490
extension Stream_Video_Sfu_Models_AppleThermalState: @unchecked Sendable {}
1491+
extension Stream_Video_Sfu_Models_ClientCapability: @unchecked Sendable {}
14481492
extension Stream_Video_Sfu_Models_CallState: @unchecked Sendable {}
14491493
extension Stream_Video_Sfu_Models_ParticipantCount: @unchecked Sendable {}
14501494
extension Stream_Video_Sfu_Models_Pin: @unchecked Sendable {}
@@ -1613,6 +1657,13 @@ extension Stream_Video_Sfu_Models_AppleThermalState: SwiftProtobuf._ProtoNamePro
16131657
]
16141658
}
16151659

1660+
extension Stream_Video_Sfu_Models_ClientCapability: SwiftProtobuf._ProtoNameProviding {
1661+
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1662+
0: .same(proto: "CLIENT_CAPABILITY_UNSPECIFIED"),
1663+
1: .same(proto: "CLIENT_CAPABILITY_SUBSCRIBER_VIDEO_PAUSE"),
1664+
]
1665+
}
1666+
16161667
extension Stream_Video_Sfu_Models_CallState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
16171668
static let protoMessageName: String = _protobuf_package + ".CallState"
16181669
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [

Sources/StreamVideoSwiftUI/CallViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ public enum CallingState: Equatable, CustomStringConvertible, Sendable {
10511051
}
10521052
}
10531053

1054-
public struct LobbyInfo: Equatable {
1054+
public struct LobbyInfo: Equatable, Sendable {
10551055
public let callId: String
10561056
public let callType: String
10571057
public let participants: [Member]

0 commit comments

Comments
 (0)