Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 054d23ca50 | |||
| 7fb760dab0 | |||
| 6693e32ecf | |||
| b79af89eb6 | |||
| b0b7f41904 | |||
| 105e8360e4 | |||
| 71f2f27d11 | |||
| 6d1624c730 | |||
| 6aa443b3d9 | |||
| 30087d53d3 | |||
| c7ad4295a1 | |||
| f9cabf3ea4 | |||
| 85f1f00a91 | |||
| a14ef8d6cc | |||
| 0c4bae5fb6 | |||
| f5c87b097c | |||
| 4af1d53984 |
@@ -14,7 +14,7 @@ internal extension UIScreen {
|
||||
`isiPhone10` is a boolean that returns if the device is iPhone X or not.
|
||||
*/
|
||||
internal var isiPhone10: Bool {
|
||||
return self.nativeBounds.size == CGSize(width: 1125, height: 2436)
|
||||
return self.nativeBounds.size == CGSize(width: 1125, height: 2436) || self.nativeBounds.size == CGSize(width: 2436, height: 1125)
|
||||
}
|
||||
}
|
||||
@available(iOS 11.0, *)
|
||||
|
||||
@@ -37,7 +37,7 @@ internal class GIFGenerator {
|
||||
|
||||
guard let path = self.currentGIFPath else{return}
|
||||
guard let destination = CGImageDestinationCreateWithURL(path as CFURL, kUTTypeGIF, images.count, nil) else{finished?(false, nil);return}
|
||||
print(destination)
|
||||
logAR.message("\(destination)")
|
||||
CGImageDestinationSetProperties(destination, gifSettings as CFDictionary)
|
||||
for image in images {
|
||||
if let imageRef = image.cgImage {
|
||||
|
||||
@@ -27,9 +27,12 @@ internal struct RenderAR {
|
||||
}else if let view = view as? ARSKView {
|
||||
guard let rawBuffer = view.session.currentFrame?.capturedImage else{return nil}
|
||||
return rawBuffer
|
||||
}else if let _ = view as? SCNView {
|
||||
return buffer
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
internal var bufferSize:CGSize? {
|
||||
guard let raw = rawBuffer else{return nil};
|
||||
var width = CVPixelBufferGetWidth(raw);
|
||||
@@ -98,6 +101,18 @@ internal struct RenderAR {
|
||||
}
|
||||
guard let buffer = renderedFrame!.buffer else{return nil};
|
||||
return buffer;
|
||||
}else if let _ = view as? SCNView {
|
||||
let size = UIScreen.main.bounds.size
|
||||
var renderedFrame:UIImage?
|
||||
pixelsQueue.sync {
|
||||
renderedFrame = renderEngine.snapshot(atTime: self.time, with: size, antialiasingMode: .none);
|
||||
}
|
||||
if let _ = renderedFrame {
|
||||
}else{
|
||||
renderedFrame = renderEngine.snapshot(atTime: time, with: size, antialiasingMode: .none);
|
||||
}
|
||||
guard let buffer = renderedFrame!.buffer else{return nil};
|
||||
return buffer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,22 @@ fileprivate var recentAngle = 0
|
||||
parentVC = vc
|
||||
}
|
||||
|
||||
@objc init?(SceneKit:SCNView) {
|
||||
super.init()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(deviceDidRotate), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
|
||||
ViewAR.orientation = .portrait
|
||||
|
||||
guard let vc = SceneKit.parent else {
|
||||
return
|
||||
}
|
||||
|
||||
parentVC = vc
|
||||
}
|
||||
|
||||
@objc fileprivate func deviceDidRotate() {
|
||||
guard var views = parentVC?.view.subviews else {
|
||||
return
|
||||
|
||||
@@ -87,6 +87,17 @@ fileprivate var renderer:RenderAR!
|
||||
A boolean that enables or disables clearing cached media after exporting to Camera Roll. Default is `true`.
|
||||
*/
|
||||
@objc public var deleteCacheWhenExported:Bool = true
|
||||
/**
|
||||
A boolean that enables or disables using envronment light rendering. Default is `false`.
|
||||
*/
|
||||
@objc public var enableAdjsutEnvironmentLighting:Bool = false {
|
||||
|
||||
didSet{
|
||||
if (renderEngine != nil) {
|
||||
renderEngine.autoenablesDefaultLighting = enableAdjsutEnvironmentLighting
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Public initialization methods
|
||||
/**
|
||||
@@ -117,6 +128,16 @@ fileprivate var renderer:RenderAR!
|
||||
logAR.message("Error occurred while loading SK Video Assets : \(error). Please download \"video.scnassets\" from\nwww.ahmedbekhit.com/ARVideoKitAssets")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize 🌞🍳 `RecordAR` with an `SCNView` 🚀.
|
||||
*/
|
||||
@objc override public init?(SceneKit: SCNView) {
|
||||
super.init(SceneKit: SceneKit)
|
||||
view = SceneKit
|
||||
setup()
|
||||
}
|
||||
|
||||
//MARK: - Internal threads
|
||||
internal let writerQueue = DispatchQueue(label:"com.ahmedbekhit.WriterQueue")
|
||||
internal let gifWriterQueue = DispatchQueue(label: "com.ahmedbekhit.GIFWriterQueue", attributes: .concurrent)
|
||||
@@ -131,6 +152,8 @@ fileprivate var renderer:RenderAR!
|
||||
return view.parent!
|
||||
}else if let view = view as? ARSKView {
|
||||
return view.parent!
|
||||
}else if let view = view as? SCNView {
|
||||
return view.parent!
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -169,6 +192,7 @@ fileprivate var renderer:RenderAR!
|
||||
let vidPath = "\(documentsDirectory)/\(formatter.string(from: date))ARVideo.mp4"
|
||||
return URL(fileURLWithPath: vidPath, isDirectory: false)
|
||||
}
|
||||
|
||||
//MARK: - Internal Video Setup
|
||||
internal func setup() {
|
||||
if let view = view as? ARSCNView {
|
||||
@@ -200,6 +224,16 @@ fileprivate var renderer:RenderAR!
|
||||
gpuLoop.preferredFramesPerSecond = fps.rawValue
|
||||
gpuLoop.add(to: .main, forMode: .commonModes)
|
||||
|
||||
status = .readyToRecord
|
||||
}else if let view = view as? SCNView {
|
||||
guard let mtlDevice = MTLCreateSystemDefaultDevice() else {logAR.message("ERROR:- This device does not support Metal");return}
|
||||
renderEngine = SCNRenderer(device: mtlDevice, options: nil)
|
||||
renderEngine.scene = view.scene
|
||||
|
||||
gpuLoop = CADisplayLink(target: self, selector: #selector(renderFrame))
|
||||
gpuLoop.preferredFramesPerSecond = fps.rawValue
|
||||
gpuLoop.add(to: .main, forMode: .commonModes)
|
||||
|
||||
status = .readyToRecord
|
||||
}
|
||||
|
||||
@@ -222,6 +256,8 @@ fileprivate var renderer:RenderAR!
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//MARK: - Public methods for capturing videos, photos, Live Photos, and GIFs
|
||||
@@ -656,6 +692,10 @@ fileprivate var renderer:RenderAR!
|
||||
ViewAR.orientation = .portrait
|
||||
|
||||
view.session.run(configuration)
|
||||
}else if let _ = view as? SCNView {
|
||||
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
|
||||
ViewAR.orientation = .portrait
|
||||
|
||||
}
|
||||
|
||||
onlyRenderWhileRec = onlyRenderWhileRecording
|
||||
@@ -676,12 +716,11 @@ internal extension RecordAR {
|
||||
@objc internal func renderFrame() {
|
||||
//frame rendering
|
||||
if self.onlyRenderWhileRec && !isRecording && !isRecordingGIF {return}
|
||||
|
||||
guard let buffer = renderer.buffer else{return}
|
||||
guard let rawBuffer = renderer.rawBuffer else{logAR.message("ERROR:- An error occurred while rendering the camera's main buffers.");return}
|
||||
guard let size = renderer.bufferSize else{logAR.message("ERROR:- An error occurred while rendering the camera buffer.");return}
|
||||
renderer.ARcontentMode = contentMode
|
||||
|
||||
|
||||
self.writerQueue.sync {
|
||||
var time:CMTime {return CMTimeMakeWithSeconds(renderer.time, 1000000);}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
FB36BD9420085C7B00002808 /* Scene.m in Sources */ = {isa = PBXBuildFile; fileRef = FB36BD9120085C7B00002808 /* Scene.m */; };
|
||||
FB36BD9520085C7B00002808 /* Scene.sks in Resources */ = {isa = PBXBuildFile; fileRef = FB36BD9320085C7B00002808 /* Scene.sks */; };
|
||||
FB36BD98200869D200002808 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = FB36BD97200869D200002808 /* LICENSE */; };
|
||||
FB36BD9F20086A1600002808 /* ARVideoKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BD9E20086A0B00002808 /* ARVideoKit.framework */; };
|
||||
FB36BDA020086A1600002808 /* ARVideoKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BD9E20086A0B00002808 /* ARVideoKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
FBE12A5320093EF800B0BB61 /* ARVideoKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BD9E20086A0B00002808 /* ARVideoKit.framework */; };
|
||||
FBE12A5420093EF800B0BB61 /* ARVideoKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BD9E20086A0B00002808 /* ARVideoKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -31,7 +31,7 @@
|
||||
remoteGlobalIDString = FBD604DA1FA969DD00EC9804;
|
||||
remoteInfo = ARVideoKit;
|
||||
};
|
||||
FB36BDA120086A1600002808 /* PBXContainerItemProxy */ = {
|
||||
FBE12A5520093EF800B0BB61 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = FB36BD9920086A0A00002808 /* ARVideoKit.xcodeproj */;
|
||||
proxyType = 1;
|
||||
@@ -41,13 +41,13 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
FB36BD61200816E400002808 /* Embed Frameworks */ = {
|
||||
FBE12A5720093EF800B0BB61 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
FB36BDA020086A1600002808 /* ARVideoKit.framework in Embed Frameworks */,
|
||||
FBE12A5420093EF800B0BB61 /* ARVideoKit.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -82,7 +82,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB36BD9F20086A1600002808 /* ARVideoKit.framework in Frameworks */,
|
||||
FBE12A5320093EF800B0BB61 /* ARVideoKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -205,12 +205,12 @@
|
||||
FB36BD382008166700002808 /* Sources */,
|
||||
FB36BD392008166700002808 /* Frameworks */,
|
||||
FB36BD3A2008166700002808 /* Resources */,
|
||||
FB36BD61200816E400002808 /* Embed Frameworks */,
|
||||
FBE12A5720093EF800B0BB61 /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
FB36BDA220086A1600002808 /* PBXTargetDependency */,
|
||||
FBE12A5620093EF800B0BB61 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "ARKit-Video";
|
||||
productName = "ARKit-Video";
|
||||
@@ -299,10 +299,10 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
FB36BDA220086A1600002808 /* PBXTargetDependency */ = {
|
||||
FBE12A5620093EF800B0BB61 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = ARVideoKit;
|
||||
targetProxy = FB36BDA120086A1600002808 /* PBXContainerItemProxy */;
|
||||
targetProxy = FBE12A5520093EF800B0BB61 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = P5DZ3XQ9FJ;
|
||||
INFOPLIST_FILE = "ARKit-Video/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
@@ -452,7 +452,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = P5DZ3XQ9FJ;
|
||||
INFOPLIST_FILE = "ARKit-Video/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import <SceneKit/SceneKit.h>
|
||||
#import <ARKit/ARKit.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
#import <Photos/Photos.h>
|
||||
@import ARVideoKit;
|
||||
|
||||
@interface SCNViewController : UIViewController
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import <SpriteKit/SpriteKit.h>
|
||||
#import <ARKit/ARKit.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
#import <Photos/Photos.h>
|
||||
@import ARVideoKit;
|
||||
|
||||
@interface SKViewController : UIViewController
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
|
||||
// Configure RecordAR to store media files in local app directory
|
||||
recorder.deleteCacheWhenExported = NO;
|
||||
|
||||
// Configure the envronment light rendering.
|
||||
recorder.enableAdjsutEnvironmentLighting = YES;
|
||||
}
|
||||
|
||||
-(void)viewWillAppear:(BOOL)animated {
|
||||
@@ -70,7 +73,11 @@
|
||||
[self.sceneView.session pause];
|
||||
|
||||
if(recorder.status == RecordARStatusRecording) {
|
||||
[recorder stopAndExport:NULL];
|
||||
[recorder stopAndExport:^(NSURL*_Nonnull filePath, PHAuthorizationStatus status, BOOL ready) {
|
||||
if (status == PHAuthorizationStatusAuthorized) {
|
||||
NSLog(@"Video Exported Successfully!");
|
||||
}
|
||||
}];
|
||||
}
|
||||
recorder.onlyRenderWhileRecording = YES;
|
||||
|
||||
@@ -116,7 +123,11 @@
|
||||
[sender setTitle:@"Record" forState: UIControlStateNormal];
|
||||
[self.pauseBtn setTitle:@"Pause" forState: UIControlStateNormal];
|
||||
self.pauseBtn.enabled = NO;
|
||||
[recorder stopAndExport:NULL];
|
||||
[recorder stopAndExport:^(NSURL*_Nonnull filePath, PHAuthorizationStatus status, BOOL ready) {
|
||||
if (status == PHAuthorizationStatusAuthorized) {
|
||||
NSLog(@"Video Exported Successfully!");
|
||||
}
|
||||
}];
|
||||
}
|
||||
}else if (sender.tag == 1) {
|
||||
//Record with duration
|
||||
@@ -131,7 +142,11 @@
|
||||
[self.pauseBtn setTitle:@"Pause" forState: UIControlStateNormal];
|
||||
self.pauseBtn.enabled = NO;
|
||||
self.recordBtn.enabled = YES;
|
||||
[recorder stopAndExport:NULL];
|
||||
[recorder stopAndExport:^(NSURL*_Nonnull filePath, PHAuthorizationStatus status, BOOL ready) {
|
||||
if (status == PHAuthorizationStatusAuthorized) {
|
||||
NSLog(@"Video Exported Successfully!");
|
||||
}
|
||||
}];
|
||||
}
|
||||
}else if (sender.tag == 2) {
|
||||
//Pause
|
||||
|
||||
@@ -120,7 +120,12 @@
|
||||
[sender setTitle:@"Record" forState: UIControlStateNormal];
|
||||
[self.pauseBtn setTitle:@"Pause" forState: UIControlStateNormal];
|
||||
self.pauseBtn.enabled = NO;
|
||||
[recorder stopAndExport:NULL];
|
||||
//URL, PHAuthorizationStatus, Bool
|
||||
[recorder stopAndExport:^(NSURL*_Nonnull filePath, PHAuthorizationStatus status, BOOL ready) {
|
||||
if (status == PHAuthorizationStatusAuthorized) {
|
||||
NSLog(@"Video Exported Successfully!");
|
||||
}
|
||||
}];
|
||||
}
|
||||
}else if (sender.tag == 1) {
|
||||
//Record with duration
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# Objective-C Example
|
||||
This folder provides you an example project written in Objective-C that demonstrates the use of [**ARVideoKit**](https://github.com/AFathi/ARVideoKit) framework.
|
||||
|
||||
## Implementation
|
||||
1. Import the `ARVideoKit` into the application delegate implementation file `AppDelegate.m` and a `UIViewController` class with an `ARKit` scene.
|
||||
```
|
||||
@import ARVideoKit;
|
||||
```
|
||||
|
||||
2. In the application delegate implementation file `AppDelegate.m`, add this 👇 in order to allow the framework access and identify the supported device orientations. **Recommended** if the application supports landscape orientations.
|
||||
```
|
||||
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
return ViewAR.orientation;
|
||||
}
|
||||
```
|
||||
|
||||
3. In the selected `UIViewController` class, create a [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) global variable by adding the following in the interface section of the implementation file (e.g `ViewController.m`).
|
||||
```
|
||||
@interface ViewController ()
|
||||
{
|
||||
RecordAR *recorder;
|
||||
}
|
||||
```
|
||||
|
||||
4. Initialize [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) with [`ARSCNView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arscenekitarscnview) or [`ARSKView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arspritekitarskview). **Recommended** to initialize in `(void)viewDidLoad`.
|
||||
|
||||
Initializing RecordAR with `ARSCNView`
|
||||
```
|
||||
recorder = [[RecordAR alloc] initWithARSceneKit:self.sceneView];
|
||||
```
|
||||
Initializing RecordAR with `ARSKView`
|
||||
```
|
||||
recorder = [[RecordAR alloc] initWithARSpriteKit:self.SKSceneView];
|
||||
```
|
||||
|
||||
5. Call the [`prepare()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-prepare_-configurationarconfiguration) method in `(void)viewWillAppear:(BOOL)animated`
|
||||
```
|
||||
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
|
||||
[recorder prepare:configuration];
|
||||
```
|
||||
|
||||
6. Call the [`rest()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-rest) method in `(void)viewWillDisappear:(BOOL)animated`
|
||||
```
|
||||
[recorder rest];
|
||||
```
|
||||
|
||||
7. Call the [`record()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-record) method in the proper method to start recording.
|
||||
```
|
||||
- (IBAction)startRecording:(UIButton *)sender {
|
||||
if (recorder.status == RecordARStatusReadyToRecord) {
|
||||
[recorder record];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
8. Call the [`stopAndExport()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-stopandexport_-finished-_-videopath-url-_-permissionstatusphauthorizationstatus-_-exportedbool---swiftvoid--nil) method in the proper method to stop recording.
|
||||
```
|
||||
- (IBAction)stopRecording:(UIButton *)sender {
|
||||
if (recorder.status == RecordARStatusRecording) {
|
||||
[recorder stopAndExport:NULL];
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -10,6 +10,7 @@
|
||||
FB2E368C1FAE2A510035B8D6 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = FB2E368B1FAE2A510035B8D6 /* LICENSE */; };
|
||||
FB36BDB020086BBB00002808 /* ARVideoKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BDAF20086BB000002808 /* ARVideoKit.framework */; };
|
||||
FB36BDB120086BBB00002808 /* ARVideoKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB36BDAF20086BB000002808 /* ARVideoKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
FB3B51A620489CBA000377AE /* overlay_2d_img.png in Resources */ = {isa = PBXBuildFile; fileRef = FB3B51A520489CB9000377AE /* overlay_2d_img.png */; };
|
||||
FB9B5D2E1FC49E3E005DDD60 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9B5D2D1FC49E3E005DDD60 /* MainViewController.swift */; };
|
||||
FBDCC5E71FABDFC600E3184D /* Scene.sks in Resources */ = {isa = PBXBuildFile; fileRef = FBDCC5E51FABDFC500E3184D /* Scene.sks */; };
|
||||
FBDCC5E81FABDFC600E3184D /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBDCC5E61FABDFC500E3184D /* Scene.swift */; };
|
||||
@@ -56,6 +57,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
FB2E368B1FAE2A510035B8D6 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||
FB36BDAA20086BB000002808 /* ARVideoKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ARVideoKit.xcodeproj; path = ../../ARVideoKit.xcodeproj; sourceTree = "<group>"; };
|
||||
FB3B51A520489CB9000377AE /* overlay_2d_img.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = overlay_2d_img.png; sourceTree = "<group>"; };
|
||||
FB9B5D2D1FC49E3E005DDD60 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
|
||||
FBDCC5E51FABDFC500E3184D /* Scene.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Scene.sks; sourceTree = "<group>"; };
|
||||
FBDCC5E61FABDFC500E3184D /* Scene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scene.swift; sourceTree = "<group>"; };
|
||||
@@ -144,20 +146,12 @@
|
||||
path = SK;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBE12A4B20086C9400B0BB61 /* Framework */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = Framework;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBE134AD1FAAD3DD00BEC469 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB2E368B1FAE2A510035B8D6 /* LICENSE */,
|
||||
FB36BDAA20086BB000002808 /* ARVideoKit.xcodeproj */,
|
||||
FBE134B81FAAD3DD00BEC469 /* ARVideoKit-Example */,
|
||||
FBE12A4B20086C9400B0BB61 /* Framework */,
|
||||
FBE134B71FAAD3DD00BEC469 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -173,6 +167,7 @@
|
||||
FBE134B81FAAD3DD00BEC469 /* ARVideoKit-Example */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB3B51A520489CB9000377AE /* overlay_2d_img.png */,
|
||||
FBE134B91FAAD3DD00BEC469 /* AppDelegate.swift */,
|
||||
FBA0AA0D1FAD9E4B006C481B /* View Controllers */,
|
||||
FBA0AA0C1FAD9E2C006C481B /* Storyboards */,
|
||||
@@ -264,6 +259,7 @@
|
||||
FBE134C11FAAD3DD00BEC469 /* Assets.xcassets in Resources */,
|
||||
FBDCC6401FAC2CD900E3184D /* art.scnassets in Resources */,
|
||||
FBE134BF1FAAD3DD00BEC469 /* Main.storyboard in Resources */,
|
||||
FB3B51A620489CBA000377AE /* overlay_2d_img.png in Resources */,
|
||||
FBDCC5E71FABDFC600E3184D /* Scene.sks in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -426,7 +422,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = P5DZ3XQ9FJ;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
@@ -448,7 +444,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = P5DZ3XQ9FJ;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="N8h-YD-r0X">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="N8h-YD-r0X">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -88,6 +88,10 @@
|
||||
<arscnView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IMN-9B-haO">
|
||||
<rect key="frame" x="0.0" y="10" width="375" height="667"/>
|
||||
</arscnView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="overlay_2d_img.png" translatesAutoresizingMaskIntoConstraints="NO" id="fyP-vk-9kb">
|
||||
<rect key="frame" x="0.0" y="10" width="375" height="657"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AR w/ SceneKit" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fCR-qg-FqO">
|
||||
<rect key="frame" x="97" y="20" width="181" height="65"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.65000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -235,6 +239,7 @@
|
||||
</view>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="overlayImg" destination="fyP-vk-9kb" id="VJg-xp-ImM"/>
|
||||
<outlet property="pauseBtn" destination="pCi-Bx-pwj" id="Vbx-Qf-GiU"/>
|
||||
<outlet property="recordBtn" destination="1R6-Xa-VsB" id="xFW-bY-b3A"/>
|
||||
<outlet property="sceneView" destination="IMN-9B-haO" id="6l9-yC-XES"/>
|
||||
@@ -242,7 +247,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="54" y="866"/>
|
||||
<point key="canvasLocation" x="53.600000000000001" y="865.81709145427294"/>
|
||||
</scene>
|
||||
<!--SKViewController-->
|
||||
<scene sceneID="emy-Ex-RPU">
|
||||
@@ -409,7 +414,10 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="9if-am-XF6" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="54" y="134"/>
|
||||
<point key="canvasLocation" x="53.600000000000001" y="133.5832083958021"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="overlay_2d_img.png" width="1080" height="1920"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -13,6 +13,7 @@ import Photos
|
||||
|
||||
class SCNViewController: UIViewController, ARSCNViewDelegate, RenderARDelegate, RecordARDelegate {
|
||||
|
||||
@IBOutlet weak var overlayImg: UIImageView!
|
||||
@IBOutlet var sceneView: ARSCNView!
|
||||
@IBOutlet var recordBtn: UIButton!
|
||||
@IBOutlet var pauseBtn: UIButton!
|
||||
@@ -36,6 +37,9 @@ class SCNViewController: UIViewController, ARSCNViewDelegate, RenderARDelegate,
|
||||
// Set the scene to the view
|
||||
sceneView.scene = scene
|
||||
sceneView.scene.rootNode.scale = SCNVector3(0.2, 0.2, 0.2)
|
||||
//
|
||||
sceneView.automaticallyUpdatesLighting = true
|
||||
sceneView.autoenablesDefaultLighting = true
|
||||
|
||||
// Initialize ARVideoKit recorder
|
||||
recorder = RecordAR(ARSceneKit: sceneView)
|
||||
@@ -54,6 +58,9 @@ class SCNViewController: UIViewController, ARSCNViewDelegate, RenderARDelegate,
|
||||
// Configure ARKit content mode. Default is .auto
|
||||
recorder?.contentMode = .aspectFill
|
||||
|
||||
//record or photo add environment light rendering, Default is false
|
||||
recorder?.enableAdjsutEnvironmentLighting = true
|
||||
|
||||
// Set the UIViewController orientations
|
||||
recorder?.inputViewOrientations = [.landscapeLeft, .landscapeRight, .portrait]
|
||||
// Configure RecordAR to store media files in local app directory
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 258 KiB |
@@ -0,0 +1,53 @@
|
||||
# Swift Example
|
||||
This folder provides you an example project written in Swift that demonstrates the use of [**ARVideoKit**](https://github.com/AFathi/ARVideoKit) framework.
|
||||
|
||||
## Implementation
|
||||
1. `import ARVideoKit` in the application delegate `AppDelegate.swift` and a `UIViewController` with an `ARKit` scene.
|
||||
|
||||
2. In the application delegate `AppDelegate.swift`, add this 👇 in order to allow the framework access and identify the supported device orientations. **Recommended** if the application supports landscape orientations.
|
||||
```
|
||||
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
return ViewAR.orientation
|
||||
}
|
||||
```
|
||||
|
||||
3. In the selected `UIViewController` class, create an optional type [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) global variable.
|
||||
```
|
||||
var recorder:RecordAR?
|
||||
```
|
||||
|
||||
4. Initialize [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) with [`ARSCNView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arscenekitarscnview) or [`ARSKView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arspritekitarskview). **Recommended** to initialize in `viewDidLoad()`.
|
||||
|
||||
Initializing RecordAR with `ARSCNView`
|
||||
```
|
||||
recorder = RecordAR(ARSceneKit: sceneView)
|
||||
```
|
||||
Initializing RecordAR with `ARSKView`
|
||||
```
|
||||
recorder = RecordAR(ARSpriteKit: SKSceneView)
|
||||
```
|
||||
|
||||
5. Call the [`prepare()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-prepare_-configurationarconfiguration) method in `viewWillAppear(_ animated: Bool)`
|
||||
```
|
||||
let configuration = ARWorldTrackingConfiguration()
|
||||
recorder?.prepare(configuration)
|
||||
```
|
||||
|
||||
6. Call the [`rest()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-rest) method in `viewWillDisappear(_ animated: Bool)`
|
||||
```
|
||||
recorder?.rest()
|
||||
```
|
||||
|
||||
7. Call the [`record()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-record) method in the proper method to start recording.
|
||||
```
|
||||
@IBAction func startRecording(_ sender: UIButton) {
|
||||
recorder?.record()
|
||||
}
|
||||
```
|
||||
|
||||
8. Call the [`stopAndExport()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-stopandexport_-finished-_-videopath-url-_-permissionstatusphauthorizationstatus-_-exportedbool---swiftvoid--nil) method in the proper method to stop recording.
|
||||
```
|
||||
@IBAction func stopRecording(_ sender: UIButton) {
|
||||
recorder?.stopAndExport()
|
||||
}
|
||||
```
|
||||
Binary file not shown.
@@ -285,6 +285,7 @@ enum RecordARMicrophoneStatus : NSInteger;
|
||||
enum RecordARMicrophonePermission : NSInteger;
|
||||
@class ARSCNView;
|
||||
@class ARSKView;
|
||||
@class SCNView;
|
||||
@class UIImage;
|
||||
|
||||
/// This class renders the <code>ARSCNView</code> or <code>ARSKView</code> content with the device’s camera stream to generate a video 📹, photo 🌄, live photo 🎇 or GIF 🎆.
|
||||
@@ -334,10 +335,14 @@ SWIFT_CLASS("_TtC10ARVideoKit8RecordAR") SWIFT_AVAILABILITY(ios,introduced=11.0)
|
||||
@property (nonatomic) BOOL adjustGIFForSharing;
|
||||
/// A boolean that enables or disables clearing cached media after exporting to Camera Roll. Default is <code>true</code>.
|
||||
@property (nonatomic) BOOL deleteCacheWhenExported;
|
||||
/// A boolean that enables or disables using envronment light rendering. Default is <code>false</code>.
|
||||
@property (nonatomic) BOOL enableAdjsutEnvironmentLighting;
|
||||
/// Initialize 🌞🍳 <code>RecordAR</code> with an <code>ARSCNView</code> 🚀.
|
||||
- (nullable instancetype)initWithARSceneKit:(ARSCNView * _Nonnull)ARSceneKit OBJC_DESIGNATED_INITIALIZER;
|
||||
/// Initialize 🌞🍳 <code>RecordAR</code> with an <code>ARSKView</code> 👾.
|
||||
- (nullable instancetype)initWithARSpriteKit:(ARSKView * _Nonnull)ARSpriteKit OBJC_DESIGNATED_INITIALIZER;
|
||||
/// Initialize 🌞🍳 <code>RecordAR</code> with an <code>SCNView</code> 🚀.
|
||||
- (nullable instancetype)initWithSceneKit:(SCNView * _Nonnull)SceneKit OBJC_DESIGNATED_INITIALIZER;
|
||||
/// A method that renders a photo 🌄 and returns it as <code>UIImage</code>.
|
||||
- (UIImage * _Nonnull)photo SWIFT_WARN_UNUSED_RESULT;
|
||||
/// A method that renders a <code>PHLivePhoto</code> 🎇 and returns <code>PHLivePhotoPlus</code> in the completion handler.
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 Ahmed Fathi Bekhit - me@ahmedbekhit.com
|
||||
Copyright 2017 Ahmed Fathi Bekhit, www.ahmedbekhit.com, me@ahmedbekhit.com
|
||||
|
||||
ARVideoKit is licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
# ARVideoKit
|
||||

|
||||
|
||||
An iOS Framework that enables developers to capture videos 📹, photos 🌄, Live Photos 🎇, and GIFs 🎆 with ARKit content.
|
||||
|
||||
In other words, you **NO LONGER** have to ~screen record~/~screenshot~ to capture videos 📹 and photos 🌄 of your awesome ARKit apps!
|
||||
@@ -10,19 +11,20 @@ In other words, you **NO LONGER** have to ~screen record~/~screenshot~ to captur
|
||||
| [Preview](#preview) | Displays 2 GIF images captured using the supported [`gif`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-gifforduration-durationtimeinterval-exportbool-_-finished-_-statusbool-_-gifpath-url-_-permissionstatusphauthorizationstatus-_-exportedbool---swiftvoid--nil) method in `ARVideoKit`|
|
||||
| [Key Features](#key-features) | Lists the key features `ARVideoKit` offers |
|
||||
| [Compatibility](#compatibility) | Describes the `ARVideoKit` device and iOS compatibality |
|
||||
| [Example Project](#example-project) | Explains how to run the example project provided in this repository |
|
||||
| [Example Projects](#example-projects) | Explains how to run the example project provided in this repository |
|
||||
| [Installation](#installation) | Describes the [Manual](#manual) option to install `ARVideoKit` |
|
||||
| [Implementation](#implementation) | Lists the [steps needed](#implementation), [notes](#note), and [reference](#youre-all-set-) for more options |
|
||||
| [Implementation](#implementation) | Lists the [steps needed](#implementation) for Objective-C & Swift, [notes](#note), and [reference](#youre-all-set-) for more options |
|
||||
| [Publishing to the App Store](#publishing-to-the-app-store) | Describes the steps **required** before submitting an application using `ARVideoKit` to the App Store. |
|
||||
|[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ahmedfbekhit@gmail.com&item_name=Support+ARVideoKit+Developer&item_number=ARVideoKit+Framework+Donations&amount=0%2e00¤cy_code=USD) | [Donations](#donate) will support me to keep maintaining `ARVideoKit` ❤️|
|
||||
| [Contributions](#contributions) | Describes how you can contribute to this project |
|
||||
| [License](#license) | Describes `ARVideoKit` license |
|
||||
| [AppCoda Tutorial](https://www.appcoda.com/record-arkit-video/) | Check out the detailed tutorial about implementing `ARVideoKit` with SpriteKit ☺️ |
|
||||
| [AppCoda Tutorial](https://www.appcoda.com/record-arkit-video/) | Check out a detailed tutorial about implementing `ARVideoKit` with SpriteKit ☺️ |
|
||||
|
||||
## Preview
|
||||
|👾 [Initialized with SpriteKit](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arspritekitarskview)👇 |🚀 [Initialized with SceneKit](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arscenekitarscnview) 👇 |
|
||||
|👾 [Initialized with SpriteKit](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arspritekitarskview)👇|🚀 [Initialized with SceneKit](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arscenekitarscnview) 👇|
|
||||
|--------------|--------------|
|
||||
|
||||
 
|
||||
|  | |
|
||||
|
||||
## Key Features
|
||||
✅ Capture [Photos](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-photo---uiimage) from [`ARSCNView`](https://developer.apple.com/documentation/arkit/arscnview) and [`ARSKView`](https://developer.apple.com/documentation/arkit/arskview)
|
||||
|
||||
@@ -42,66 +44,21 @@ In other words, you **NO LONGER** have to ~screen record~/~screenshot~ to captur
|
||||
- iOS 11
|
||||
- Swift 3.2 or higher
|
||||
|
||||
## Example Project
|
||||
To try the example project, simply clone this repository and open `ARVideoKit-Example.xcodeproj` project file.
|
||||
## Example Projects
|
||||
To try the example project, simply clone this repository and open the `Examples` folder to choose between the Objective-C and Swift project files.
|
||||
|
||||
It's **recommended** to test `SKViewController` by assigning it as the initial view controller.
|
||||

|
||||
## Installation
|
||||
### Manual
|
||||
Drag the `ARVideoKit.framework` file as an embedded binary of your project targets. `ARVideoKit.framework` can be found in the `/Framework/` folder of this repository.
|
||||
Drag the `ARVideoKit.framework` file as an embedded binary of your project targets. `ARVideoKit.framework` can be found in the `/Framework Build/` folder of this repository.
|
||||

|
||||
|
||||
Or you may drag `ARVideoKit.xcodeproj` into your project and click the **+** button in the embedded binaries section of your project's target.
|
||||

|
||||
## Implementation
|
||||
1. `import ARVideoKit` in the application delegate `AppDelegate.swift` and a `UIViewController` with an `ARKit` scene.
|
||||
|
||||
2. In the application delegate `AppDelegate.swift`, add this 👇 in order to allow the framework access and identify the supported device orientations. **Recommended** if the application supports landscape orientations.
|
||||
```
|
||||
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
return ViewAR.orientation
|
||||
}
|
||||
```
|
||||
|
||||
3. In the selected `UIViewController` class, create an optional type [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) global variable.
|
||||
```
|
||||
var recorder:RecordAR?
|
||||
```
|
||||
|
||||
4. Initialize [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) with [`ARSCNView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arscenekitarscnview) or [`ARSKView`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#init-arspritekitarskview). **Recommended** to initialize in `viewDidLoad()`.
|
||||
|
||||
Initializing RecordAR with `ARSCNView`
|
||||
```
|
||||
recorder = RecordAR(ARSceneKit: sceneView)
|
||||
```
|
||||
Initializing RecordAR with `ARSKView`
|
||||
```
|
||||
recorder = RecordAR(ARSpriteKit: SKSceneView)
|
||||
```
|
||||
|
||||
5. Call the [`prepare()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-prepare_-configurationarconfiguration) method in `viewWillAppear(_ animated: Bool)`
|
||||
```
|
||||
let configuration = ARWorldTrackingConfiguration()
|
||||
recorder?.prepare(configuration)
|
||||
```
|
||||
|
||||
6. Call the [`rest()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-rest) method in `viewWillDisappear(_ animated: Bool)`
|
||||
```
|
||||
recorder?.rest()
|
||||
```
|
||||
|
||||
7. Call the [`record()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-record) method in the proper method to start recording.
|
||||
```
|
||||
@IBAction func startRecording(_ sender: UIButton) {
|
||||
recorder?.record()
|
||||
}
|
||||
```
|
||||
|
||||
8. Call the [`stopAndExport()`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR#func-stopandexport_-finished-_-videopath-url-_-permissionstatusphauthorizationstatus-_-exportedbool---swiftvoid--nil) method in the proper method to stop recording.
|
||||
```
|
||||
@IBAction func stopRecording(_ sender: UIButton) {
|
||||
recorder?.stopAndExport()
|
||||
}
|
||||
```
|
||||
### Swift
|
||||
[Click here to check the Swift implementation steps.](https://github.com/AFathi/ARVideoKit/tree/master/Examples/Swift)
|
||||
### Objective-C
|
||||
[Click here to check the Objective-C implementation steps.](https://github.com/AFathi/ARVideoKit/tree/master/Examples/Objective-C)
|
||||
|
||||
### NOTE
|
||||
Make sure you add the usage description of the `camera`, `microphone`, and `photo library` in the app's `Info.plist`.
|
||||
@@ -123,7 +80,7 @@ Check [`RecordAR`](https://github.com/AFathi/ARVideoKit/wiki/RecordAR) documenta
|
||||
## Publishing to the App Store
|
||||
Before publishing to the App Store make sure to add the [ARVideoKit License](#license) to your app licences list.
|
||||
|
||||
Additionally, you MUST **strip out the simulator architectures** from the framework before pushing an application to the App Store.
|
||||
Additionally, if you are using the binary build from `Framework Build` or the latest release, you MUST **strip out the simulator architectures** from the framework before pushing an application to the App Store.
|
||||
|
||||
To do so, follow those steps:
|
||||
|
||||
@@ -151,6 +108,11 @@ Donations will support me to keep maintining **ARVideoKit Framework** ❤️
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ahmedfbekhit@gmail.com&item_name=Support+ARVideoKit+Developer&item_number=ARVideoKit+Framework+Donations&amount=0%2e00¤cy_code=USD)
|
||||
|
||||
## Contributions
|
||||
If you have an idea for a new **ARVideoKit** feature/functionality and want to add it to this repository, feel free to fork the project and create a pull request!
|
||||
|
||||
Also, feel free to create an issue if you have any suggestions or need any help ☺️
|
||||
|
||||
## [License](LICENSE)
|
||||
Copyright 2017 Ahmed Fathi Bekhit, www.ahmedbekhit.com, me@ahmedbekhit.com
|
||||
|
||||
|
||||
Reference in New Issue
Block a user