Sign up for our live Camera Kit office hour on July 17 @ 9:30am (PT) / 4:30pm (GMT)

iOS - Changing CameraKit video output resolution

Options
Roy
Roy Posts: 29 🔥
edited June 2022 in General #1

I'd like to have all videos captured via CameraKit to be captured in the 1080x1920 HD resolution.

I've been able to find the area that is responsible for the video output size, it is in the Recorder.swift file.

In the Recorder's init function:

public init(url: URL, orientation: AVCaptureVideoOrientation, size: CGSize) throws {
        outputURL = url
        writer = try AVAssetWriter(outputURL: url, fileType: .mp4)
        videoInput = AVAssetWriterInput(
            mediaType: .video,
            outputSettings: [
                AVVideoCodecKey: AVVideoCodecType.h264,
                AVVideoHeightKey: size.height,
                AVVideoWidthKey: size.width,
                AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill,
            ]
        )

The "size" param, which is called from the CameraController.swift class, is calculated based on the "OutputSizeHelper.normalizedSize" function, which takes the aspect ratio of the screen size, not the view itself:

recorder = try? Recorder(
            url: URL(fileURLWithPath: "\(NSTemporaryDirectory())\(UUID().uuidString).mp4"),
            orientation: cameraKit.activeInput.frameOrientation,
            size: OutputSizeHelper.normalizedSize(
                for: cameraKit.activeInput.frameSize,
                aspectRatio: UIScreen.main.bounds.width / UIScreen.main.bounds.height,
                orientation: cameraKit.activeInput.frameOrientation)
        )

What would be the best approach to adjust the video output size to a custom value?

Thanks!

Comments

  • Roy
    Roy Posts: 29 🔥
    Options

    As a follow up, I've currently been able to get desired functionality doing two things:

    1. Initialising the camera view controller with the relevant properties
    let lensesConfig = LensesConfig(cacheConfig: CacheConfig(lensContentMaxSize: 150 * 1024 * 1024))
            let cameraKit = Session(sessionConfig: nil, lensesConfig: lensesConfig, errorHandler: nil)
            let captureSession = AVCaptureSession()
            captureSession.sessionPreset = .hd1920x1080
    
            let cameraViewController = SnapCameraViewController(cameraKit: cameraKit, captureSession: captureSession, repoGroups: [SCCameraKitLensRepositoryBundledGroup, Constants.supercreatorBaseGroupId, Constants.kevinsBasegroupId])
    
    1. Changing the aspectRatio directly in the CameraContainer.swift pod file
    let aspectRatio = 1080.0 / 1920.0
            recorder = try? Recorder(
                url: URL(fileURLWithPath: "\(NSTemporaryDirectory())\(UUID().uuidString).mp4"),
                orientation: cameraKit.activeInput.frameOrientation,
                size: OutputSizeHelper.normalizedSize(
                    for: cameraKit.activeInput.frameSize,
                    aspectRatio: aspectRatio,
                    orientation: cameraKit.activeInput.frameOrientation)
            )
    

    The caveat is that I'm directly modifying the pod's source file, meaning it wont persist between pod installs + is generally not a good way of making the change.

    Just filling as I'm still trying to figure out an optimal solution :)

  • arashp
    arashp Posts: 52 🔥🔥
    edited June 2022 #3
    Options

    Hi @Roy, thanks for the question and the code snippets!

    You can change the recording aspect ratio to 1920x1080 exactly as you have in option (2) above. If you only do that though, the lens will render on just part of the screen--in both preview and post-capture.

    So, in addition, you will need to configure the viewport to match the aspect ratio of the recording. You can use our helper class ExplicitViewportProvider to do that, e.g. in CameraViewController.setup():

    let safeArea = CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.0)
    let aspectRatio = 1080.0 / 1920.0
    
    let viewportSize = OutputSizeHelper.normalizedSize(
    ​    for: cameraController.cameraKit.activeInput.frameSize,
    ​    aspectRatio: aspectRatio,
    ​    orientation: cameraController.cameraKit.activeInput.frameOrientation)
    
    ​cameraView.previewView.explicitViewportProvider = ExplicitViewportProvider(
    ​    viewportSize: viewportSize, 
    ​    outputResolution: getScreenResolution(), 
        safeArea: safeArea)
    

    Still, some Lenses might not be designed to work in that aspect ratio and, as a result, might get cutoff on the screen. For this reason, we recommend using the default behavior of our PreviewView, which keeps to the size and aspect ratio of the screen.

  • arashp
    arashp Posts: 52 🔥🔥
    Options

    Regarding changing classes in the pod, you can often subclass them. But since the methods here are private, you will probably want to copy over the class to keep your changes across pod installs.

  • Roy
    Roy Posts: 29 🔥
    Options

    Thanks @arashp - that's what I did, I create my own versions of the classes and was then able to modify the output size accordingly and make more customizations.

    That wasn't clear from docs initially but glad it works now :)

    @arashp said:
    Regarding changing classes in the pod, you can often subclass them. But since the methods here are private, you will probably want to copy over the class to keep your changes across pod installs.