Had*_*ier 6 ios sprite-kit swift arkit
我正在玩ARKit,我想从ARSKView帧创建一个视频.我尝试使用ReplayKit,但行为不是我所期望的: - 我不想记录整个屏幕. - 我不希望提示用户我们正在录制屏幕.
另外,我如何结合微输入和视频?我想在ARSKView中没有流式传输音频?这是代码(来自Apple示例):
import UIKit
import SpriteKit
import ARKit
class ViewController: UIViewController, ARSKViewDelegate {
@IBOutlet var sceneView: ARSKView!
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and node count
sceneView.showsFPS = true
sceneView.showsNodeCount = true
// Load the SKScene from 'Scene.sks'
if let scene = SKScene(fileNamed: "Scene") {
sceneView.presentScene(scene)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
// MARK: - ARSKViewDelegate
func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? {
// Create and configure a node for the anchor added to the view's session.
let labelNode = SKLabelNode(text: "")
labelNode.horizontalAlignmentMode = .center
labelNode.verticalAlignmentMode = .center
return labelNode;
}
func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user
}
func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay
}
func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required
}}
Run Code Online (Sandbox Code Playgroud)
如果有必要,可以使用Scene类:
import SpriteKit
import ARKit
class Scene: SKScene {
override func didMove(to view: SKView) {
// Setup your scene here
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let sceneView = self.view as? ARSKView else {
return
}
// Create anchor using the camera's current position
if let currentFrame = sceneView.session.currentFrame {
// Create a transform with a translation of 0.2 meters in front of the camera
var translation = matrix_identity_float4x4
translation.columns.3.z = -0.2
let transform = simd_mul(currentFrame.camera.transform, translation)
// Add a new anchor to the session
let anchor = ARAnchor(transform: transform)
sceneView.session.add(anchor: anchor)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要只记录帧(如AVCaptureSession,而不是"真实的" 3D场景SCNNodes),只是让他们为ARFrame.capturedImage中updateAtTime的委托功能SCNSceneRenderer:
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
createMovieWriterOnce(frame: session.currentFrame)
appendFrameWithMetadaToMovie(frame: session.currentFrame)
}
Run Code Online (Sandbox Code Playgroud)
我还没有找到一种方法来获取帧大小ARSession,所以MovieWriter等待第一帧设置大小:
func createMovieWriterOnce(frame: ARFrame?) {
if(frame == nil) { return }
DispatchQueue.once(token: "SimplestMovieWriter.constructor") {
movieWriter = SimplestMovieWriter(frameWidth: CVPixelBufferGetWidth(frame!.capturedImage), frameHeight: CVPixelBufferGetHeight(frame!.capturedImage))
}
}
Run Code Online (Sandbox Code Playgroud)
接下来每一个都CVPixelBuffer被送到MovieWriter:
func appendFrameWithMetadaToMovie(frame: ARFrame?) {
if(!isVideoRecording || frame == nil) { return }
let interestingPoints = frame?.rawFeaturePoints?.points
movieWriter.appendBuffer(buffer: (frame?.capturedImage)!, withMetadata: interestingPoints)
}
Run Code Online (Sandbox Code Playgroud)
MovieWriter是自定义类AVAssetWriter,AVAssetWriterInput和AVAssetWriterInputPixelBufferAdaptor.
您可以在没有音频的情况下保存视频,然后使用AVAssetExportSession添加任何内容(音频,字幕,元数据):
let composition = AVMutableComposition()
...
let trackVideo = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let videoFileAsset = AVURLAsset(url: currentURL!, options: nil)
let videoFileAssetTrack = videoFileAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
// add audio track here
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1216 次 |
| 最近记录: |