Heads up! We're sunsetting this forum to streamline our community space.

join us on Discord for support, updates, and all things Snap AR! See you there!
Sign up for our live Camera Kit office hour on July 17 @ 9:30am (PT) / 4:30pm (GMT)

iOS - Changing CameraKit video output resolution

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 🔥

    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

    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 🔥🔥

    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 🔥

    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.

  • To ensure that all videos captured using CameraKit are in 1080x1920 HD resolution, you’ll need to adjust the video output size in your code. Here’s how you can make these adjustments based on your provided code:

    Step-by-Step Guide
    Modify the Recorder Initialization:

    Change the size parameter in the Recorder class to a fixed resolution of 1080x1920.

    swift
    Copy code
    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,
    ]
    )
    }
    Set Custom Size in CameraController.swift:

    Adjust the size parameter to always be 1080x1920. Override the OutputSizeHelper.normalizedSize function to return this fixed size:

    swift
    Copy code
    recorder = try? Recorder(
    url: URL(fileURLWithPath: "(NSTemporaryDirectory())(UUID().uuidString).mp4"),
    orientation: cameraKit.activeInput.frameOrientation,
    size: CGSize(width: 1080, height: 1920) // Custom resolution
    )
    Update OutputSizeHelper if Needed:

    Ensure that the OutputSizeHelper does not alter your fixed resolution. If it does, you might need to bypass or modify its implementation.

    If OutputSizeHelper is being used to determine the video resolution, you can either set it to always return CGSize(width: 1080, height: 1920) or adjust the logic to fit your custom resolution.

    Example modification might be:

    swift
    Copy code
    static func normalizedSize(for frameSize: CGSize, aspectRatio: CGFloat, orientation: AVCaptureVideoOrientation) -> CGSize {
    // Return fixed size
    return CGSize(width: 1080, height: 1920)
    }
    Check and Adjust Aspect Ratio:

    Ensure that the aspect ratio used in video recording settings aligns with the 1080x1920 resolution. Since 1080x1920 is a portrait mode resolution, confirm that any scaling or cropping aligns with this format.

    Test Your Changes:

    After making these changes, test the video capture to confirm that the output resolution is consistently 1080x1920.

    Summary
    By setting the size parameter directly to CGSize(width: 1080, height: 1920) in the CameraController.swift class, you will ensure that all videos recorded are in the desired resolution. Additionally, make sure that the OutputSizeHelper and any related configurations support or do not override this fixed resolution.

    Feel free to adjust the steps based on the exact requirements of your application and the functionality of the OutputSizeHelper.

    you can see more details here Calculadora De Tempo

Categories