logo
当前页

PK 连麦

功能简介

PK 连麦,指两个直播间进行主播连麦 PK 互动,应用于秀场、游戏、电商等直播场景,可以提升直播间内容的丰富性、吸引更多的粉丝流,提升直播间的娱乐气氛。

前提条件

在开始之前,请确保您完成了以下步骤:

实现流程

主播在自己的直播间开始后,可以向他们想要连接的主播发送 PK 连麦请求,一旦对方主播接受了 PK 连麦请求,两个直播间即可被连接。

开始 PK 连麦

如需开始 PK 连麦,您需要调用 ZegoLiveStreamingManager.shared.sendPKBattleRequest(anotherHostUserID); 方法先发送一个 PK 连麦请求。一旦对方主播接受了您的请求,PK 连麦就会开始。

Untitled
ZegoLiveStreamingManager.shared.sendPKBattleRequest(anotherHostUserID: userID, callback: { errorCode, requestID in
    if errorCode != 0 {
        sender.setTitle("PK", for: .normal)
    }
})
1
Copied!

停止 PK 连麦

如需停止 PK 连麦,可调用 ZegoLiveStreamingManager.shared.stopPKBattle() 方法。

监听 PK 连麦事件

如需监听 PK 连麦事件,可调用 ZegoLiveStreamingManager.shared.addLiveManagerDelegate(...) 方法。
当您收到 PK 请求时,您可以为用户显示一个弹出窗口,让用户选择是否接受或拒绝。

  • 如果接受,可调用 ZegoLiveStreamingManager.shared.acceptIncomingPKBattleRequest()
  • 如果拒绝,可调用 ZegoLiveStreamingManager.shared.rejectPKBattleStartRequest()

您还可以自定义自己的业务逻辑,来处理相应的 PK 事件。

Untitled
func onIncomingPKRequestReceived(requestID: String, anotherHostUser: ZegoUIKitUser, anotherHostLiveID: String, customData: String?) {
    let alterView = UIAlertController(title: "receive pk request", message: "", preferredStyle: .alert)
    self.pkAlterView = alterView
    let acceptButton: UIAlertAction = UIAlertAction(title: "accept", style: .default) { [weak self] action in
        ZegoLiveStreamingManager.shared.acceptIncomingPKBattleRequest(requestID, anotherHostLiveID: anotherHostLiveID, anotherHostUser: anotherHostUser)
    }
    let rejectButton: UIAlertAction = UIAlertAction(title: "reject", style: .cancel) { [weak self] action in
        ZegoLiveStreamingManager.shared.rejectPKBattleStartRequest(requestID)
    }
    alterView.addAction(acceptButton)
    alterView.addAction(rejectButton)
    liveStreamingVC?.present(alterView, animated: true)
}
1
Copied!

示例源代码

请点击 这里,获取详细的示例源码。


根据需要自定义您自己的 PK 连麦逻辑和流程ZegoLiveStreamingManager 包含一系列方法供您进行进一步的定制。在您进行定制之前,请先下方 API 简介 部分。

API 简介

发送 PK 连麦请求

Untitled
public func sendPKBattleRequest(anotherHostUserID: String, timeout: UInt32 = 10, customData: String, callback: UserRequestCallback?)
1
Copied!
  • anotherHostUserID:发送 PK 连麦请求时,您需要指定您想要连接的主播的用户 ID。
  • timeout:设置您发送的 PK 连麦请求的超时时长。超时后,发送请求的主播将通过 onOutgoingPKRequestTimeout 接收到回调通知。
  • customData:自定义您希望被邀请的主播接收的信息,被邀请的主播将通过 onIncomingPKRequestReceived 接收到您设置的信息。
Warning

您邀请的主播必须已经开始了直播,否则,相关错误将通过您调用的方法返回。有关错误信息和原因,请在 callback 中检查。

