我希望将我的iPhone相机视图设置为我的Sprite Kit游戏中的背景图像。怎么去那样做?非常感谢帮助!
答案 0 :(得分:0)
import UIKit
import AVFoundation
import AssetsLibrary
class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {
var SessionRunningAndDeviceAuthorizedContext = "SessionRunningAndDeviceAuthorizedContext"
@available(iOS 4.0, *)
public func fileOutput(_ captureOutput: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
}
// MARK: property
var sessionQueue: DispatchQueue!
var session: AVCaptureSession?
var videoDeviceInput: AVCaptureDeviceInput?
var deviceAuthorized: Bool = false
var backgroundRecordId: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
var sessionRunningAndDeviceAuthorized: Bool {
get {
return (self.session?.isRunning != nil && self.deviceAuthorized )
}
}
var runtimeErrorHandlingObserver: AnyObject?
var lockInterfaceRotation: Bool = false
@IBOutlet weak var previewView: AVCamPreviewView!
override func viewDidLoad() {
super.viewDidLoad()
let session: AVCaptureSession = AVCaptureSession()
session.sessionPreset = AVCaptureSession.Preset.photo
self.session = session
self.previewView.session = session
self.checkDeviceAuthorizationStatus()
let sessionQueue: DispatchQueue = DispatchQueue(label: "KehoeGames.whatever",attributes: [])
self.sessionQueue = sessionQueue
sessionQueue.async {
self.backgroundRecordId = UIBackgroundTaskInvalid
let videoDevice: AVCaptureDevice! = ViewController.deviceWithMediaType(AVMediaType.video.rawValue, preferringPosition: AVCaptureDevice.Position.back)
var error: NSError? = nil
var videoDeviceInput: AVCaptureDeviceInput?
do {
videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)
} catch let error1 as NSError {
error = error1
videoDeviceInput = nil
} catch {
fatalError()
}
if (error != nil) {
print(error)
let alert = UIAlertController(title: "Error", message: error!.localizedDescription
, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
if session.canAddInput(videoDeviceInput!){
session.addInput(videoDeviceInput!)
self.videoDeviceInput = videoDeviceInput
DispatchQueue.main.async {
let orientation: AVCaptureVideoOrientation = AVCaptureVideoOrientation(rawValue: UIDevice.current.orientation.rawValue)!
(self.previewView.layer as! AVCaptureVideoPreviewLayer).connection?.videoOrientation = .portrait
(self.previewView.layer as! AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravity.resizeAspectFill
}
}
}
}
}
override func viewWillAppear(_ animated: Bool) {
self.sessionQueue.async {
self.addObserver(self, forKeyPath: "sessionRunningAndDeviceAuthorized", options: [.old , .new] , context: &SessionRunningAndDeviceAuthorizedContext)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.subjectAreaDidChange(_:)), name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange, object: self.videoDeviceInput?.device)
self.runtimeErrorHandlingObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVCaptureSessionRuntimeError, object: self.session, queue: nil) {
(note: Notification?) in
self.sessionQueue.async { [unowned self] in
if let sess = self.session {
sess.startRunning()
}
}
}
self.session?.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
self.sessionQueue.async {
if let sess = self.session {
sess.stopRunning()
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange, object: self.videoDeviceInput?.device)
NotificationCenter.default.removeObserver(self.runtimeErrorHandlingObserver!)
self.removeObserver(self, forKeyPath: "sessionRunningAndDeviceAuthorized", context: &SessionRunningAndDeviceAuthorizedContext)
}
}
}
override var shouldAutorotate : Bool {
return !self.lockInterfaceRotation
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
return super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
@objc func subjectAreaDidChange(_ notification: Notification){
let devicePoint: CGPoint = CGPoint(x: 0.5, y: 0.5)
self.focusWithMode(AVCaptureDevice.FocusMode.continuousAutoFocus, exposureMode: AVCaptureDevice.ExposureMode.continuousAutoExposure, point: devicePoint, monitorSubjectAreaChange: false)
}
class func deviceWithMediaType(_ mediaType: String, preferringPosition:AVCaptureDevice.Position) -> AVCaptureDevice? {
var devices = AVCaptureDevice.devices(for: AVMediaType(rawValue: mediaType));
if (devices.isEmpty) {
print("This device has no camera. Probably the simulator.")
return nil
} else {
var captureDevice: AVCaptureDevice = devices[0]
for device in devices {
if (device as AnyObject).position == preferringPosition {
captureDevice = device
break
}
}
return captureDevice
}
}
func checkDeviceAuthorizationStatus(){
let mediaType:String = AVMediaType.video.rawValue;
AVCaptureDevice.requestAccess(for: AVMediaType(rawValue: mediaType)) { (granted: Bool) in
if granted {
self.deviceAuthorized = true;
} else {
DispatchQueue.main.async {
let alert: UIAlertController = UIAlertController(
title: "AVCam",
message: "AVCam does not have permission to access camera",
preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "OK", style: .default) { _ in }
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
self.deviceAuthorized = false;
}
}
}
创建一个名为AVCamPreviewView的新类
import Foundation
import UIKit
import AVFoundation
class AVCamPreviewView: UIView {
var session: AVCaptureSession? {
get {
return (self.layer as! AVCaptureVideoPreviewLayer).session
}
set (session) {
(self.layer as! AVCaptureVideoPreviewLayer).session = session
}
}
override class var layerClass : AnyClass {
return AVCaptureVideoPreviewLayer.self
}
}
您应该可以在场景背面预览视图,然后将游戏置于其上。