From 0428d5961ef3562afe584ce20a3d16adbd6d59c0 Mon Sep 17 00:00:00 2001 From: thanhlt36 Date: Sat, 18 Jan 2020 15:36:24 +0700 Subject: [PATCH] -Update code swift 5 --- CoreImageVideo.xcodeproj/project.pbxproj | 3 + CoreImageVideo/AppDelegate.swift | 0 CoreImageVideo/Base.lproj/Main.storyboard | 0 CoreImageVideo/CameraBufferSource.swift | 15 +++-- CoreImageVideo/Cat.mp4 | Bin CoreImageVideo/CoreImageView.swift | 12 ++-- CoreImageVideo/Extensions.swift | 26 ++++---- CoreImageVideo/FunctionalCoreImage.swift | 62 +++++++++--------- .../AppIcon.appiconset/Contents.json | 0 CoreImageVideo/Info.plist | 0 .../SimpleFilterViewController.swift | 12 ++-- .../StaticVideoViewController.swift | 14 ++-- CoreImageVideo/VideoSampleBufferSource.swift | 32 ++++----- CoreImageVideoTests/CoreImageVideoTests.swift | 0 CoreImageVideoTests/Info.plist | 0 15 files changed, 92 insertions(+), 84 deletions(-) mode change 100644 => 100755 CoreImageVideo.xcodeproj/project.pbxproj mode change 100644 => 100755 CoreImageVideo/AppDelegate.swift mode change 100644 => 100755 CoreImageVideo/Base.lproj/Main.storyboard mode change 100644 => 100755 CoreImageVideo/CameraBufferSource.swift mode change 100644 => 100755 CoreImageVideo/Cat.mp4 mode change 100644 => 100755 CoreImageVideo/CoreImageView.swift mode change 100644 => 100755 CoreImageVideo/Extensions.swift mode change 100644 => 100755 CoreImageVideo/FunctionalCoreImage.swift mode change 100644 => 100755 CoreImageVideo/Images.xcassets/AppIcon.appiconset/Contents.json mode change 100644 => 100755 CoreImageVideo/Info.plist mode change 100644 => 100755 CoreImageVideo/SimpleFilterViewController.swift mode change 100644 => 100755 CoreImageVideo/StaticVideoViewController.swift mode change 100644 => 100755 CoreImageVideo/VideoSampleBufferSource.swift mode change 100644 => 100755 CoreImageVideoTests/CoreImageVideoTests.swift mode change 100644 => 100755 CoreImageVideoTests/Info.plist diff --git a/CoreImageVideo.xcodeproj/project.pbxproj b/CoreImageVideo.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 6685e9b..138b4b2 --- a/CoreImageVideo.xcodeproj/project.pbxproj +++ b/CoreImageVideo.xcodeproj/project.pbxproj @@ -199,6 +199,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -368,6 +369,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -379,6 +381,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/CoreImageVideo/AppDelegate.swift b/CoreImageVideo/AppDelegate.swift old mode 100644 new mode 100755 diff --git a/CoreImageVideo/Base.lproj/Main.storyboard b/CoreImageVideo/Base.lproj/Main.storyboard old mode 100644 new mode 100755 diff --git a/CoreImageVideo/CameraBufferSource.swift b/CoreImageVideo/CameraBufferSource.swift old mode 100644 new mode 100755 index 86325fe..3c495c0 --- a/CoreImageVideo/CameraBufferSource.swift +++ b/CoreImageVideo/CameraBufferSource.swift @@ -24,9 +24,10 @@ struct CaptureBufferSource { } } - init?(device: AVCaptureDevice, transform: CGAffineTransform, callback: BufferConsumer) { + init?(device: AVCaptureDevice, transform: CGAffineTransform, callback: @escaping BufferConsumer) { captureSession = AVCaptureSession() - if let deviceInput = AVCaptureDeviceInput(device: device, error: nil) where captureSession.canAddInput(deviceInput) { + + if let deviceInput = try? AVCaptureDeviceInput(device: device), captureSession.canAddInput(deviceInput) { captureSession.addInput(deviceInput) let dataOutput = AVCaptureVideoDataOutput() dataOutput.alwaysDiscardsLateVideoFrames = true @@ -34,7 +35,7 @@ struct CaptureBufferSource { captureDelegate = CaptureBufferDelegate { buffer in callback(buffer, transform) } - dataOutput.setSampleBufferDelegate(captureDelegate, queue: dispatch_get_main_queue()) + dataOutput.setSampleBufferDelegate(captureDelegate, queue: DispatchQueue.main) captureSession.addOutput(dataOutput) captureSession.commitConfiguration() return @@ -42,7 +43,7 @@ struct CaptureBufferSource { return nil } - init?(position: AVCaptureDevicePosition, callback: BufferConsumer) { + init?(position: AVCaptureDevice.Position, callback: @escaping BufferConsumer) { if let camera = position.device { self.init(device: camera, transform: position.transform, callback: callback) return @@ -52,13 +53,13 @@ struct CaptureBufferSource { } private class CaptureBufferDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { - let callback: CMSampleBuffer -> () + let callback: (CMSampleBuffer) -> () - init(_ callback: CMSampleBuffer -> ()) { + init(_ callback: @escaping (CMSampleBuffer) -> ()) { self.callback = callback } func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) { callback(sampleBuffer) } -} \ No newline at end of file +} diff --git a/CoreImageVideo/Cat.mp4 b/CoreImageVideo/Cat.mp4 old mode 100644 new mode 100755 diff --git a/CoreImageVideo/CoreImageView.swift b/CoreImageVideo/CoreImageView.swift old mode 100644 new mode 100755 index 775ed32..78610ce --- a/CoreImageVideo/CoreImageView.swift +++ b/CoreImageVideo/CoreImageView.swift @@ -18,12 +18,12 @@ class CoreImageView: GLKView { let coreImageContext: CIContext override convenience init(frame: CGRect) { - let eaglContext = EAGLContext(API: EAGLRenderingAPI.OpenGLES2) + let eaglContext = EAGLContext(api: EAGLRenderingAPI.openGLES2) self.init(frame: frame, context: eaglContext) } override init(frame: CGRect, context eaglContext: EAGLContext!) { - coreImageContext = CIContext(EAGLContext: eaglContext) + coreImageContext = CIContext(eaglContext: eaglContext) super.init(frame: frame, context: eaglContext) // We will be calling display() directly, hence this needs to be false enableSetNeedsDisplay = false @@ -33,11 +33,11 @@ class CoreImageView: GLKView { fatalError("init(coder:) has not been implemented") } - override func drawRect(rect: CGRect) { + override func draw(_ rect: CGRect) { if let img = image { let scale = self.window?.screen.scale ?? 1.0 - let destRect = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(scale, scale)) - coreImageContext.drawImage(img, inRect: destRect, fromRect: img.extent()) + let destRect = bounds.applying(CGAffineTransform(scaleX: scale, y: scale)) + coreImageContext.draw(img, in: destRect, from: img.extent) } } -} \ No newline at end of file +} diff --git a/CoreImageVideo/Extensions.swift b/CoreImageVideo/Extensions.swift old mode 100644 new mode 100755 index 6be777b..45d60dc --- a/CoreImageVideo/Extensions.swift +++ b/CoreImageVideo/Extensions.swift @@ -12,27 +12,27 @@ import AVFoundation extension CGAffineTransform { init(rotatingWithAngle angle: CGFloat) { - let t = CGAffineTransformMakeRotation(angle) + let t = CGAffineTransform(rotationAngle: angle) self.init(a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty) } init(scaleX sx: CGFloat, scaleY sy: CGFloat) { - let t = CGAffineTransformMakeScale(sx, sy) + let t = CGAffineTransform(scaleX: sx, y: sy) self.init(a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty) } func scale(sx: CGFloat, sy: CGFloat) -> CGAffineTransform { - return CGAffineTransformScale(self, sx, sy) + return CGAffineTransform(scaleX: sx, y: sy) } func rotate(angle: CGFloat) -> CGAffineTransform { - return CGAffineTransformRotate(self, angle) + return CGAffineTransform(rotationAngle: angle) } } extension CIImage { convenience init(buffer: CMSampleBuffer) { - self.init(CVPixelBuffer: CMSampleBufferGetImageBuffer(buffer)) + self.init(cvPixelBuffer: CMSampleBufferGetImageBuffer(buffer)!) } } @@ -42,22 +42,22 @@ extension CGRect { } } -extension AVCaptureDevicePosition { +extension AVCaptureDevice.Position { var transform: CGAffineTransform { switch self { - case .Front: - return CGAffineTransform(rotatingWithAngle: -CGFloat(M_PI_2)).scale(1, sy: -1) - case .Back: - return CGAffineTransform(rotatingWithAngle: -CGFloat(M_PI_2)) + case .front: + return CGAffineTransform(rotatingWithAngle: -CGFloat(Double.pi/2)).scale(sx: 1, sy: -1) + case .back: + return CGAffineTransform(rotatingWithAngle: -CGFloat(Double.pi/2)) default: - return CGAffineTransformIdentity + return .identity } } var device: AVCaptureDevice? { - return AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo).filter { + return AVCaptureDevice.devices(for: AVMediaType.video).filter { $0.position == self }.first as? AVCaptureDevice } -} \ No newline at end of file +} diff --git a/CoreImageVideo/FunctionalCoreImage.swift b/CoreImageVideo/FunctionalCoreImage.swift old mode 100644 new mode 100755 index 7e84d08..eccd33a --- a/CoreImageVideo/FunctionalCoreImage.swift +++ b/CoreImageVideo/FunctionalCoreImage.swift @@ -9,48 +9,48 @@ import Foundation import UIKit -typealias Filter = CIImage -> CIImage +typealias Filter = ((CIImage) -> (CIImage)) func blur(radius: Double) -> Filter { return { image in - let parameters = [ + let parameters:[String:Any] = [ kCIInputRadiusKey: radius, kCIInputImageKey: image ] let filter = CIFilter(name: "CIGaussianBlur", - withInputParameters: parameters) - return filter.outputImage + parameters: parameters) + return filter!.outputImage! } } -func colorGenerator(color: UIColor) -> Filter { +func colorGenerator(_ color: UIColor) -> Filter { return { _ in let parameters = [kCIInputColorKey: color] let filter = CIFilter(name: "CIConstantColorGenerator", - withInputParameters: parameters) - return filter.outputImage + parameters: parameters) + return filter!.outputImage! } } func hueAdjust(angleInRadians: Float) -> Filter { return { image in - let parameters = [ + let parameters:[String : Any] = [ kCIInputAngleKey: angleInRadians, kCIInputImageKey: image - ] + ] let filter = CIFilter(name: "CIHueAdjust", - withInputParameters: parameters) - return filter.outputImage + parameters: parameters) + return filter!.outputImage! } } func pixellate(scale: Float) -> Filter { return { image in - let parameters = [ + let parameters:[String : Any] = [ kCIInputImageKey:image, kCIInputScaleKey:scale ] - return CIFilter(name: "CIPixellate", withInputParameters: parameters).outputImage + return CIFilter(name: "CIPixellate", parameters: parameters)!.outputImage! } } @@ -59,44 +59,44 @@ func kaleidoscope() -> Filter { let parameters = [ kCIInputImageKey:image, ] - return CIFilter(name: "CITriangleKaleidoscope", withInputParameters: parameters).outputImage.imageByCroppingToRect(image.extent()) + return CIFilter(name: "CITriangleKaleidoscope", parameters: parameters)!.outputImage!.cropped(to: image.extent) } } func vibrance(amount: Float) -> Filter { return { image in - let parameters = [ + let parameters:[String:Any] = [ kCIInputImageKey: image, "inputAmount": amount ] - return CIFilter(name: "CIVibrance", withInputParameters: parameters).outputImage + return CIFilter(name: "CIVibrance", parameters: parameters)!.outputImage! } } -func compositeSourceOver(overlay: CIImage) -> Filter { +func compositeSourceOver(_ overlay: CIImage) -> Filter { return { image in - let parameters = [ + let parameters:[String:Any] = [ kCIInputBackgroundImageKey: image, kCIInputImageKey: overlay ] let filter = CIFilter(name: "CISourceOverCompositing", - withInputParameters: parameters) - let cropRect = image.extent() - return filter.outputImage.imageByCroppingToRect(cropRect) + parameters: parameters) + let cropRect = image.extent + return filter!.outputImage!.cropped(to:cropRect) } } func radialGradient(center: CGPoint, radius: CGFloat) -> CIImage { - let params: [NSObject: AnyObject] = [ + let params: [String: Any] = [ "inputColor0": CIColor(red: 1, green: 1, blue: 1), "inputColor1": CIColor(red: 0, green: 0, blue: 0), - "inputCenter": CIVector(CGPoint: center), + "inputCenter": CIVector(cgPoint: center), "inputRadius0": radius, "inputRadius1": radius + 1 ] - return CIFilter(name: "CIRadialGradient", withInputParameters: params).outputImage + return CIFilter(name: "CIRadialGradient", parameters: params)!.outputImage! } func blendWithMask(background: CIImage, mask: CIImage) -> Filter { @@ -107,9 +107,9 @@ func blendWithMask(background: CIImage, mask: CIImage) -> Filter { kCIInputImageKey: image ] let filter = CIFilter(name: "CIBlendWithMask", - withInputParameters: parameters) - let cropRect = image.extent() - return filter.outputImage.imageByCroppingToRect(cropRect) + parameters: parameters) + let cropRect = image.extent + return filter!.outputImage!.cropped(to:cropRect) } } @@ -120,9 +120,11 @@ func colorOverlay(color: UIColor) -> Filter { } } +infix operator >>>: FilterPrecedence -infix operator >>> { associativity left } - -func >>> (filter1: Filter, filter2: Filter) -> Filter { +precedencegroup FilterPrecedence { + associativity: left +} +func >>> (filter1: @escaping Filter, filter2: @escaping Filter) -> Filter { return { img in filter2(filter1(img)) } } diff --git a/CoreImageVideo/Images.xcassets/AppIcon.appiconset/Contents.json b/CoreImageVideo/Images.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 diff --git a/CoreImageVideo/Info.plist b/CoreImageVideo/Info.plist old mode 100644 new mode 100755 diff --git a/CoreImageVideo/SimpleFilterViewController.swift b/CoreImageVideo/SimpleFilterViewController.swift old mode 100644 new mode 100755 index c9a0c37..577c470 --- a/CoreImageVideo/SimpleFilterViewController.swift +++ b/CoreImageVideo/SimpleFilterViewController.swift @@ -14,7 +14,7 @@ class SimpleFilterViewController: UIViewController { var coreImageView: CoreImageView? var angleForCurrentTime: Float { - return Float(NSDate.timeIntervalSinceReferenceDate() % M_PI*2) + return Float( Date.timeIntervalSinceReferenceDate.truncatingRemainder(dividingBy: Double.pi) * 2) } override func loadView() { @@ -22,18 +22,18 @@ class SimpleFilterViewController: UIViewController { self.view = coreImageView } - override func viewDidAppear(animated: Bool) { + override func viewDidAppear(_ animated: Bool) { setupCameraSource() } - override func viewDidDisappear(animated: Bool) { + override func viewDidDisappear(_ animated: Bool) { source?.running = false } func setupCameraSource() { - source = CaptureBufferSource(position: AVCaptureDevicePosition.Front) { [unowned self] (buffer, transform) in - let input = CIImage(buffer: buffer).imageByApplyingTransform(transform) - let filter = hueAdjust(self.angleForCurrentTime) + source = CaptureBufferSource(position: AVCaptureDevice.Position.front) { [unowned self] (buffer, transform) in + let input = CIImage(buffer: buffer).transformed(by: transform) + let filter = hueAdjust(angleInRadians: self.angleForCurrentTime) self.coreImageView?.image = filter(input) } source?.running = true diff --git a/CoreImageVideo/StaticVideoViewController.swift b/CoreImageVideo/StaticVideoViewController.swift old mode 100644 new mode 100755 index dca8df4..739e246 --- a/CoreImageVideo/StaticVideoViewController.swift +++ b/CoreImageVideo/StaticVideoViewController.swift @@ -14,7 +14,7 @@ class StaticVideoViewController: UIViewController { var videoSource: VideoSampleBufferSource? var angleForCurrentTime: Float { - return Float(NSDate.timeIntervalSinceReferenceDate() % M_PI*2) + return Float(Date.timeIntervalSinceReferenceDate.truncatingRemainder(dividingBy: TimeInterval(Double.pi)) * 2.0) } override func loadView() { @@ -22,14 +22,14 @@ class StaticVideoViewController: UIViewController { self.view = coreImageView } - override func viewDidAppear(animated: Bool) { - let url = NSBundle.mainBundle().URLForResource("Cat", withExtension: "mp4")! + override func viewDidAppear(_ animated: Bool) { + let url = Bundle.main.url(forResource: "Cat", withExtension: "mp4")! videoSource = VideoSampleBufferSource(url: url) { [unowned self] buffer in - let image = CIImage(CVPixelBuffer: buffer) + let image = CIImage(cvPixelBuffer: buffer) let background = kaleidoscope()(image) - let mask = radialGradient(image.extent().center, CGFloat(self.angleForCurrentTime) * 100) - let output = blendWithMask(image, mask)(background) + let mask = radialGradient(center: image.extent.center, radius: CGFloat(self.angleForCurrentTime) * 100) + let output = blendWithMask(background: image, mask: mask)(background) self.coreImageView?.image = output } } -} \ No newline at end of file +} diff --git a/CoreImageVideo/VideoSampleBufferSource.swift b/CoreImageVideo/VideoSampleBufferSource.swift old mode 100644 new mode 100755 index d6093f5..6e8fcc6 --- a/CoreImageVideo/VideoSampleBufferSource.swift +++ b/CoreImageVideo/VideoSampleBufferSource.swift @@ -10,23 +10,24 @@ import Foundation import AVFoundation import GLKit -let pixelBufferDict: [NSObject:AnyObject] = - [kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] +let pixelBufferDict: [String:Any] = + [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] class VideoSampleBufferSource: NSObject { lazy var displayLink: CADisplayLink = - CADisplayLink(target: self, selector: "displayLinkDidRefresh:") + CADisplayLink(target: self, selector: #selector(displayLinkDidRefresh(link:))) let videoOutput: AVPlayerItemVideoOutput - let consumer: CVPixelBuffer -> () + let consumer: ((CVPixelBuffer) -> ()) let player: AVPlayer - init?(url: NSURL, consumer callback: CVPixelBuffer -> ()) { - player = AVPlayer(URL: url) + init?(url: URL, consumer callback: @escaping (CVPixelBuffer) -> ()) { + player = AVPlayer(url: url) consumer = callback + videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: pixelBufferDict) - player.currentItem.addOutput(videoOutput) + player.currentItem?.add(videoOutput) super.init() @@ -35,17 +36,18 @@ class VideoSampleBufferSource: NSObject { } func start() { - displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) + displayLink.add( to: RunLoop.main, forMode: RunLoop.Mode.common) } - func displayLinkDidRefresh(link: CADisplayLink) { - let itemTime = videoOutput.itemTimeForHostTime(CACurrentMediaTime()) - if videoOutput.hasNewPixelBufferForItemTime(itemTime) { - var presentationItemTime = kCMTimeZero - let pixelBuffer = videoOutput.copyPixelBufferForItemTime(itemTime, itemTimeForDisplay: &presentationItemTime) - consumer(pixelBuffer) + @objc func displayLinkDidRefresh(link: CADisplayLink) { + let itemTime = videoOutput.itemTime(forHostTime: CACurrentMediaTime()) + if videoOutput.hasNewPixelBuffer(forItemTime: itemTime) { + var presentationItemTime = CMTime.zero + if let pixelBuffer = videoOutput.copyPixelBuffer(forItemTime: itemTime, itemTimeForDisplay: &presentationItemTime) { + consumer(pixelBuffer) + } } } -} \ No newline at end of file +} diff --git a/CoreImageVideoTests/CoreImageVideoTests.swift b/CoreImageVideoTests/CoreImageVideoTests.swift old mode 100644 new mode 100755 diff --git a/CoreImageVideoTests/Info.plist b/CoreImageVideoTests/Info.plist old mode 100644 new mode 100755