Skip to content

Commit

Permalink
0.0.1 rc
Browse files Browse the repository at this point in the history
  • Loading branch information
maxvol committed Sep 27, 2018
1 parent c6b8d1f commit ecf6d28
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 2 deletions.
33 changes: 33 additions & 0 deletions README.md
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
```


84 changes: 82 additions & 2 deletions RxAVFoundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
94DF2750215CA8A400051F68 /* RxAVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94DF2746215CA8A300051F68 /* RxAVFoundation.framework */; };
94DF2755215CA8A400051F68 /* RxAVFoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94DF2754215CA8A400051F68 /* RxAVFoundationTests.swift */; };
94DF2757215CA8A400051F68 /* RxAVFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DF2749215CA8A300051F68 /* RxAVFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
94DF2766215CAAAA00051F68 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94DF2765215CAAAA00051F68 /* RxSwift.framework */; };
94DF2768215CB2D900051F68 /* AVCaptureSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94DF2767215CB2D900051F68 /* AVCaptureSession+Rx.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -29,13 +31,20 @@
94DF274F215CA8A400051F68 /* RxAVFoundationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxAVFoundationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
94DF2754215CA8A400051F68 /* RxAVFoundationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxAVFoundationTests.swift; sourceTree = "<group>"; };
94DF2756215CA8A400051F68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
94DF2765215CAAAA00051F68 /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = ../../Carthage/Build/iOS/RxSwift.framework; sourceTree = "<group>"; };
94DF2767215CB2D900051F68 /* AVCaptureSession+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVCaptureSession+Rx.swift"; sourceTree = "<group>"; };
94DF2769215D476600051F68 /* Cartfile.resolved */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.resolved; sourceTree = "<group>"; };
94DF276A215D476600051F68 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
94DF276B215D476600051F68 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
94DF276C215D476600051F68 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
94DF2743215CA8A300051F68 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
94DF2766215CAAAA00051F68 /* RxSwift.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -53,9 +62,14 @@
94DF273C215CA8A300051F68 = {
isa = PBXGroup;
children = (
94DF276C215D476600051F68 /* Cartfile */,
94DF2769215D476600051F68 /* Cartfile.resolved */,
94DF276A215D476600051F68 /* LICENSE */,
94DF276B215D476600051F68 /* README.md */,
94DF2748215CA8A300051F68 /* RxAVFoundation */,
94DF2753215CA8A400051F68 /* RxAVFoundationTests */,
94DF2747215CA8A300051F68 /* Products */,
94DF2764215CAAA900051F68 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand All @@ -73,6 +87,7 @@
children = (
94DF2749215CA8A300051F68 /* RxAVFoundation.h */,
94DF274A215CA8A300051F68 /* Info.plist */,
94DF2767215CB2D900051F68 /* AVCaptureSession+Rx.swift */,
);
path = RxAVFoundation;
sourceTree = "<group>";
Expand All @@ -86,6 +101,14 @@
path = RxAVFoundationTests;
sourceTree = "<group>";
};
94DF2764215CAAA900051F68 /* Frameworks */ = {
isa = PBXGroup;
children = (
94DF2765215CAAAA00051F68 /* RxSwift.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand All @@ -108,6 +131,8 @@
94DF2742215CA8A300051F68 /* Sources */,
94DF2743215CA8A300051F68 /* Frameworks */,
94DF2744215CA8A300051F68 /* Resources */,
94DF2762215CAA4F00051F68 /* Carthage */,
94DF2763215CAA5200051F68 /* Delete Nested Framework(s) */,
);
buildRules = (
);
Expand Down Expand Up @@ -148,6 +173,7 @@
TargetAttributes = {
94DF2745215CA8A300051F68 = {
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1000;
};
94DF274E215CA8A400051F68 = {
CreatedOnToolsVersion = 10.0;
Expand Down Expand Up @@ -189,11 +215,52 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
94DF2762215CAA4F00051F68 /* Carthage */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(SRCROOT)/Carthage/Build/iOS/RxSwift.framework",
);
name = Carthage;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks\n";
};
94DF2763215CAA5200051F68 /* Delete Nested Framework(s) */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Delete Nested Framework(s)";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\nif [[ -d \"Frameworks\" ]]; then\n rm -fr Frameworks\nfi\n";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
94DF2742215CA8A300051F68 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
94DF2768215CB2D900051F68 /* AVCaptureSession+Rx.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -268,7 +335,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -326,7 +393,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
Expand All @@ -341,12 +408,17 @@
94DF275B215CA8A400051F68 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = RxAVFoundation/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -357,6 +429,7 @@
PRODUCT_BUNDLE_IDENTIFIER = maxvol.RxAVFoundation;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand All @@ -365,12 +438,17 @@
94DF275C215CA8A400051F68 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = RxAVFoundation/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -389,6 +467,7 @@
94DF275E215CA8A400051F68 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = RxAVFoundationTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -406,6 +485,7 @@
94DF275F215CA8A400051F68 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = RxAVFoundationTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down
80 changes: 80 additions & 0 deletions RxAVFoundation/AVCaptureSession+Rx.swift
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)
}

}

0 comments on commit ecf6d28

Please sign in to comment.