Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct remote video size on iPhoneX during video call using webrtc iOS swift

I am using webRTC for video calling. Everything is running smooth but I am struggling with aspect ratio of Remote video on iPhoneX, XSMax. I am seeing lot of zoom in video. Can you please help me out how I can manage remote video on devices that have notch. Below is the code where I am handling remote size.

func videoView(_ videoView: RTCEAGLVideoView, didChangeVideoSize size: CGSize) {
    print(size)

    let defaultAspectRatio: CGSize = CGSize(width: 4, height: 3)
    let aspectRatio: CGSize = size.equalTo(CGSize.zero) ? defaultAspectRatio : size
    let videoRect: CGRect = self.view.bounds
    let maxFloat = CGFloat.maximum(self.view.frame.width, self.view.frame.height)
    let newAspectRatio = aspectRatio.width / aspectRatio.height
    var frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
    if (aspectRatio.width < aspectRatio.height) {
        frame.size.width = maxFloat;
        frame.size.height = frame.size.width / newAspectRatio;
    } else {
        frame.size.height = maxFloat;
        frame.size.width = frame.size.height * newAspectRatio;
    }
    frame.origin.x = (self.view.frame.width - frame.size.width) / 2
    frame.origin.y = (self.view.frame.height - frame.size.height) / 2

self.remoteView.frame = frame

}
like image 498
Raj Shekhar Avatar asked Jun 24 '19 14:06

Raj Shekhar


1 Answers

According to @Eysner's answer, what is work for me, the final code (written using swift 5):

import UIKit
import WebRTC


final class WebRTCView: UIView, RTCVideoViewDelegate {
    let videoView = RTCEAGLVideoView(frame: .zero)
    var videoSize = CGSize.zero

    override init(frame: CGRect) {
        super.init(frame: frame)
        videoView.delegate = self
        addSubview(videoView)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        videoView.delegate = self
        addSubview(videoView)
    }

    func videoView(_ videoView: RTCVideoRenderer, didChangeVideoSize size: CGSize) {
        self.videoSize = size
        setNeedsLayout()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        guard videoSize.width > 0 && videoSize.height > 0 else {
            videoView.frame = bounds
            return
        }

        var videoFrame = AVMakeRect(aspectRatio: videoSize, insideRect: bounds)
        let scale = videoFrame.size.aspectFitScale(in: bounds.size)
        videoFrame.size.width = videoFrame.size.width * CGFloat(scale)
        videoFrame.size.height = videoFrame.size.height * CGFloat(scale)

        videoView.frame = videoFrame
        videoView.center = CGPoint(x: bounds.midX, y: bounds.midY)
    }
}


extension CGSize {
    func aspectFitScale(in container: CGSize) -> CGFloat {

        if height <= container.height && width > container.width {
            return container.width / width
        }
        if height > container.height && width > container.width {
            return min(container.width / width, container.height / height)
        }
        if height > container.height && width <= container.width {
            return container.height / height
        }
        if height <= container.height && width <= container.width {
            return min(container.width / width, container.height / height)
        }
        return 1.0
    }
}

There is aspectFitScale function, it is simply to describe logic, you can refactor it if you want to.

I'm using this approach in the demo: https://github.com/Maxatma/Walkie-Talkie/

like image 176
Zaporozhchenko Oleksandr Avatar answered Sep 21 '22 21:09

Zaporozhchenko Oleksandr