示例代码
ZegoLiveStreamingManager.shared.sendPKBattleRequest(anotherHostUserID: userID, callback: { errorCode, requestID in
    if errorCode != 0 {
        sender.setTitle("PK", for: .normal)
    }
})
1
Copied!

取消 PK 连麦请求

Untitled
public func cancelPKBattleRequest(customData: String?, callback: UserRequestCallback?)
1
Copied!

当请求未超时且未收到任何响应时,可以通过调用此方法取消 PK 连麦请求。取消后,被邀请的主播将通过 onIncomingPKRequestCancelled 接收到回调通知。

示例代码
ZegoLiveStreamingManager.shared.cancelPKBattleRequest(customData: nil) { errorCode, requestID in
    sender.setTitle("PK", for: .normal)
}
1
Copied!

响应 PK 连麦请求

如需接收 PK 连麦请求,您可以监听并设置 onIncomingPKRequestReceived

接受 PK 连麦请求

要接受 PK 连麦请求,调用 acceptIncomingPKBattleRequest 方法。对方的主播将通过 onOutgoingPKRequestAccepted 接收到通知,更多细节可以在 PK 请求被接受 中查看。

Untitled
ZegoLiveStreamingManager.shared.acceptIncomingPKBattleRequest(requestID, anotherHostLiveID: anotherHostLiveID, anotherHostUser: anotherHostUser)
1
Copied!

拒绝 PK 连麦请求

如需拒绝 PK 连麦请求,可调用 rejectPKBattleStartRequest 方法。对方的主播将通过 onOutgoingPKRequestRejected 接收到通知,并通过 rejectCode 告知为什么请求被拒绝。更多细节可以在 PK 请求被拒绝 中查看。

Untitled
ZegoLiveStreamingManager.shared.rejectPKBattleStartRequest(requestID)
1
Copied!

响应 PK 请求的示例代码

Untitled
func onIncomingPKRequestReceived(requestID: String, anotherHostUser: ZegoUIKitUser, anotherHostLiveID: String, customData: String?) {
    let alterView = UIAlertController(title: "receive pk request", message: "", preferredStyle: .alert)
    self.pkAlterView = alterView
    let acceptButton: UIAlertAction = UIAlertAction(title: "accept", style: .default) { [weak self] action in
        ZegoLiveStreamingManager.shared.acceptIncomingPKBattleRequest(requestID, anotherHostLiveID: anotherHostLiveID, anotherHostUser: anotherHostUser)
    }
    let rejectButton: UIAlertAction = UIAlertAction(title: "reject", style: .cancel) { [weak self] action in
        ZegoLiveStreamingManager.shared.rejectPKBattleStartRequest(requestID)
    }
    alterView.addAction(acceptButton)
    alterView.addAction(rejectButton)
    liveStreamingVC?.present(alterView, animated: true)
}
1
Copied!

监听发送的 PK 连麦请求

PK 连麦请求被接受

当发送的 PK 连麦请求被接受时,您可以通过监听或设置 onOutgoingPKRequestAccepted 来接收回调通知或自定义您的业务逻辑。

Untitled
func onOutgoingPKRequestAccepted() {
    //...
}
1
Copied!

PK 连麦请求被拒绝

当发送的 PK 连麦请求被拒绝时,您可以通过监听或设置 onOutgoingPKRequestRejected 来接收回调通知或自定义您的业务逻辑。

Note

当被邀请的主播处于忙碌状态时,PK 连麦请求将被自动拒绝。
忙碌状态:主播尚未启动他的直播间、主播正在与他人进行 PK 连麦、主播正在被邀请、主播正在向他人发送 PK 连麦请求。

Untitled
func onOutgoingPKRequestRejected(reason: Int, anotherHostUser: ZegoUIKitUser) {
    if reason == ZegoLiveStreamingPKBattleRejectCode.host_reject.rawValue {
        uikitLiveVC?.view.makeToast("another host busy",position: .center)
    } else {
        uikitLiveVC?.view.makeToast("pk is rejected",position: .center)
    }
    pkButton?.setTitle("PK", for: .normal)
}
1
Copied!

其中,ZegoLiveStreamingPKBattleRejectCode 可用于声明被邀请的主播为何拒绝了您的请求,定义如下:

Untitled
@objc public enum ZegoLiveStreamingPKBattleRejectCode: Int {
    case host_reject
    case use_not_host
    case in_pk
    case live_not_started
    case already_send
    case already_received
}
1
Copied!

PK 连麦请求超时

如果被邀请的主播在超时时长之后没有响应,则 PK 连麦请求将默认超时。互动直播 UIKit 会更新内部状态,但不会触发任何默认行为。 您可以通过监听或设置 ZegoLiveStreamingListener.onOutgoingPKBattleRequestTimeout 来接收回调通知或自定义您的业务逻辑。

示例代码
func onOutgoingPKRequestTimeout(requestID: String, anotherHost: ZegoUIKitUser) {
    pkButton?.setTitle("PK", for: .normal)
    uikitLiveVC?.view.makeToast("发送PK超时", position: .center)
}
1
Copied!

PK 连麦请求发送失败

在某些情况下,PK 连麦请求可能无法成功发送,例如,主播的应用程序尚未启动。 当 PK 连麦请求发送失败时,sendPKBattleRequest 会返回错误,您可以通过 sendPKBattleRequest 返回的值来识别和处理这些错误。

示例代码
ZegoLiveStreamingManager.shared.sendPKBattleRequest(anotherHostUserID: userID, callback: { errorCode, requestID in
    if errorCode != 0 {
        self?.uikitLiveVC?.view.makeToast("发送PK 连麦失败:\(errorCode)", duration: 1.0, position: .center)
        //...更新UI
        sender.setTitle("PK", for: .normal)
    }
})
1
Copied!

监听接收到的 PK 连麦请求

接收到 PK 连麦请求

当接收到 PK 连麦请求时,您可以通过监听或设置 onIncomingPKRequestReceived 来接收回调通知或自定义您的业务逻辑。

示例代码
func onIncomingPKRequestReceived(requestID: String, anotherHostUser: ZegoUIKitUser, anotherHostLiveID: String, customData: String?) {
    let alterView = UIAlertController(title: "接收到PK请求", message: "", preferredStyle: .alert)
    self.pkAlterView = alterView
    let acceptButton: UIAlertAction = UIAlertAction(title: "接受", style: .default) { [weak self] action in
        //...
    }
    let rejectButton: UIAlertAction = UIAlertAction(title: "拒绝", style: .cancel) { [weak self] action in
        //...
    }
    alterView.addAction(acceptButton)
    alterView.addAction(rejectButton)
    liveStreamingVC?.present(alterView, animated: true)
}
1
Copied!

接收到的 PK 连麦请求已被取消

当 PK 连麦请求被取消时,您可以通过监听或设置 onIncomingPKBattleRequestCancelled 来接收回调通知或自定义您的业务逻辑。

Untitled
func onIncomingPKRequestCancelled(anotherHostLiveID: String, anotherHostUser: ZegoUIKitUser, customData: String?) {
    self.pkAlterView?.dismiss(animated: true)
}
1
Copied!

接收到的 PK 连麦请求超时

当接收到的 PK 连麦请求超时时,您可以通过监听或设置 onIncomingPKRequestTimeout 来接收回调通知或自定义您的业务逻辑。

示例代码
func onIncomingPKRequestTimeout(requestID: String, anotherHostUser: ZegoUIKitUser) {
    self.pkAlterView?.dismiss(animated: true)
}
1
Copied!

在 PK 连麦期间静音对方主播

当 PK 连麦开始时,两位主播都可根据需要在连麦期间静音已连接的主播。对方主播被静音后,观众就听不到被静音直播间的声音了。

Untitled
public func muteAnotherHostAudio(_ mute: Bool, callback: ZegoUIKitCallBack?)
1
Copied!

