Skip to content

Instantly share code, notes, and snippets.

@standinga
Created December 12, 2020 22:34
Show Gist options
  • Save standinga/49a7087ca4c20f08e03970f378bb46d8 to your computer and use it in GitHub Desktop.
Save standinga/49a7087ca4c20f08e03970f378bb46d8 to your computer and use it in GitHub Desktop.
Medium article about VideoToolbox h264 encoding and decoding
//
// AVManager.swift
// VideoToolboxArticle
//
// Created by michal on 26/10/2020.
//
import AVFoundation
class AVManager {
// MARK: - Properties
var session: AVCaptureSession!
private var camera: AVCaptureDevice?
let delegate: AVCaptureVideoDataOutputSampleBufferDelegate
// MARK: - Life Cycle
init(delegate: AVCaptureVideoDataOutputSampleBufferDelegate) {
self.delegate = delegate
}
// MARK: - Helpers
func start() {
requestCameraPermission { [weak self] granted in
guard granted else {
print("no camera access")
return
}
self?.setupCaptureSession()
}
}
private func setupCaptureSession() {
DispatchQueue(label:"co.borama.sessionQueue").async {
let deviceTypes: [AVCaptureDevice.DeviceType] = [ .builtInWideAngleCamera
]
let discoverySession = AVCaptureDevice.DiscoverySession(
deviceTypes: deviceTypes,
mediaType: .video,
position: .front)
let session = AVCaptureSession()
guard let camera = discoverySession.devices.first else { fatalError("no camera") }
self.camera = camera
session.beginConfiguration()
do {
let videoIn = try AVCaptureDeviceInput(device: camera)
if session.canAddInput(videoIn) {
session.addInput(videoIn)
} else {
print("failed to add video input")
return
}
} catch {
print("failed to initialized video input")
return
}
let videoOut = AVCaptureVideoDataOutput()
videoOut.videoSettings = [ kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) ]
videoOut.setSampleBufferDelegate(self.delegate, queue: DispatchQueue(label: "videoQueue"))
if session.canAddOutput(videoOut) {
session.addOutput(videoOut)
} else {
print("failed to add video output")
return
}
session.commitConfiguration()
session.startRunning()
self.session = session
}
}
private func requestCameraPermission(handler: @escaping (Bool) -> Void) {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized: // The user has previously granted access to the camera.
handler(true)
case .notDetermined: // The user has not yet been asked for camera access.
AVCaptureDevice.requestAccess(for: .video) { granted in
handler(granted)
}
case .denied, .restricted: // The user can't grant access due to restrictions.
handler(false)
@unknown default:
fatalError()
}
}
// MARK: - Types
enum AVError: Error {
case noCamera
case cameraAccess
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment