直播连线

功能介绍

连线功能是一种实时互动交流方式,专门为主播量身定制。它让来自不同房间的主播在直播过程中实现实时互动与交流,TUILiveKit 的连线功能可支持单房间内多达9人同时连线,为主播互动、知识分享、文化交流、电商培训等多种场景提供了强大的技术支持,不仅为主播提供多样化的互动方式,也为观众带来更加丰富和深入的观看体验,从而为双方创造更多的惊喜和价值,使直播更具吸引力。
双人连线
多人连线







使用说明

主播发起连线

点击连线按钮
选择主播发起连线
连线成功
断开连线













主播接收连线

主播收到邀请
主播接受邀请







功能定制

替换推荐列表数据源

TUILiveKit 的连线推荐列表数据源默认是使用 getRecommendedList 获取直播列表。若您需要使用自定义的推荐列表,可参考下方示例代码替换对应的推荐列表:
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/ConnectionService.swift
func getRecommendedList(cursor: String, count: Int = 20) -> AnyPublisher<(String, [TUILiveInfo]), InternalError> {
return Future<(String,[TUILiveInfo]), InternalError> { [weak self] promise in
guard let self = self else { return }
guard let listManager = roomEngine.getExtension(extensionType: .liveListManager) as? TUILiveListManager else {
promise(.failure(InternalError(error:TUIError.failed, message: String.localized("live.error.failed"))))
return
}
listManager.fetchLiveList(cursor: cursor, count: count) { responseCursor, responseLiveList in
let liveList = responseLiveList.filter { info in
return LiveIdentityGenerator.shared.getIDType(info.roomInfo.roomId) == .live
}
promise(.success((responseCursor, liveList)))
} onError: { error, message in
promise(.failure(InternalError(error: error, message: message)))
}
}.eraseToAnyPublisher()
}

自定义连线面板 UI

如您需要自定义连线面板 UI、推荐列表 UI、已连线列表 UI ,请参考以下路径更改。
// 文件位置:iOS/TUILiveKit/Source/View/LiveRoom/View/Anchor/LivingView/Connection

├── ConnectionManagerPanel.swift // 连线面板视图
├── ConnectionUserCell.swift // 推荐列表、连线列表复用Cell视图样式
└── ConnectionUserTableHeaderView.swift // 连线面板标题视图样式

自定义连线视图

如您需要自定义连线视图 UI ,请参考以下路径更改。
Swift
// 文件位置:iOS/TUILiveKit/Source/View/LiveRoom/View/Common/Video/Component/RenderView.swift

class RenderView: UIView {
...
func constructViewHierarchy() {
// 视图层级构建
}

func activateConstraints() {
// 视图layout布局
}

}

关键代码

主播连线

TUILiveKit 主播连线功能主要是基于 ConnectionService 实现的,您可通过 store.serviceCenter.connectionService 获取到连线管理类对象,进而调用连线相关 API函数,实现连线功能。以主播 A,B连线为例,具体交互时序可参考下图。




主播 A 发起连线

主播 A 通过调用requestConnection发起连线,在参数 roomIdList 中传入主播 B 房间 id。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/ConnectionService.swift
func requestConnection(roomIdList:[String], extensionInfo: String) -> AnyPublisher<[String:TUIConnectionCode], InternalError> {
return Future<[String:TUIConnectionCode], InternalError> {[weak self] promise in
guard let self = self else { return }
connectionManager.requestConnection(roomIdList: roomIdList, timeout: 10, extensionInfo: extensionInfo) { result in
var connectionResult:[String:TUIConnectionCode] = [:]
result.forEach { (key: String, value: NSNumber) in
connectionResult[key] = TUIConnectionCode(rawValue: value.intValue) ?? .unknown
}
promise(.success(connectionResult))
} onError: { err, message in
let error = InternalError(error: err, message: message)
promise(.failure(error))
}
}.eraseToAnyPublisher()
}
主播 A 可通过 onConnectionRequestAccept 接收请求同意回调。

主播收到连线请求

主播 B 通过 onConnectionRequestReceived 接收连线请求回调。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift
func onConnectionRequestReceived(inviter: TUIConnectionUser, inviteeList: [TUIConnectionUser], extensionInfo: String) {
guard let store = self.store else { return }
store.dispatch(action: ConnectionActions.onConnectionRequestReceived(payload: (inviter, inviteeList, extensionInfo)))
}
主播 B 通过调用 accept 接受连线请求。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/ConnectionService.swift
func accept(roomId:String) -> AnyPublisher<Void, InternalError>{
return Future<Void, InternalError> {[weak self] promise in
guard let self = self else { return }
connectionManager.acceptConnection(roomId) {
promise(.success(()))
} onError: { err, message in
let error = InternalError(error: err, message: message)
promise(.failure(error))
}
}.eraseToAnyPublisher()
}
主播 A,B 以及房间内观众可通过 onConnectionUserListChanged 接收连线列表变化。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift
func onConnectionUserListChanged(connectedList: [TUIConnectionUser], joinedList: [TUIConnectionUser], leavedList: [TUIConnectionUser]) {
guard let store = self.store else { return }
store.dispatch(action: ConnectionActions.onConnectionUserListChanged(payload: connectedList))
}

主播退出连线

以主播 B 退出连线为例,交互时序可参考下图。



主播 B 调用 disconnect退出连线。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/ConnectionService.swift
func disconnect() -> AnyPublisher<Void, InternalError>{
return Future<Void, InternalError> {[weak self] promise in
guard let self = self else { return }
connectionManager.disconnect {
promise(.success(()))
} onError: { err, message in
let error = InternalError(error: err, message: message)
promise(.failure(error))
}
}.eraseToAnyPublisher()
}
主播 A, B 以及房间内观众收到 onConnectionUserListChanged 回调,收到接收连线列表发生变化通知。
Swift
// 文件位置:iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift
func onConnectionUserListChanged(connectedList: [TUIConnectionUser], joinedList: [TUIConnectionUser], leavedList: [TUIConnectionUser]) {
guard let store = self.store else { return }
store.dispatch(action: ConnectionActions.onConnectionUserListChanged(payload: connectedList))
}
说明:
ConnectionService 是基于 TUILiveConnectionManager 实现,若您需要扩展连线功能,可参考文档: TUILiveConnectionManager