Post not yet marked as solved
So, I've never faced a problem like this for so long. I have basically scrutinized every possible website on the internet looking for a solution but have found nothing so far.I have a custom picker controller in which I can select videos and play them. Beforehand, I was struggling to play slow motion videos (only no-slow-motion videos were playing) but after searching I found the solution here.http://stackoverflow.com/questions/26152396/how-to-access-nsdata-nsurl-of-slow-motion-videos-using-photokitSo, my code to get videos became this:let videoOptions = PHVideoRequestOptions()
videoOptions.version = PHVideoRequestOptionsVersion.Original
PHImageManager.defaultManager().requestAVAssetForVideo(asset!, options: videoOptions , resultHandler: { (asset, audioMix, info) -> Void in
if let asset = asset as? AVURLAsset {
let videoData = NSData(contentsOfURL: asset.URL)
let videoPath = NSTemporaryDirectory() + "tmpMovie.MOV"
let videoURL = NSURL(fileURLWithPath: videoPath)
let writeResult = videoData?.writeToURL(videoURL, atomically: true)
if let writeResult = writeResult where writeResult {
print("success")
let videoVC = VideoViewController(videoUrl: videoURL)
imagePicker.presentViewController(videoVC, animated: false, completion: nil)
}
else {
print("failure")
}
}
}) Now, slow motion videos are playing but in a normal way instead of in a slow-motion way. This questions relates to the problem.https://devforums.apple.com/message/903937#903937I've seen a lot of comments saying they solved the problem by using Photos framework, but I have no idea how to achieve this and they didn't explain either. It might be something to do PHAssetMediaSubtypeVideoHighFrameRate. So, how would be possible to play slow motion videos? Do I need to change the fps somehow?Please help, I am quite desperate :/ Objective-C code is welcome as well.
I'm trying to do some realtime audio processing on audio served from an HLS stream (i.e. an AVPlayer created using an M3U HTTP URL). It doesn't seem like attaching an AVAudioMix configured with with an `audioTapProcessor` has any effect; none of the callbacks except `init` are being invoked. Is this a known limitation? If so, is this documented somewhere?If the above is a limitation, what are my options using some of the other audio APIs? I looked into `AVAudioEngine` as well but it doesn't seem like there's any way I can configure any of the input node types to use an HLS stream. Am I wrong? Are there lower level APIs available to play HLS streams that provide the necessary hooks?Alternatively, is there some generic way to tap into all audio being output by my app regardless of its source?Thanks a lot!
Post not yet marked as solved
HiIs it possible to scan multiple 1D barcodes using the Apple APIs provided? I can only seem to scan multiple QR codes but when I try 1 D barcodes I only ever get one result, the code is as follows- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
CGRect highlightViewRect = CGRectZero;
AVMetadataMachineReadableCodeObject *barCodeObject;
NSString *detectionString = nil;
NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
for (AVMetadataObject *metadata in metadataObjects) {
for (NSString *type in barCodeTypes) {
if ([metadata.type isEqualToString:type])
{
barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
highlightViewRect = barCodeObject.bounds;
detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
break;
}
}
if (detectionString != nil)
{
_label.text = detectionString;
break;
}
else
_label.text = @"(none)";
}
_highlightView.frame = highlightViewRect;
}
Post not yet marked as solved
I am currently working with AVAssetWriterInput with interlaced source.I want to know the proper procedure to preserve 'fiel' format description extension through AVAssetWriterInput compression operation.Do you anyone have an answer on this?>>Technical Note TN2162>>Uncompressed Y´CbCr Video in QuickTime Files>>The 'fiel' ImageDescription Extension: Field/Frame Information//What I have tried is following:First decode into sample buffer with Field/Frame information- Decode DV-NTSC source and get current FieldCount/Detail of source data- Create a kCVPixelFormatType_422YpCbCr8 CVImageBuffer from source- CMSetAttachments() kCVImageBufferFieldCountKey/kCVImageBufferFieldDetailKey with FieldCount=2/FieldDetail=14 to imageBuffer, same as DV-NTSC source- CMVideoFormatDescriptionCreateForImageBuffer()- CMSampleBufferCreateForImageBuffer()- Now decompressed samplebuffer has kCMFormatDescriptionExtension_FieldXXX same as sourceSecond encode using ProRes422- Next I create AVAssetWriterInput to transcode from _422YpCbCr8 into AVVideoCodecAppleProRes422- Now AVAssetWriter can produce ProRes422 mov file, but it does not contain the format description extension 'fiel'.- ProRes422 Encoder does preserve 'colr', 'pasp', 'clap' same as source, but no 'fiel' is there.I have also tried to serve format description with kCMFormatDescriptionExtension_FieldXXX with initWithMediaType:outputSettings:sourceFormatHint:but no success.//
Post not yet marked as solved
Currently, I'm recording audio on the Apple Watch using the presentAudioRecorderController and sending it to the corresponding iPhone app.The audio format by default seems to be recorded on the Apple Watch using two channels and there doesn't seem to be a way to change that.For various reasons, I need the audio format to be only one channel. I was hoping there would be something on iOS to convert the audio file from stereo (two channels) to mono (one channel)Right now, I'm investigating if this is possible using AVAudioEngine and other various related classes. I'm not sure if it's possible and it seems very complicated at the moment.
Post not yet marked as solved
Hi,I'm having two problems using the scheduleBuffer function of AVAudioPlayerNode.Background: my app generates audio programatically, which is why I am using this function. I also need low latency. Therefore, I'm using a strategy of scheduling a small number of buffers, and using the completion handler to keep the process moving forward by scheduling one more buffer for each one that completes.I'm seeing two problems with this approach:One, the total memory consumed by my app grows steadily while the audio is playing, which suggests that the audio buffers are never being deallocated or some other runaway process is underway. (The Leaks tool doesn't detect any leaks, however).Two, audio playback sometimes stops, particularly on slower devices. By "stops", what I mean is that at some point I schedule a buffer and the completion block for that buffer is never called. When this happens, I can't even clear the problem by stopping the player.Now, regarding the first issue, I suspected that if my completion block recursively scheduled another buffer with another completion block, I would probably end up blowing out the stack with an infinite recursion. To get around this, instead of directly scheduling the buffer in the completion block, I set it up to enqueue the schedule in a dispatch queue. However, this doesn't seem to solve the problem.Any advice would be appreciated. Thanks.
Post not yet marked as solved
I am working on AVPlayer based streaming apps wherein I am relying on ID3 tags for fetching metadata from the HLS stream. I am using KVO for this and observing AVPlayerItem’s timedMetadata property. This works perfectly well in normal scenario. However when I route the playback to Apple TV via Airplay, I do not get any notifications for the said KVO. In fact, the timedMetadata property resets to nil once the Airplay is activated as the API docs says here,“As an optimization for playback, AVPlayerItem may omit the processing of timed metadata when no observer of this property is registered. Therefore, when no such observer is registered, the value of the timedMetadata property may remain nil regardless of the contents of the underlying media.”Is there any way, we can fetch timedMetadata property of AVPlayerItem while the steam is being played via Airplay mode.
In this URL there is the following blerb:https://www.apple.com/in/ipados/ipados-preview/features/Image Capture APIThe Image Capture API allows developers to leverage the Camera Connection Kit to import photos directly into their apps.I haven't been able to find in the docs or WWDC sessions where it talks about this. I have an app for our action camera and would love to be able to directly read the camera's filesystem over USB. I see where you can use a a document picker to access a USB filesystem, but that requires the user to properly find/select the correct directory in the camera's file system. I am hoping to be able to detect it and access it without the error prone user selection.
Post not yet marked as solved
I'm using AVAssetReaders with AVSampleBufferDisplayLayers to display multiple videos at once. I'm seeing this issue on iOS 13.1.3, 13.2b2, on various hardware like iPad 10.5 and iPad 12.9.It works well for a while, then a random call to copyNextSampleBuffer never returns, blocking that thread indefinitely and eating up resources.I have tried different threading approaches with no avail:If copyNextSampleBuffer() and reader.cancelReading() are done on the same queue, then copyNextSampleBuffer() gets stuck and the cancelReading() never gets processed because the queue is blocked. If I manually (with the debugger) jump in on that blocked queue and execute cancelReading(), immediately an EXC_BREAKPOINT crashes the appIf copyNextSampleBuffer() and reader.cancelReading() are done on different queues, then copyNextSampleBuffer() crashes with EXC_BAD_ACCESSHere's the stacktrace (same queue approach). I don't understand why it's stuck, my expectation is that copyNextSampleBuffer should always return (ie. with nil in error case).VideoPlayerView: UIView with AVSampleBufferDisplayLayerAVAssetFactory: Singleton with the queue that creates & manages all AVAssetReader / AVAsset* objects* thread #22, queue = 'AVAssetFactory'
frame #0: 0x00000001852355f4 libsystem_kernel.dylib`mach_msg_trap + 8
frame #1: 0x0000000185234a60 libsystem_kernel.dylib`mach_msg + 72
frame #2: 0x00000001853dc068 CoreFoundation`__CFRunLoopServiceMachPort + 216
frame #3: 0x00000001853d7188 CoreFoundation`__CFRunLoopRun + 1444
frame #4: 0x00000001853d68bc CoreFoundation`CFRunLoopRunSpecific + 464
frame #5: 0x000000018f42b6ac AVFoundation`-[AVRunLoopCondition _waitInMode:untilDate:] + 400
frame #6: 0x000000018f38f1dc AVFoundation`-[AVAssetReaderOutput copyNextSampleBuffer] + 148
frame #7: 0x000000018f3900f0 AVFoundation`-[AVAssetReaderTrackOutput copyNextSampleBuffer] + 72
* frame #8: 0x0000000103309d98 Photobooth`closure #1 in AVAssetFactory.nextSampleBuffer(reader=0x00000002814016f0, retval=(Swift.Optional<CoreMedia.CMSampleBuffer>, Swift.Optional<AVFoundation.AVAssetReader.Status>) @ 0x000000016dbd1cb8) at AVAssetFactory.swift:108:34
frame #9: 0x0000000102f4f480 Photobooth`thunk for @callee_guaranteed () -> () at <compiler-generated>:0
frame #10: 0x0000000102f4f4a4 Photobooth`thunk for @escaping @callee_guaranteed () -> () at <compiler-generated>:0
frame #11: 0x000000010bfe6c04 libdispatch.dylib`_dispatch_client_callout + 16
frame #12: 0x000000010bff5888 libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 124
frame #13: 0x0000000103309a5c Photobooth`AVAssetFactory.nextSampleBuffer(reader=0x00000002814016f0, self=0x0000000281984f60) at AVAssetFactory.swift:101:20
frame #14: 0x00000001032ab690 Photobooth`closure #1 in VideoPlayerView.setRequestMediaLoop(self=0x000000014b8da1d0, handledCompletion=false) at VideoPlayerView.swift:254:70
frame #15: 0x0000000102dce978 Photobooth`thunk for @escaping @callee_guaranteed () -> () at <compiler-generated>:0
frame #16: 0x000000018f416848 AVFoundation`-[AVMediaDataRequester _requestMediaDataIfReady] + 80
frame #17: 0x000000010bfe5828 libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #18: 0x000000010bfe6c04 libdispatch.dylib`_dispatch_client_callout + 16
frame #19: 0x000000010bfedb74 libdispatch.dylib`_dispatch_lane_serial_drain + 744
frame #20: 0x000000010bfee744 libdispatch.dylib`_dispatch_lane_invoke + 500
frame #21: 0x000000010bff9ae4 libdispatch.dylib`_dispatch_workloop_worker_thread + 1324
frame #22: 0x000000018517bfa4 libsystem_pthread.dylib`_pthread_wqthread + 276I've tried all kinds of other things like making sure the AVAssets and all objects are made on one queue, and stopping the AVAssetReaders from ever deallocing to see if that helps. Nothing works. Any ideas?
Post not yet marked as solved
I'm having an issue with playing sequences of different kinds of items in a background.In an app I'm working on we've introduced playlists which contain both content provided by the app and Apple Music content.For that use AVPlayer and MPMusicPlayerController respectively. We observe one player or the other (depending what content is now playing) and if the other kind of content comes next, we release the old player (if we can - MPMusicPlayerController is a singleton, so best we can do is stop it) and load item to another player.The problem starts when the app leaves foreground. Once MPMusicPlayerController takes over it doesn't want to give up control, so if any AVPlayer content comes after MPMusicPlayerController content, the music stops.One workaround that I've tried is playing with `.mixWithOthers` options when I set the category on AVAudioSession, however this creates new category of problems - I'm loosing lockscreen controls, therefore I'm also loosing airplay. One dirty trick that I've tried was setting `.mixWithOthers` 3 seconds before MPMediaItem ends, and then disabling it back once AVPlayer starts. Beside the fact that there're probably many different things that can go wrong here, MPMediaPlayerController still doesn't want to give me back the control over lockscreen controls.Is there any way this could ever work on iOS 13?
Post not yet marked as solved
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"?
Post not yet marked as solved
I'm trying to make an app that plays audio when push is received, even while the ringer is silent.I have the audio background mode enabled and the app works (usually) fine, but sometimes i get a mysterious 561015905 error.The error isAVAudioSession.ErrorCode.cannotStartPlayingAnd docs indicate:This error type can occur if the app’s Information property list doesn’t permit audio use.
It can also occur if the app is in the background and using a category that doesn’t allow background audio.https://developer.apple.com/documentation/avfoundation/avaudiosession/errorcode/cannotstartplayingHowever, the audio mode is definitely enabled and the category is always playback that should allow background playing.(this works 95-99% of times)So, with intesnse testing i have found that once every 20-100 incoming pushes i get this error:Error: Error Domain=NSOSStatusErrorDomain Code=561015905 "(null)"Why?
Post not yet marked as solved
I am using the microphone, and found a lot of issues that crashes the app when the input source did change. The error was always something like:
** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: format.sampleRate == hwFormat.sampleRate.
Now I have fixed this issue, forcing the input-source to be always the builtin microphone and using AVAudioFoundation entities at different moments. But I am still not confident about this solution. For example, I still having some inconsistencies while transmitting the device screen on macOS through QuickTime. So my question around this:
How to prevent app-crashes with this kind of error?
I saw a lot of similar errors just changing the property of the format. How can I avoid these kinds of errors? There is a Swift-way to handle the error instead of using an exception catcher from Objective-c?
Post not yet marked as solved
Hi, I'm working on an app where a user can scroll through a feed of short videos (a bit like TikTok). I do some pre-fetching of videos a couple positions ahead of the user's scroll position, so the video can start playing as soon as he or she scrolls to the video.
Currently, I just pre-fetch by initializing a few AVPlayers. However, I'd like to add a better caching system.
I'm looking for the best way to: get videos to start playing as possible, while
making sure to minimize re-downloading of videos if a user scrolls away from a video and back to it.
Is there a way that I can cache the contents of an AVPlayer that has loaded an HLS video?
Alternatively, I've explored using AVAssetDownloadTask to download the HLS videos. My issue is that I can't download the full video and then play it - I need to start playing the video as soon as the user scrolls to it, even if it's not done downloading.
Is there a way to start an HLS download with an AVAssetDownloadTask, and then start playing the video while it continues downloading?
Thank you!
Post not yet marked as solved
We are creating a watch party app that allows you to video chat with your friends and play a YouTube video at the same time. The video is played using Google's youtube-ios-player-helperlibrary which uses a WKWebView with their iframe API, as that's the only way to play it without violating the Terms of Service. We need the ability to change the volume of the YouTube video separately from the video chat, so you can hear your friends over the video for example.
Unfortunately it's not possible to directly change the volume because iOS does not support changing the volume via JavaScript - https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW10, unlike macOS. Setting volume doesn't do anything and getting it always returns 1. Users can change the volume with the hardware buttons but this applies to all audio including the video chat, not just the YouTube video.
Someone found a workaround - https://stackoverflow.com/a/37315071/1795356 to get the underlying AVPlayer and change its volume natively. This worked with UIWebView but does not work now that it uses WKWebView.
What can be done to change the volume of the YouTube video?
Post not yet marked as solved
Summary:
I am using the Vision framework, in conjunction with AVFoundation, to detect facial landmarks of each face in the camera feed (by way of the VNDetectFaceLandmarksRequest). From here, I am taking the found observations and unprojecting each point to a SceneKit View (SCNView), then using those points as the vertices to draw a custom geometry that is textured with a material over each found face.
Effectively, I am working to recreate how an ARFaceTrackingConfiguration functions. In general, this task is functioning as expected, but only when my device is using the front camera in landscape right orientation. When I rotate my device, or switch to the rear camera, the unprojected points do not properly align with the found face as they do in landscape right/front camera.
Problem:
When testing this code, the mesh appears properly (that is, appears affixed to a user's face), but again, only when using the front camera in landscape right. While the code runs as expected (that is, generating the face mesh for each found face) in all orientations, the mesh is wildly misaligned in all other cases.
My belief is this issue either stems from my converting the face's bounding box (using VNImageRectForNormalizedRect, which I am calculating using the width/height of my SCNView, not my pixel buffer, which is typically much larger), though all modifications I have tried result in the same issue.
Outside of that, I also believe this could be an issue with my SCNCamera, as I am a bit unsure how the transform/projection matrix works and whether that would be needed here.
Sample of Vision Request Setup:
// Setup Vision request options
var requestHandlerOptions: [VNImageOption: AnyObject] = [:]
// Setup Camera Intrinsics
let cameraIntrinsicData = CMGetAttachment(sampleBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil)
if cameraIntrinsicData != nil {
requestHandlerOptions[VNImageOption.cameraIntrinsics] = cameraIntrinsicData
}
// Set EXIF orientation
let exifOrientation = self.exifOrientationForCurrentDeviceOrientation()
// Setup vision request handler
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer,
orientation: exifOrientation,
options: requestHandlerOptions)
// Setup the completion handler
let completion: VNRequestCompletionHandler = {request, error in
let observations = request.results as! [VNFaceObservation]
// Draw faces
DispatchQueue.main.async {
drawFaceGeometry(observations: observations)
}
}
// Setup the image request
let request = VNDetectFaceLandmarksRequest(completionHandler: completion)
// Handle the request
do {
try handler.perform([request])
} catch {
print(error)
}
Sample of SCNView Setup:
// Setup SCNView
let scnView = SCNView()
scnView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(scnView)
scnView.showsStatistics = true
NSLayoutConstraint.activate([
scnView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
scnView.topAnchor.constraint(equalTo: self.view.topAnchor),
scnView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
scnView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
])
// Setup scene
let scene = SCNScene()
scnView.scene = scene
// Setup camera
let cameraNode = SCNNode()
let camera = SCNCamera()
cameraNode.camera = camera
scnView.scene?.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 0, z: 16)
// Setup light
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light?.type = SCNLight.LightType.ambient
ambientLightNode.light?.color = UIColor.darkGray
scnView.scene?.rootNode.addChildNode(ambientLightNode)
Sample of "face processing"
func drawFaceGeometry(observations: [VNFaceObservation]) {
// An array of face nodes, one SCNNode for each detected face
var faceNode = [SCNNode]()
// The origin point
let projectedOrigin = sceneView.projectPoint(SCNVector3Zero)
// Iterate through each found face
for observation in observations {
// Setup a SCNNode for the face
let face = SCNNode()
// Setup the found bounds
let faceBounds = VNImageRectForNormalizedRect(observation.boundingBox, Int(self.scnView.bounds.width), Int(self.scnView.bounds.height))
// Verify we have landmarks
if let landmarks = observation.landmarks {
// Landmarks are relative to and normalized within face bounds
let affineTransform = CGAffineTransform(translationX: faceBounds.origin.x, y: faceBounds.origin.y)
.scaledBy(x: faceBounds.size.width, y: faceBounds.size.height)
// Add all points as vertices
var vertices = [SCNVector3]()
// Verify we have points
if let allPoints = landmarks.allPoints {
// Iterate through each point
for (index, point) in allPoints.normalizedPoints.enumerated() {
// Apply the transform to convert each point to the face's bounding box range
_ = index
let normalizedPoint = point.applying(affineTransform)
let projected = SCNVector3(normalizedPoint.x, normalizedPoint.y, CGFloat(projectedOrigin.z))
let unprojected = sceneView.unprojectPoint(projected)
vertices.append(unprojected)
}
}
// Setup Indices
var indices = [UInt16]()
// Add indices
// ... Removed for brevity ...
// Setup texture coordinates
var coordinates = [CGPoint]()
// Add texture coordinates
// ... Removed for brevity ...
// Setup texture image
let imageWidth = 2048.0
let normalizedCoordinates = coordinates.map { coord -> CGPoint in
let x = coord.x / CGFloat(imageWidth)
let y = coord.y / CGFloat(imageWidth)
let textureCoord = CGPoint(x: x, y: y)
return textureCoord
}
// Setup sources
let sources = SCNGeometrySource(vertices: vertices)
let textureCoordinates = SCNGeometrySource(textureCoordinates: normalizedCoordinates)
// Setup elements
let elements = SCNGeometryElement(indices: indices, primitiveType: .triangles)
// Setup Geometry
let geometry = SCNGeometry(sources: [sources, textureCoordinates], elements: [elements])
geometry.firstMaterial?.diffuse.contents = textureImage
// Setup node
let customFace = SCNNode(geometry: geometry)
sceneView.scene?.rootNode.addChildNode(customFace)
// Append the face to the face nodes array
faceNode.append(face)
}
// Iterate the face nodes and append to the scene
for node in faceNode {
sceneView.scene?.rootNode.addChildNode(node)
}
}
Post not yet marked as solved
Hello,
I am using HLS audio stream and I get metadata to show the song info, artist info etc., in the app using AVPlayer. In iOS 14, I see the artwork data (which embeds in WXXX frame of id3 tag) is coming over across along with other metadata. The same stream is working fine and showing artwork data in iOS 13.
Does anything changed in iOS 14 which effects this metadata? Please let me know
Thank you
I am currently working on a macOS app which will be creating very large video files with up to an hour of content. However, generating the images and adding them to AVAssetWriter leads to VTDecoderXPCService using 16+ GB of memory and the kernel-task using 40+ GB (the max I saw was 105GB).
It seems like the generated video is not streamed onto the disk but rather written to memory for it to be written to disk all at once. How can I force it to stream the data to disk while the encoding is happening?
Btw. my app itself consistently needs around 300MB of memory, so I don't think I have a memory leak here.
Here is the relevant code:
func analyse()
{
				self.videoWritter = try! AVAssetWriter(outputURL: outputVideo, fileType: AVFileType.mp4)
				let writeSettings: [String: Any] = [
						AVVideoCodecKey: AVVideoCodecType.h264,
						AVVideoWidthKey: videoSize.width,
						AVVideoHeightKey: videoSize.height,
						AVVideoCompressionPropertiesKey: [
								AVVideoAverageBitRateKey: 10_000_000,
						]
				]
				self.videoWritter!.movieFragmentInterval = CMTimeMake(value: 60, timescale: 1)
				self.frameInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: writeSettings)
				self.frameInput?.expectsMediaDataInRealTime = true
				self.videoWritter!.add(self.frameInput!)
				if self.videoWritter!.startWriting() == false {
						print("Could not write file: \(self.videoWritter!.error!)")
						return
				}
}
func writeFrame(frame: Frame)
{
				/* some more code to determine the correct frame presentation time stamp */
				let newSampleBuffer = self.setTimeStamp(frame.sampleBuffer, newTime: self.nextFrameStartTime!)
				self.frameInput!.append(newSampleBuffer)
				/* some more code */
}
func setTimeStamp(_ sample: CMSampleBuffer, newTime: CMTime) -> CMSampleBuffer {
				var timing: CMSampleTimingInfo = CMSampleTimingInfo(
						duration: CMTime.zero,
						presentationTimeStamp: newTime,
						decodeTimeStamp: CMTime.zero
				)
				var newSampleBuffer: CMSampleBuffer?
				CMSampleBufferCreateCopyWithNewTiming(
						allocator: kCFAllocatorDefault,
					 sampleBuffer: sample,
					 sampleTimingEntryCount: 1,
					 sampleTimingArray: &timing,
					 sampleBufferOut: &newSampleBuffer
			 )
				return	newSampleBuffer!
		}
My specs:
MacBook Pro 2018
32GB Memory
macOS Big Sur 11.1
Post not yet marked as solved
I implemented a custom player and used AVPictureInPictureController. pip button is coming and also calling startPictureInPicture() in action.
controller.isPictureInPicturePossible is returning true.
AVPictureInPictureController delegates are not receiving the call.
Any help?
func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("PIP will start")
} Have enabled Picture in picture in background mode capability
set AVAudioSession category to playback in appdelegate
set AVAudioSession.sharedInstance().setActive(true) as true
Hello there,
in our team we were requested to add the possibility to manually select the video quality. I know that HLS is an adaptive stream and that depending on the network condition it choose the best quality that fits to the current situation.
I also tried some setting with preferredMaximumResolution and preferredPeakBitRate but none of them worked once the user was watching the steam. I also tried something like replacing the currentPlayerItem with the new configuration but anyway this only allowed me to downgrade the quality of the video. When I wanted to set it for example to 4k it did not change to that track event if I set a very high values to both params mentioned above.
My question is if there is any method which would allow me to force certain quality from the manifest file. I already have some kind of extraction which can parse the manifest file and provide me all the available information but I couldn't still figure out how to make the player reproduce specific stream with my desired quality from the available playlist.