Post

Replies

Boosts

Views

Activity

Crash When Exporting Video with Text Overlay
I am putting together a simple video editor app for iOS. The videos are exported with a "watermark" in the form of a text overlay (e.g. "This video was made with XYZ").The app (still a prototype) was working until around February this year. Then I got busy, moved to other projects and stopped working on it for a while.About a months ago, I resumed work on the app but suddenly noticed that it was crashing whenever I attempted to export any video.The crash looks like this:libxpc.dylib`_xpc_api_misuse: 0x7fff51c53154 <+0>: pushq %rbp 0x7fff51c53155 <+1>: movq %rsp, %rbp 0x7fff51c53158 <+4>: pushq %rbx 0x7fff51c53159 <+5>: subq $0xa8, %rsp 0x7fff51c53160 <+12>: movq %rdi, %r9 0x7fff51c53163 <+15>: movaps 0xdba6(%rip), %xmm0 ; __xpcVersionNumber + 160 0x7fff51c5316a <+22>: leaq -0xb0(%rbp), %rbx 0x7fff51c53171 <+29>: movaps %xmm0, 0x90(%rbx) 0x7fff51c53178 <+36>: movaps %xmm0, 0x80(%rbx) 0x7fff51c5317f <+43>: movaps %xmm0, 0x70(%rbx) 0x7fff51c53183 <+47>: movaps %xmm0, 0x60(%rbx) 0x7fff51c53187 <+51>: movaps %xmm0, 0x50(%rbx) 0x7fff51c5318b <+55>: movaps %xmm0, 0x40(%rbx) 0x7fff51c5318f <+59>: movaps %xmm0, 0x30(%rbx) 0x7fff51c53193 <+63>: movaps %xmm0, 0x20(%rbx) 0x7fff51c53197 <+67>: movaps %xmm0, 0x10(%rbx) 0x7fff51c5319b <+71>: movaps %xmm0, (%rbx) 0x7fff51c5319e <+74>: leaq 0x1150d(%rip), %r8 ; "XPC API Misuse: %s" 0x7fff51c531a5 <+81>: movl $0xa0, %esi 0x7fff51c531aa <+86>: movl $0xa0, %ecx 0x7fff51c531af <+91>: movq %rbx, %rdi 0x7fff51c531b2 <+94>: movl $0x0, %edx 0x7fff51c531b7 <+99>: xorl %eax, %eax 0x7fff51c531b9 <+101>: callq 0x7fff51c5fe18 ; symbol stub for: __snprintf_chk 0x7fff51c531be <+106>: movq %rbx, 0x380787c3(%rip) ; gCRAnnotations + 8 0x7fff51c531c5 <+113>: leaq 0x114f9(%rip), %rax ; "API Misuse" 0x7fff51c531cc <+120>: movq %rax, 0x380787bd(%rip) ; gCRAnnotations + 16 -> 0x7fff51c531d3 <+127>: ud2 < Thread 55: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)After experimenting a bit by eliminating features, I found out that the app crashes only if the exported video compositions contain the text overlay: if I comment out the code responsible for overlaying the text layer, the issue resolves.This is the code I am using to export the video composition:func export(completion: @escaping (() -> Void), failure: @escaping ((Error) -> Void)) { let exportQuality = AVAssetExportPresetHighestQuality guard let exporter = AVAssetExportSession(asset: composition, presetName: exportQuality) else { return failure(ProjectError.failedToCreateExportSession) } guard let documents = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else { return failure(ProjectError.temporaryOutputDirectoryNotFound) } let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd_HHmmss" let fileName = dateFormatter.string(from: Date()) let fileExtension = "mov" let fileURL = documents.appendingPathComponent(fileName).appendingPathExtension(fileExtension) exporter.outputURL = fileURL exporter.outputFileType = AVFileType.mov exporter.shouldOptimizeForNetworkUse = true if shouldAddWatermark { // Watermark overlay: let frame = CGRect(origin: .zero, size: videoComposition.renderSize) let watermark = WatermarkLayer(frame: frame) let parentLayer = CALayer() let videoLayer = CALayer() parentLayer.frame = frame videoLayer.frame = frame parentLayer.addSublayer(videoLayer) parentLayer.addSublayer(watermark) videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) } exporter.videoComposition = videoComposition exporter.exportAsynchronously { if exporter.status == .completed { /* Composition was successfully saved to the documents folder. Now create a new asset in the device's camera roll (i.e. photo library): */ AssetLibrary.saveVideo(at: fileURL, completion: { completion() }, failure: {(error) in failure(ProjectError.failedToExportToPhotoLibrary(detail: error?.localizedDescription ?? "Unknown")) }) } else { DispatchQueue.main.async { failure(ProjectError.failedToExportComposition(detail: exporter.error?.localizedDescription ?? "Unknown")) } } } }The WatermarkLayer class used above is defined as follows:class WatermarkLayer: CATextLayer { // MARK: - Constants private let defaultFontSize: CGFloat = 48 private let rightMargin: CGFloat = 10 private let bottomMargin: CGFloat = 10 // MARK: - Initialization init(frame: CGRect) { super.init() guard let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String else { fatalError("!!!") } self.foregroundColor = CGColor.srgb(r: 255, g: 255, b: 255, a: 0.5) self.backgroundColor = CGColor.clear self.string = String(format: String.watermarkFormat, appName) self.font = CTFontCreateWithName(String.watermarkFontName as CFString, defaultFontSize, nil) self.fontSize = defaultFontSize self.shadowOpacity = 0.75 self.alignmentMode = .right self.frame = frame } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented. Use init(frame:) instead.") } // MARK: - CALayer override func draw(in ctx: CGContext) { let height = self.bounds.size.height let fontSize = self.fontSize //let yDiff = (height-fontSize)/2 - fontSize/10 // Center let yDiff = (height-fontSize) - fontSize/10 - bottomMargin // Bottom (minus margin) ctx.saveGState() ctx.translateBy(x: -rightMargin, y: yDiff) super.draw(in: ctx) ctx.restoreGState() } }What's going on? Which API is being "misused"?
11
3
5k
May ’20
SK3DNode Always Above All Other SKNode Content
I have successfully incorporated some basic 3D content into my SpriteKit-based app.Next, I want to display some sprites overlaid on top of the 3D content, but can't manage to do so.Manipulating the .zPosition porperty of the SK3DNode and SKSpriteNode involded doesn't seem to do it.This is my code for both the Spritekit scene, and the SceneKit scene whose content is displayed within the SK3DNode:SpriteKit-side:import SpriteKit class SpriteKitScene: SKScene { override init(size: CGSize) { super.init(size: size) // Scene Background self.backgroundColor = .red // 3D Node let objectNode = SK3DNode(viewportSize: size) objectNode.scnScene = SceneKitScene() addChild(objectNode) objectNode.position = CGPoint(x: size.width/2, y: size.height/2) let camera = SCNCamera() let cameraNode = SCNNode() cameraNode.camera = camera objectNode.pointOfView = cameraNode objectNode.pointOfView?.position = SCNVector3(x: 0, y: 0, z: 60) objectNode.zPosition = -100 // 2D Sprite let sprite = SKSpriteNode(color: .yellow, size: CGSize(width: 250, height: 60)) sprite.position = objectNode.position sprite.zPosition = +100 addChild(sprite) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }SceneKit-side:import SceneKit class SceneKitScene: SCNScene { override init() { super.init() let box = SCNBox(width: 10, height: 10, length: 10, chamferRadius: 0) let material = SCNMaterial() material.diffuse.contents = UIColor.green box.materials = [material] let boxNode = SCNNode(geometry: box) boxNode.transform = SCNMatrix4MakeRotation(.pi/2, 1, 1, 1) self.rootNode.addChildNode(boxNode) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }The sprites seem to be rendered at exatly the "far plane" of the SK3DNode's camera; if I push my geometry back to the far plane, it gets clipped ewxactly where it "intersects" the srpite.
1
0
884
May ’20