I am implementing video calls using pjsip and callkit. The remote video view is coming fine and the call is happening well. But when I am trying to implement a local video view the video is stuck on the other side.
But on my side local and remote video view both working well. I tried but nothing i am getting.
Local view:-
struct LocalVideoView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView();
view.backgroundColor = UIColor.black;
return view;
}
func updateUIView(_ uiView: UIView, context: Context) {
// Perform AVCaptureSession setup on a background thread
DispatchQueue.global(qos: .userInitiated).async {
self.setupAVCaptureSession(uiView)
}
}
func setupAVCaptureSession(_ uiView: UIView) {
let captureSession = AVCaptureSession()
let cameraOutput = AVCaptureVideoDataOutput()
captureSession.sessionPreset = .high
guard let frontCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else {
print("Front camera not available")
return
}
do {
let input = try AVCaptureDeviceInput(device: frontCamera)
if captureSession.canAddInput(input) {
captureSession.addInput(input)
}
if captureSession.canAddOutput(cameraOutput) {
captureSession.addOutput(cameraOutput)
}
let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer.videoGravity = .resizeAspectFill
captureSession.sessionPreset = .medium // You can adjust the preset as needed
// videoPreviewLayer.connection?.videoOrientation = .portrait // Adjust orientation if needed
if let frameRateRanges = frontCamera.activeFormat.videoSupportedFrameRateRanges.first {
// Choose a frame rate within the supported range (e.g., 30 FPS)
let desiredFrameRate = min(30, frameRateRanges.maxFrameRate)
do {
try frontCamera.lockForConfiguration()
frontCamera.activeVideoMinFrameDuration = CMTime(value: 1, timescale: CMTimeScale(desiredFrameRate))
frontCamera.activeVideoMaxFrameDuration = CMTime(value: 1, timescale: CMTimeScale(desiredFrameRate))
frontCamera.unlockForConfiguration()
} catch {
print("Error setting frame rate: \(error.localizedDescription)")
}
} else {
print("No supported frame rate ranges found for the camera.")
}
// Perform UI updates related to AVCaptureSession on the main thread
DispatchQueue.main.async {
videoPreviewLayer.frame = uiView.layer.bounds
uiView.layer.addSublayer(videoPreviewLayer)
}
captureSession.startRunning()
} catch {
print("Error setting up capture session: \(error.localizedDescription)")
}
}
}
media state where i am passing remote video view using PJSIP
private func on_call_media_state(call_id: pjsua_call_id) {
var ci = pjsua_call_info();
pjsua_call_get_info(call_id, &ci);
for mi in 0...ci.media_cnt {
let media: [pjsua_call_media_info] = tupleToArray(tuple: ci.media);
if (media[Int(mi)].status == PJSUA_CALL_MEDIA_ACTIVE ||
media[Int(mi)].status == PJSUA_CALL_MEDIA_REMOTE_HOLD)
{
switch (media[Int(mi)].type) {
case PJMEDIA_TYPE_AUDIO:
var call_conf_slot: pjsua_conf_port_id;
call_conf_slot = media[Int(mi)].stream.aud.conf_slot;
pjsua_conf_connect(call_conf_slot, 0);
pjsua_conf_connect(0, call_conf_slot);
DispatchQueue.main.async {
let hostingController = UIHostingController(rootView: AudioCallView())
VidInfo.shared.vid_win = hostingController.view
}
break;
case PJMEDIA_TYPE_VIDEO:
let wid = media[Int(mi)].stream.vid.win_in;
var wi = pjsua_vid_win_info();
if (pjsua_vid_win_get_info(wid, &wi) == PJ_SUCCESS.rawValue) {
let vid_win:UIView =
Unmanaged<UIView>.fromOpaque(wi.hwnd.info.ios.window).takeUnretainedValue();
DispatchQueue.main.async {
vid_win.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2.0))
VidInfo.shared.vid_win = vid_win
print("Server view is \(String(describing: VidInfo.shared.vid_win))")
}
}
break;
default:
break;
}
}
}
}