import MetalKit import UIKit final class ViewController: UIViewController { private let mtkView = MTKView() private let renderer: Renderer? private let videoReader = VideoReader() private let sampleConverter: SampleConverter? init() { let device = MTLCreateSystemDefaultDevice() let pixelFormat = MTLPixelFormat.bgra8Unorm if let device = device { renderer = Renderer(device: device, pixelFormat: pixelFormat) sampleConverter = SampleConverter(device: device, pixelFormat: pixelFormat) } else { renderer = nil sampleConverter = nil } super.init(nibName: nil, bundle: nil) mtkView.delegate = renderer mtkView.device = device mtkView.clearColor = MTLClearColor(red: 1, green: 215 / 255, blue: 0, alpha: 1) mtkView.colorPixelFormat = pixelFormat } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .green view.addSubview(mtkView) startReadVideo() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() mtkView.frame = CGRect(x: 0, y: view.safeAreaInsets.top, width: view.bounds.width, height: view.bounds.height - view.safeAreaInsets.top - view.safeAreaInsets.bottom) } private func startReadVideo() { guard let sampleConverter = sampleConverter, let videoReader = videoReader else { return } videoReader.sampleRead = { [weak self] sample in guard let texture = sampleConverter.convert(sample: sample) else { return } DispatchQueue.main.async { [weak self] in self?.renderer?.showTexture(texture) } } videoReader.readSamples() } }