您也可以通过 ZegoLiveStreamingManager.shared.isAnotherHostMuted 获取对方主播的静音状态。

示例代码
@objc func muteButtonClick(_ sender: UIButton) {
    let pkUserMuted: Bool = ZegoLiveStreamingManager.shared.isAnotherHostMuted
    ZegoLiveStreamingManager.shared.muteAnotherHostAudio(!pkUserMuted, callback: nil)
}
1
Copied!

自定义预构建 UI

仅适用于 PK 连麦特性的可定制方法

除了上述用于定制的方法外,ZegoUIKitPrebuiltLiveStreamingVC 中的 ZegoUIKitPrebuiltLiveStreamingVCDelegate 还提供了一些仅适用于 PK 连麦特性的 UI 和功能的定制。

Untitled
@objc public protocol ZegoUIKitPrebuiltLiveStreamingVCDelegate: AnyObject {
    //...
    @objc optional func getPKBattleForegroundView(_ parentView: UIView, userInfo: ZegoUIKitUser) -> UIView?
    @objc optional func getPKBattleTopView(_ parentView: UIView, userList: [ZegoUIKitUser]) -> UIView?
    @objc optional func getPKBattleBottomView(_ parentView: UIView, userList: [ZegoUIKitUser]) -> UIView?
}
1
Copied!

如果您想在 PK 视图的上方、下方和顶部放置自定义视图,可以参考以下示例代码:

示例代码
class ViewController: UIViewController {

    var userID: String?
    var userName: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        //... 
    }

    @IBAction func startLive(_ sender: Any) {
        let config: ZegoUIKitPrebuiltLiveStreamingConfig = ZegoUIKitPrebuiltLiveStreamingConfig.host(enableCoHosting: true)
        let liveVC: ZegoUIKitPrebuiltLiveStreamingVC = ZegoUIKitPrebuiltLiveStreamingVC(self.appID, appSign: self.appSign, userID: self.userID ?? "", userName: self.userName ?? "", liveID: self.roomIDTextField.text ?? "", config: config)
        liveVC.modalPresentationStyle = .fullScreen
        liveVC.delegate = self // 设置监听器
        //...
        self.present(liveVC, animated: true, completion: nil)
    }

    @IBAction func watchLive(_ sender: Any) {
        let config: ZegoUIKitPrebuiltLiveStreamingConfig = ZegoUIKitPrebuiltLiveStreamingConfig.audience(enableCoHosting: true)
        let liveVC: ZegoUIKitPrebuiltLiveStreamingVC = ZegoUIKitPrebuiltLiveStreamingVC(self.appID, appSign: self.appSign, userID: self.userID ?? "", userName: self.userName ?? "", liveID: self.roomIDTextField.text ?? "", config: config)
        liveVC.modalPresentationStyle = .fullScreen
        liveVC.delegate = self // 设置监听器
        //...
        self.present(liveVC, animated: true, completion: nil)
    }
}

extension ViewController: ZegoUIKitPrebuiltLiveStreamingVCDelegate {

    func getPKBattleForegroundView(_ parentView: UIView, userInfo: ZegoUIKitUser) -> UIView? {
        let view = UIView()
        let button: UIButton = UIButton()
        button.frame = CGRect(x: 30, y: 30, width: 80, height: 40)
        view.addSubview(button)
        return view
    }
    
    func getPKBattleTopView(_ parentView: UIView, userList: [ZegoUIKitUser]) -> UIView? {
        let view = UIView()
        view.backgroundColor = UIColor.red
        return view
    }
    
    func getPKBattleBottomView(_ parentView: UIView, userList: [ZegoUIKitUser]) -> UIView? {
        let view = UIView()
        view.backgroundColor = UIColor.blue
        return view
    }
}

1
Copied!

效果将如下所示:

示例源代码

Previous

设置用户头像

Next

发送虚拟礼物