-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
195 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,35 @@ | ||
# RxAVFoundation | ||
RxAVFoundation (based on RxSwift) | ||
|
||
Basic usage. | ||
|
||
```swift | ||
let session = AVCaptureSession.rx.session() | ||
session | ||
.flatMapLatest { (session) -> Observable<CaptureOutput> in | ||
return session.message | ||
} | ||
.subscribe { (event) in | ||
switch event { | ||
case .next(let captureOutput): | ||
// handle 'captureOutput' | ||
break | ||
case .error(let error): | ||
// handle error | ||
break | ||
case .completed: | ||
// never happens | ||
break | ||
} | ||
} | ||
.disposed(by: disposeBag) | ||
``` | ||
|
||
Carthage setup. | ||
|
||
``` | ||
github "maxvol/RxAVFoundation" ~> 0.0.1 | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// | ||
// AVCaptureSession+Rx.swift | ||
// RxAVFoundation | ||
// | ||
// Created by Maxim Volgin on 27/09/2018. | ||
// Copyright © 2018 Maxim Volgin. All rights reserved. | ||
// | ||
|
||
import AVFoundation | ||
#if !RX_NO_MODULE | ||
import RxSwift | ||
import RxCocoa | ||
#endif | ||
|
||
public typealias CaptureOutput = (output: AVCaptureOutput, sampleBuffer: CMSampleBuffer, connection: AVCaptureConnection) | ||
|
||
final class RxAVCaptureVideoDataOutputSampleBufferDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { | ||
|
||
typealias Observer = AnyObserver<CaptureOutput> | ||
|
||
var observer: Observer? | ||
|
||
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { | ||
observer?.on(.next(CaptureOutput(output, sampleBuffer, connection))) | ||
} | ||
|
||
} | ||
|
||
public struct RxAVCaptureSession { | ||
|
||
public let session: AVCaptureSession | ||
public let previewLayer: AVCaptureVideoPreviewLayer | ||
public let captureOutput: Observable<CaptureOutput> | ||
|
||
private let delegate: RxAVCaptureVideoDataOutputSampleBufferDelegate | ||
|
||
public init() { | ||
let session = AVCaptureSession() | ||
let delegate = RxAVCaptureVideoDataOutputSampleBufferDelegate() | ||
let previewLayer = AVCaptureVideoPreviewLayer(session: session) | ||
let captureOutput: Observable<CaptureOutput> = Observable | ||
.create { observer in | ||
delegate.observer = observer | ||
return Disposables.create { | ||
session.stopRunning() | ||
} | ||
} | ||
.do(onSubscribed: { | ||
session.sessionPreset = AVCaptureSession.Preset.photo | ||
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video) | ||
let deviceInput = try! AVCaptureDeviceInput(device: captureDevice!) | ||
let deviceOutput = AVCaptureVideoDataOutput() | ||
deviceOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)] | ||
deviceOutput.setSampleBufferDelegate(delegate, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default)) | ||
session.addInput(deviceInput) | ||
session.addOutput(deviceOutput) | ||
deviceOutput.connections.first?.videoOrientation = .portrait | ||
session.startRunning() | ||
}) | ||
self.captureOutput = captureOutput | ||
self.previewLayer = previewLayer | ||
self.delegate = delegate | ||
self.session = session | ||
} | ||
|
||
} | ||
|
||
extension Reactive where Base: AVCaptureSession { | ||
|
||
static public func session() -> Observable<RxAVCaptureSession> { | ||
return Observable | ||
.create { observer in | ||
let session = RxAVCaptureSession() | ||
observer.on(.next(session)) | ||
return Disposables.create() | ||
} | ||
.share(replay: 1, scope: .whileConnected) | ||
} | ||
|
||
} |