Keval Gajjar
Keval Gajjar

Reputation: 69

How to modify FPS, Bit rate and resolution for the video programmatically in iOS?

I am implementing the functionality for to record the video in my iOS application,

Also, i am using ReplayKit to record a full screen instead of the camera's default capturing

In that there is a requirement for customizing, (1) Resolution (2) FPS (frames) (3) Bit Rate

to implement the above functionalities i am currently working on (1) Resolution and (2) FPS.

For this i have set the resolution and FPS as coded below.

class PreviewView: UIView {

     private var captureSession: AVCaptureSession?
     private var shakeCountDown: Timer?
     let videoFileOutput = AVCaptureMovieFileOutput()
     var recordingDelegate:AVCaptureFileOutputRecordingDelegate!
     var recorded = 0
     var secondsToReachGoal = 30
     var videoDevice: AVCaptureDevice?

     var onRecord: ((Int, Int)->())?
     var onReset: (() -> ())?
     var onComplete: (() -> ())?

     //MARK:- Screen Recording Variables
     let recorder = RPScreenRecorder.shared()
     var isRecording = false

init() {
    super.init(frame: .zero)
    var allowedAccess = false
    let blocker = DispatchGroup()
    blocker.enter()
    AVCaptureDevice.requestAccess(for: .video) { flag in
        allowedAccess = flag
        blocker.leave()
    }
    blocker.wait()
    recorder.isMicrophoneEnabled = true
    if !allowedAccess {
        print("!!! NO ACCESS TO CAMERA")
        return
    }
    
    // setup session
    let session = AVCaptureSession()
    session.beginConfiguration()
            
    videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera,
                                              for: .video, position: .back)
    guard videoDevice != nil, let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!), session.canAddInput(videoDeviceInput) else {
        print("!!! NO CAMERA DETECTED")
        return
    }
    session.addInput(videoDeviceInput)
    session.commitConfiguration()
    self.captureSession = session
    
    //MARK: Test Cases
    //Setup the resolution
    captureSession?.sessionPreset = AVCaptureSession.Preset.inputPriority
    
    // Setup the frame
    videoDevice?.set(frameRate: 20) // 1 to 30 FPS
    

}

override class var layerClass: AnyClass {
    AVCaptureVideoPreviewLayer.self
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

var videoPreviewLayer: AVCaptureVideoPreviewLayer {
    return layer as! AVCaptureVideoPreviewLayer
}

override func didMoveToSuperview() {
     super.didMoveToSuperview()
     recordingDelegate = self
}   }

and, to set frame rates (FPS) i have created one extension as below:

extension AVCaptureDevice {
  func set(frameRate: Double) {
    
    var isFPSSupported = false
    do {

         let supportedFrameRange = activeFormat.videoSupportedFrameRateRanges
            for range in supportedFrameRange {
                if (range.maxFrameRate >= Double(frameRate) && range.minFrameRate <= Double(frameRate)) {
                    isFPSSupported = true
                    break
                }
            }

        if isFPSSupported {
            try lockForConfiguration()
            activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: Int32(frameRate))
            activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: Int32(frameRate))
            unlockForConfiguration()
        }

    } catch {
        print("lockForConfiguration error: \(error.localizedDescription)")
    }
  }
}

I have checked the scenario for preset the session like, (1) AVCaptureSession.Preset.inputPriority (2) AVCaptureSession.Preset.hd1280x720 etc...

But, i got result on saved video like screenshots below:

As screenshot describe the FPS is 59.88 FPS which is not same as what we set through the code, as in code i have set 20 as FPS.

and the second question is how we can set the resolution? Because in all the preset session scenarios it's taking always the resolution like, 828 x 1792

How can we achieve this? Any help would be appreciable

Thanks in advance

Upvotes: 0

Views: 1593

Answers (1)

thaozz
thaozz

Reputation: 7

  • check isFPSSupported == true or not, I use activeVideoMaxFrameDuration and activeVideoMinFrameDuration and it's worked.
  • to set custom resolution that IOS not in list supported, I use FFmpeg and crop video after recording it. You also need show only crop preview that you want to crop too

Upvotes: 0

Related Questions