diff --git a/CHANGELOG.md b/CHANGELOG.md index 96ac420..545460a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and the Camera Kit SDK adheres to [Semantic Versioning](https://semver.org/spec/ ## [Unreleased] + +## [1.37.0] - 2024-12-18 +### Features +- Lens Studio 5.4 support +- Support for Lens HTTP requests + ## [1.36.1] - 2024-11-22 ### Bug Fixes diff --git a/Package.swift b/Package.swift index 1aff408..c037185 100644 --- a/Package.swift +++ b/Package.swift @@ -20,14 +20,14 @@ let package = Package( targets: [ .binaryTarget( name: "SCSDKCameraKit", - url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.36.1/SCSDKCameraKit.xcframework.zip", - checksum: "e545e4caf8604200f7843804973871c7464baa6eb4dfd2c2b3826d4bce70d449" + url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.37.0/SCSDKCameraKit.xcframework.zip", + checksum: "cf23027909a57693f627cec4a248ddc7ca2476defd652b4a4a6af714d748f781" ), .binaryTarget( name: "SCSDKCameraKitBaseExtension", - url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.36.1/SCSDKCameraKitBaseExtension.xcframework.zip", - checksum: "778ae89a1fe1ad64069a82fee0e8d8056452bdc75fc247f7a32049818c36716c" + url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.37.0/SCSDKCameraKitBaseExtension.xcframework.zip", + checksum: "3c6e0f4835fd3a583ca4a84f04afbb56f2638fb178ba083a1deacf1904794fcb" ), .target( name: "SCSDKCameraKitBaseExtension_Wrapper", @@ -40,8 +40,8 @@ let package = Package( .binaryTarget( name: "SCSDKCameraKitLoginKitAuth", - url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.36.1/SCSDKCameraKitLoginKitAuth.xcframework.zip", - checksum: "25e1ed3f77d13b5e84c4695adfcd3532277648b40518fccebef3e960de93c8f6" + url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.37.0/SCSDKCameraKitLoginKitAuth.xcframework.zip", + checksum: "03eac84b236881fa60eb58d016ecd8a03310e7232071c49aaf71112ce4f791ed" ), .target( name: "SCSDKCameraKitLoginKitAuth_Wrapper", @@ -55,8 +55,8 @@ let package = Package( .binaryTarget( name: "SCSDKCameraKitPushToDeviceExtension", - url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.36.1/SCSDKCameraKitPushToDeviceExtension.xcframework.zip", - checksum: "d99fb0f238a49000d5d646b60913666c72f83c731752574cfcf8223bfb736c56" + url: "https://storage.googleapis.com/snap-kit-build/scsdk/camera-kit-ios/releases-spm/1.37.0/SCSDKCameraKitPushToDeviceExtension.xcframework.zip", + checksum: "de2ed7ae58fc7a14da191797917d734ddd9d734548e6df903798af3f28949abc" ), .target( name: "SCSDKCameraKitPushToDeviceExtension_Wrapper", diff --git a/README.md b/README.md index 357547c..c3450b7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Camera Kit for iOS -[Home Page](https://developers.snap.com/camera-kit/home) | [Documentation & Guides](https://developers.snap.com/camera-kit/getting-started/what-is-camera-kit) | [Showcase](https://ar.snap.com/camera-kit) | [API Reference](https://kit.snapchat.com/reference/CameraKit/ios/1.36.1/index.html) | [Developer Portal](https://kit.snapchat.com/manage/) | [My Lenses](https://my-lenses.snapchat.com/) | [Discord](https://discord.gg/snapar) +[Home Page](https://developers.snap.com/camera-kit/home) | [Documentation & Guides](https://developers.snap.com/camera-kit/getting-started/what-is-camera-kit) | [Showcase](https://ar.snap.com/camera-kit) | [API Reference](https://kit.snapchat.com/reference/CameraKit/ios/1.37.0/index.html) | [Developer Portal](https://kit.snapchat.com/manage/) | [My Lenses](https://my-lenses.snapchat.com/) | [Discord](https://discord.gg/snapar) Camera Kit brings the power of Snap's AR platform to your websites and mobile apps on iOS and Android. It has never been easier to create and deliver scalable, multi-platform AR experiences to meet your customers, wherever they are. diff --git a/Sources/SCSDKCameraKitReferenceUI/Camera/CameraController.swift b/Sources/SCSDKCameraKitReferenceUI/Camera/CameraController.swift index 2d6c44d..888e784 100644 --- a/Sources/SCSDKCameraKitReferenceUI/Camera/CameraController.swift +++ b/Sources/SCSDKCameraKitReferenceUI/Camera/CameraController.swift @@ -91,7 +91,7 @@ open class CameraController: NSObject, LensRepositoryGroupObserver, LensPrefetch public private(set) var photoCaptureOutput: PhotoCaptureOutput? /// An output used for recording videos. - public private(set) var recorder: Recorder? + public var recorder: Recorder? // MARK: Data providers @@ -424,8 +424,27 @@ open class CameraController: NSObject, LensRepositoryGroupObserver, LensPrefetch } } } - - // MARK: Recording + + // MARK: Recorder + + /// Configures the recorder to be ready to record a new video. + open func configureRecorder() { + if let old = recorder { + cameraKit.remove(output: old.output) + } + 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 + ) + ) + if let recorder { + cameraKit.add(output: recorder.output) + } + } /// Begin recording video. open func startRecording() { @@ -716,29 +735,6 @@ private extension CameraController { } } -// MARK: Recording - -private extension CameraController { - /// Configures the recorder to be ready to record a new video. - func configureRecorder() { - if let old = recorder { - cameraKit.remove(output: old.output) - } - 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 - ) - ) - if let recorder { - cameraKit.add(output: recorder.output) - } - } -} - // MARK: Lens Application extension CameraController { diff --git a/Sources/SCSDKCameraKitReferenceUI/CameraUI/CameraViewController.swift b/Sources/SCSDKCameraKitReferenceUI/CameraUI/CameraViewController.swift index dc5e667..94fef8d 100644 --- a/Sources/SCSDKCameraKitReferenceUI/CameraUI/CameraViewController.swift +++ b/Sources/SCSDKCameraKitReferenceUI/CameraUI/CameraViewController.swift @@ -550,7 +550,6 @@ extension CameraViewController: CameraButtonDelegate { print("Camera button tapped") cameraController.takePhoto { image, error in guard let image else { return } - self.cameraController.clearLens(willReapply: true) DispatchQueue.main.async { self.cameraController.restoreBrightnessIfNecessary() let viewController = ImagePreviewViewController(image: image) @@ -560,7 +559,9 @@ extension CameraViewController: CameraButtonDelegate { self?.cameraController.reapplyCurrentLens() self?.cameraController.increaseBrightnessIfNecessary() } - self.present(viewController, animated: true, completion: nil) + self.present(viewController, animated: true) { [weak self] in + self?.cameraController.clearLens(willReapply: true) + } } } } diff --git a/Sources/SCSDKCameraKitReferenceUI/Helper/OutputSizeHelper.swift b/Sources/SCSDKCameraKitReferenceUI/Helper/OutputSizeHelper.swift index 1f66b71..791a515 100644 --- a/Sources/SCSDKCameraKitReferenceUI/Helper/OutputSizeHelper.swift +++ b/Sources/SCSDKCameraKitReferenceUI/Helper/OutputSizeHelper.swift @@ -5,7 +5,7 @@ import AVFoundation import Foundation /// Provides helper functions to determine output sizes given input sizes and other constraints (aspect ratio, orientation, etc.) -enum OutputSizeHelper { +public enum OutputSizeHelper { /// Returns the size normalized to a new aspect ratio and orientation. /// For example, given an input size of 1080x1920 and aspect ratio of 0.462 and portrait orientation, /// this will return a new size of 887x1920. @@ -14,7 +14,7 @@ enum OutputSizeHelper { /// - aspectRatio: The aspect ratio to normalize the output size to. /// - orientation: The orientation of the input size (defaults to portrait). /// - Returns: The new size normalized to the aspect ratio. - static func normalizedSize( + public static func normalizedSize( for size: CGSize, aspectRatio: CGFloat, orientation: AVCaptureVideoOrientation = .portrait ) -> CGSize { var height = orientation == .portrait ? size.height : size.width diff --git a/Sources/SCSDKCameraKitReferenceUI/Recorder/Recorder.swift b/Sources/SCSDKCameraKitReferenceUI/Recorder/Recorder.swift index 604ddd9..f97b4f3 100644 --- a/Sources/SCSDKCameraKitReferenceUI/Recorder/Recorder.swift +++ b/Sources/SCSDKCameraKitReferenceUI/Recorder/Recorder.swift @@ -11,11 +11,15 @@ public class Recorder { /// The AVWriterOutput for CameraKt. public let output: AVWriterOutput + /// Flip captured video horizontally. + /// - Attention: If your camera pipeline uses AVFoundation, you do not need to set this property. + /// - Note: By default this is FALSE. When set to FALSE, the capture will be mirrored on the front and not mirrored on the back camera. + /// - Note: If set to TRUE, the capture will be mirrored on top of any mirroring done by AVFoundation: Capture is mirrored if either horizontallyMirrored is TRUE or device set to front camera is TRUE. If both are TRUE the two mirroring operations will cancel out. + public var horizontallyMirror: Bool = false private let writer: AVAssetWriter private let videoInput: AVAssetWriterInput private let pixelBufferInput: AVAssetWriterInputPixelBufferAdaptor - private let audioInput: AVAssetWriterInput = { let compressionAudioSettings: [String: Any] = [ @@ -35,6 +39,9 @@ public class Recorder { /// - url: output URL of video file /// - orientation: current orientation of device /// - size: height of video output + /// - mirrored:flip video capture horizontally. If false, Recorder will automatically mirror capture + /// based on AVFoundation camera configuration. If true, Recorder will flip the capture. Set this parameter + /// to true when manually mirroring the input with LensProcessor.setInputHorizontallyMirrored. /// - Throws: Throws error if cannot create asset writer with output file URL and file type public init(url: URL, orientation: AVCaptureVideoOrientation, size: CGSize) throws { self.outputURL = url @@ -48,8 +55,8 @@ public class Recorder { AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill, ] ) - videoInput.expectsMediaDataInRealTime = true - videoInput.transform = Recorder.affineTransform(orientation: orientation, mirrored: false) + + videoInput.transform = Recorder.affineTransform(orientation: orientation, mirrored: self.horizontallyMirror) self.pixelBufferInput = AVAssetWriterInputPixelBufferAdaptor( assetWriterInput: videoInput, @@ -78,7 +85,7 @@ public class Recorder { } } - private static func affineTransform(orientation: AVCaptureVideoOrientation, mirrored: Bool) + public static func affineTransform(orientation: AVCaptureVideoOrientation, mirrored: Bool) -> CGAffineTransform { var transform: CGAffineTransform = .identity diff --git a/Sources/SCSDKCameraKitReferenceUI/Support/Testable.swift b/Sources/SCSDKCameraKitReferenceUI/Support/Testable.swift index 6e1af1b..51dc5bd 100644 --- a/Sources/SCSDKCameraKitReferenceUI/Support/Testable.swift +++ b/Sources/SCSDKCameraKitReferenceUI/Support/Testable.swift @@ -97,4 +97,5 @@ public enum OtherElements: String, TestableElement { case tapToFocusView case pairingButton case connectedLensStartButton + case mirrorButton } diff --git a/VERSION b/VERSION index f107550..bf50e91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.36.1 +1.37.0