I started your agora project with deepar but ran into a problem. That is, when I connect two people to streaming, the video of the other participant is not always displayed. Let’s say I launch a stream of two people three times and everything works, I launch it for the fourth time and one of them stops displaying the video of another participant.
How to solve this problem?
The example (GitHub - DeepARSDK/videocall-ios-swift: Video call using Agora.io SDK with face masks provided by DeepAR SDK) has the same behavior.
DeepAR SDK version 4.0.3
Agora version 4.1.0
import UIKit
import DeepAR
import AgoraRtcKit
class ViewController: UIViewController {
@IBOutlet weak var localVideo: UIView!
@IBOutlet weak var remoteVideo: UIView!
@IBOutlet weak var hangUpButton: UIButton!
@IBOutlet weak var micButton: UIButton!
@IBOutlet weak var cameraButton: UIButton!
// Defines localView
// var localView: UIView!
var agoraKit: AgoraRtcEngineKit!
var userRole: AgoraClientRole = .broadcaster
private var deepAr: DeepAR!
private var arView: ARView!
private var cameraController: CameraController!
private var maskPaths = [Bundle.main.path(forResource: "mask-1.deepar", ofType: nil),
Bundle.main.path(forResource: "mask-2.deepar", ofType: nil),
Bundle.main.path(forResource: "mask-3.deepar", ofType: nil)]
let AppID: String = "dff2d9630bb0426386af15e5796e0eb0"
let token = "007eJxTYHDZdTGn5sjlrRG7LzPeyuMNVbm2bU2Q9oxHJy5dqgtZJnhDgSElLc0oxdLM2CApycDEyMzYwiwxzdA01dTc0izVIDXJwP/y7uSGQEaG9oWRjIwMEAjiszOUZaak5ju6MDAAAG+CIsQ="
var channelID = "videoAD"
var deepArID = "c7bd70481e36df05b8af9eb3cee77785a7d5248ad56fc35603bc786a0576edc8c248ab8e98351543"
override func viewDidLoad() {
super.viewDidLoad()
initializeAgoraEngine()
setupVideo()
setupDeepAR()
setupARCamera()
joinChannel()
// setupLocalVideo()
switchMode()
}
@IBAction func didClickHangUpButton(_ sender: UIButton) {
sender.isSelected.toggle()
micButton.isHidden.toggle()
cameraButton.isHidden.toggle()
if sender.isSelected {
agoraKit.stopPreview()
agoraKit.leaveChannel(nil)
UIApplication.shared.isIdleTimerDisabled = false
} else {
initializeAgoraEngine()
setupVideo()
// setupLocalVideo()
setupDeepAR()
setupARCamera()
joinChannel()
switchMode()
}
}
@IBAction func didClickMuteButton(_ sender: UIButton) {
sender.isSelected.toggle()
agoraKit.muteLocalAudioStream(sender.isSelected)
}
@IBAction func didClickSwitchCameraButton(_ sender: UIButton) {
sender.isSelected.toggle()
agoraKit.switchCamera()
}
func initializeAgoraEngine() {
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: AppID, delegate: self)
}
func setupDeepAR() {
deepAr = DeepAR()
deepAr.setLicenseKey(deepArID)
deepAr.delegate = self
}
func setupVideo() {
agoraKit.enableVideo()
agoraKit.disableAudio()
agoraKit.setExternalVideoSource(true, useTexture: true, sourceType: .videoFrame)
agoraKit.setVideoEncoderConfiguration(
AgoraVideoEncoderConfiguration(size: AgoraVideoDimension640x360,
frameRate: .fps15,
bitrate: AgoraVideoBitrateStandard,
orientationMode: .adaptative,
mirrorMode: .auto))
agoraKit.setClientRole(.broadcaster)
agoraKit.setChannelProfile(.liveBroadcasting)
}
private func setupARCamera() {
arView = deepAr.createARView(withFrame: localVideo.frame) as! ARView
arView.translatesAutoresizingMaskIntoConstraints = false
localVideo.addSubview(arView)
arView.leftAnchor.constraint(equalTo: localVideo.leftAnchor, constant: 0).isActive = true
arView.rightAnchor.constraint(equalTo: localVideo.rightAnchor, constant: 0).isActive = true
arView.topAnchor.constraint(equalTo: localVideo.topAnchor, constant: 0).isActive = true
arView.bottomAnchor.constraint(equalTo: localVideo.bottomAnchor, constant: 0).isActive = true
localVideo.isHidden = true
cameraController = CameraController()
cameraController.deepAR = deepAr
cameraController.startCamera()
}
func joinChannel() {
let option = AgoraRtcChannelMediaOptions()
option.clientRoleType = .broadcaster
option.channelProfile = .communication
agoraKit.joinChannel(byToken: token, channelId: channelID, uid: 0, mediaOptions: option) { (channel, uid, elapsed) in
UIApplication.shared.isIdleTimerDisabled = true
self.deepAr.startCapture(withOutputWidth: 360, outputHeight: 640, subframe: CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0))
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = 0
videoCanvas.renderMode = .hidden
videoCanvas.view = self.localVideo
// Set the local video view
self.agoraKit.setupLocalVideo(videoCanvas)
self.localVideo.isHidden = false
self.remoteVideo.isHidden = false
}
}
func switchMode() {
deepAr.switchEffect(withSlot: "effect", path: maskPaths[0])
}
}
extension ViewController: AgoraRtcEngineDelegate {
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.renderMode = .hidden
videoCanvas.view = remoteVideo
agoraKit.setupRemoteVideo(videoCanvas)
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid:UInt, reason:AgoraUserOfflineReason) {
remoteVideo.isHidden = true
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didVideoMuted muted:Bool, byUid:UInt) {
remoteVideo.isHidden = muted
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) {
print("did occur ***WARNING***, code: \(warningCode.rawValue)")
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) {
print("did occur ***ERROR***, code: \(errorCode.rawValue)")
}
}
extension ViewController: DeepARDelegate {
func didFinishPreparingForVideoRecording() {}
func didStartVideoRecording() {}
func frameAvailable(_ sampleBuffer: CMSampleBuffer!) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
print("*** NO BUFFER ERROR")
return
}
let time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
let videoFrame = AgoraVideoFrame()
videoFrame.format = 12
videoFrame.time = time
videoFrame.textureBuf = pixelBuffer
videoFrame.rotation = 0
agoraKit?.pushExternalVideoFrame(videoFrame)
}
func didFinishVideoRecording(_ videoFilePath: String!) {}
func recordingFailedWithError(_ error: Error!) {}
func didTakeScreenshot(_ screenshot: UIImage!) {}
func didInitialize() {}
func faceVisiblityDidChange(_ faceVisible: Bool) {
print("faceVisible: \(faceVisible)")
}
}