Dive into the world of video on Apple platforms, exploring ways to integrate video functionalities within your iOS,iPadOS, macOS, tvOS, visionOS or watchOS app.

Video Documentation

Post

Replies

Boosts

Views

Activity

AVPlayer.replaceCurrentItem(with:) "Incorrect actor executor assumption" runtime crash when building for iOS 18
Hi there, I have some code that's been working fine for the last few versions of iOS and macOS and all the others, and now causes a runtime crash in iOS 18/macOS 15 etc. I have an actor called Player which is basically a big wrapper around an AVPlayer. It all gets compiled down to a Framework, and my clients use it by dropping it in to their video player app code. It handles everything needed for them to be able to talk to our media infrastructure and handles telemetry. It has its own property called avplayer which is an AVPlayer. Gets created at the init(). It has a function called load(_ avPlayerItem: AVPlayerItem) which the clients use to load a new video into player. The offending code (which used to work!) looks like this: Task { @MainActor in avplayer.replaceCurrentItem(with: avPlayerItem) } No warnings in Xcode. When you run it, it crashes on iOS 18 and macOS 15 with this error in the debugger: Incorrect actor executor assumption I thought, "Okay well maybe replaceCurrentItem has changed and doesn't need to be on the main actor anymore, so even if you say this outside of a Main Actor-scoped task: avplayer.replaceCurrentItem(with: avPlayerItem) ...it still crashes the exact same way. Does anyone have any ideas? I'm under some heavy pressure here to get this working and I don't even know where to start with this. Big thanks in advance.
4
0
441
Sep ’24
Why isReadyForMoreMediaData is false sometimes?
Hi, Recording Videos with AVAssetWriter, capture fps(camera output fps) is ok, but final result video fps was lower, the reason is AVAssetWriterInput.isReadyForMoreMediaData is false sometimes. Yes, I have read document many times, it said need to set expectsMediaDataInRealTime to true and balabala... I really be tortured by this problem for a long time, can I debug this problem? or any advice?
2
0
334
Sep ’24
How to generate thumbnails for protected content using AVAssetImageGenerator?
I have a FairPlay-encrypted HLS stream and played the video in an AVPlayer.And I want to generate scrubbing thumbnails using the AVAssetImageGenerator. Also, I am able to generate thumbnails for clear streams but get errors for protected content. *How to generate thumbnails for protected content. func getImageThumbnail(forTime: CMTime) { let generator = AVAssetImageGenerator(asset: asset) generator.appliesPreferredTrackTransform = true generator.cancelAllCGImageGeneration() generator.generateCGImagesAsynchronously(forTimes: [NSValue(time: forTime)]) { [weak self] requestedTime, image, actualTime, result, error in if let error = error { print("Error generate: \(error.localizedDescription)") return } if let image = image { DispatchQueue.main.async { let image = UIImage(cgImage: image).jpegData(compressionQuality: 1.0) self?.playerImg.image = UIImage(data: image!) } } } }
1
0
314
Sep ’24
Progress tracking does not work after the download has been paused and resumed
Hello, I recently started integrating HLS downloads into my application by using AVAssetDownloadTask and AVAssetDownloadConfiguration. I took an example from the documentation as a basis, with only one small difference: the minimum target for my application is iOS 16, so I replaced urlSession(_:assetDownloadTask:willDownloadTo:) with urlSession(_:assetDownloadTask:didFinishDownloadingTo:). And I encountered the following issue: after pausing a download and resuming it later, the progress no longer functions as expected. Could you, please, help me with this? What are the right approaches to implementing pause and progress tracking? Some details: I used devices with iOS 16.0.2 and 17.6.1 for testing. There was no code in the example that pauses the download and resumes it. So, I used the following methods to do this: suspend and resume Also, I have tried to track downloading progress using two different approaches: Using task.progress.observe(\.fractionCompleted) { ... }, which was presented in the example. In this scenario, after a pause, an observation callback will only be called once, when the download has completed, despite the fact that data is being successfully downloaded over the network. Using urlSession(_:assetDownloadTask:didLoad:totalTimeRangesLoaded:timeRangeExpectedToLoad:) and calculating progress as totalTimeRangesLoaded.reduce(0.0) { $0 + CMTimeGetSeconds($1.timeRangeValue.duration) / CMTimeGetSeconds(timeRangeExpectedToLoad.duration) }. In this scenario, I have noticed that the result of the calculation does not always increase, but sometimes there are outliers. Example of logs: 68%, 69%, 70%, 72%, 63%, 65%, 66%, 69%, 70%, 71%, 72%. Such fluctuations are most easily reproduced when I try to resume the download after pause. However, sometimes they occur spontaneously. It's important to mention, that this method marked as deprecated, perhaps for this reason. In both cases download is successful, the problem is with progress reporting only. Full version of code can be found here.
0
0
177
Sep ’24
iOS18 AVPlayerViewController 出现卡住界面
(AVPlayerViewController *)avPlayerVC { if(!_avPlayerVC){ _avPlayerVC =[[AVPlayerViewController alloc] init]; _avPlayerVC.videoGravity = AVLayerVideoGravityResizeAspectFill; _avPlayerVC.showsPlaybackControls = NO; [self addSubview:_avPlayerVC.view]; [_avPlayerVC.view mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(0); }]; [self sendSubviewToBack:_avPlayerVC.view]; } return _avPlayerVC; } 我在一个cell里添加这个,界面无法动弹。只有在iOS18会这样
2
1
336
Sep ’24
iOS18 and Xcode16 using AVPlayer prints lots of warning logs
<<<< FigPlayerInterstitial >>>> fpic_ServiceCurrentEvent signalled err=-15671 (kFigPlayerInterstitialError_ClientReleased) (no primary) at FigPlayerInterstitialCoordinator.m:7885 <<<< FigPlayerInterstitial >>>> fpic_ServiceCurrentEvent signalled err=-15671 (kFigPlayerInterstitialError_ClientReleased) (no primary) at FigPlayerInterstitialCoordinator.m:7885 <<<< FigPlayerInterstitial >>>> fpic_ServiceCurrentEvent signalled err=-15671 (kFigPlayerInterstitialError_ClientReleased) (no primary) at FigPlayerInterstitialCoordinator.m:7885 <<<< FigPlayerInterstitial >>>> fpic_ServiceCurrentEvent signalled err=-15671 (kFigPlayerInterstitialError_ClientReleased) (no primary) at FigPlayerInterstitialCoordinator.m:7885 <<<< FigPlayerInterstitial >>>> fpic_ServiceCurrentEvent signalled err=-15671 (kFigPlayerInterstitialError_ClientReleased) (no primary) at FigPlayerInterstitialCoordinator.m:7885 My project uses AVPlayer (AVPlayerViewController) to play video. There are continuous warning logs while playing and when it goes to dealloc, it prints information below. <<<< PlayerRemoteXPC >>>> remoteXPCItem_handleSetProperty signalled err=-12860 (kFigPlayerError_ParamErr) (propertyValue should be MTAudioProcessingTap) at FigPlayer_RemoteXPC.m:2760 This only happens in iOS 18 and I have no idea about this. There is no any information for FigPlayerInterstitial and else.
1
2
290
Sep ’24
Blocking the main thread when calling the pause method of AVPlayer.
Basic iPhone 11 iOS 17.5.1 Main Thread libsystem_kernel.dylib___ulock_wait (in libsystem_kernel.dylib) +8 libdispatch.dylib__dlock_wait (in libdispatch.dylib) +52 libdispatch.dylib__dispatch_thread_event_wait_slow (in libdispatch.dylib) +52 libdispatch.dylib___DISPATCH_WAIT_FOR_QUEUE__ (in libdispatch.dylib) +364 libdispatch.dylib__dispatch_sync_f_slow (in libdispatch.dylib) +144 MediaToolbox_fpic_CopyCurrentEvent (in MediaToolbox) +132 AVFCore___104-[AVPlayer _setRate:withVolumeRampDuration:playImmediately:rateChangeReason:affectsCoordinatedPlayback:]_block_invoke_2 (in AVFCore) +244 AVFCore-[AVPlayer _setRate:withVolumeRampDuration:playImmediately:rateChangeReason:affectsCoordinatedPlayback:] (in AVFCore) +276 AVFCore-[AVPlayer setRate:] (in AVFCore) +56 call AVPlayer pause Thread 81 name: fpic-sync libsystem_kernel.dylib___ulock_wait (in libsystem_kernel.dylib) +8 libdispatch.dylib__dlock_wait (in libdispatch.dylib) +52 libdispatch.dylib__dispatch_thread_event_wait_slow (in libdispatch.dylib) +52 libdispatch.dylib___DISPATCH_WAIT_FOR_QUEUE__ (in libdispatch.dylib) +364 libdispatch.dylib__dispatch_sync_f_slow (in libdispatch.dylib) +144 MediaToolbox_itemasync_CopyProperty (in MediaToolbox) +588 MediaToolbox_fpic_CurrentItemMoment (in MediaToolbox) +184 MediaToolbox___fpic_EstablishCurrentEventForCurrentItem_block_invoke (in MediaToolbox) +136 libdispatch.dylib__dispatch_client_callout (in libdispatch.dylib) +16 libdispatch.dylib__dispatch_lane_barrier_sync_invoke_and_complete (in libdispatch.dylib) +52 MediaToolbox_fpic_ServiceCurrentEvent (in MediaToolbox) +600 MediaToolbox___fpic_NotifyServiceCurrentEvent_block_invoke (in MediaToolbox) +912 libdispatch.dylib__dispatch_call_block_and_release (in libdispatch.dylib) +28 libdispatch.dylib__dispatch_client_callout (in libdispatch.dylib) +16 libdispatch.dylib__dispatch_lane_serial_drain (in libdispatch.dylib) +744 libdispatch.dylib__dispatch_lane_invoke (in libdispatch.dylib) +428 libdispatch.dylib__dispatch_root_queue_drain (in libdispatch.dylib) +388 libdispatch.dylib__dispatch_worker_thread (in libdispatch.dylib) +256 libsystem_pthread.dylib__pthread_start (in libsystem_pthread.dylib) +132 libsystem_pthread.dylib_thread_start (in libsystem_pthread.dylib) +4 Thread 93 name: com.apple.coremedia.player.async.0x303c60240.P/GR libsystem_kernel.dylib_mach_msg2_trap (in libsystem_kernel.dylib) +8 libsystem_kernel.dylib_mach_msg2_internal (in libsystem_kernel.dylib) +76 libsystem_kernel.dylib_mach_msg_overwrite (in libsystem_kernel.dylib) +432 libsystem_kernel.dylib_mach_msg (in libsystem_kernel.dylib) +20 libdispatch.dylib__dispatch_mach_send_and_wait_for_reply (in libdispatch.dylib) +540 libdispatch.dylib_dispatch_mach_send_with_result_and_wait_for_reply (in libdispatch.dylib) +56 libxpc.dylib_xpc_connection_send_message_with_reply_sync (in libxpc.dylib) +260 CoreMedia_FigXPCConnectionSendSyncMessageCreatingReply (in CoreMedia) +288 CoreMedia_FigXPCRemoteClientSendSyncMessageCreatingReply (in CoreMedia) +44 MediaToolbox_remoteXPCPlayer_SetRateWithOptions (in MediaToolbox) +148 MediaToolbox_playerasync_runOneCommand (in MediaToolbox) +768 MediaToolbox_playerasync_runAsynchronousCommandOnQueue (in MediaToolbox) +180 libdispatch.dylib__dispatch_client_callout (in libdispatch.dylib) +16 libdispatch.dylib__dispatch_lane_serial_drain (in libdispatch.dylib) +744 libdispatch.dylib__dispatch_lane_invoke (in libdispatch.dylib) +428 libdispatch.dylib__dispatch_root_queue_drain (in libdispatch.dylib) +388 libdispatch.dylib__dispatch_worker_thread (in libdispatch.dylib) +256 libsystem_pthread.dylib__pthread_start (in libsystem_pthread.dylib) +132 libsystem_pthread.dylib_thread_start (in libsystem_pthread.dylib) +4
1
0
261
Sep ’24
Floating point value support in CMFormatDescriptionExtension
I updated macOS to 15.0 yesterday, and I found some floating point value support under CMFormatDescriptionExtensions and CVPixelBuffer's Attachment seems to be broken. When I call CMSampleBufferCreateReadyWithImageBuffer() from CVPixelBuffer, macOS 15.0 always fail with floating point values. a. kCMFormatDescriptionExtension_GammaLevel Previous macOS 14.x works with double value like NSString* keyGamma = (__bridge NSString*)kCMFormatDescriptionExtension_GammaLevel; extensions[keyGamma] = @(2.2); b. kCMFormatDescriptionExtension_CleanAperture I am not sure yet but such non-integer value issue also seems to be applied to CleanAperture. kCMFormatDescriptionKey_CleanApertureWidth kCMFormatDescriptionKey_CleanApertureHeight kCMFormatDescriptionKey_CleanApertureHorizontalOffset kCMFormatDescriptionKey_CleanApertureVerticalOffset Also, When I add rational values to extensions, it cannot pass CMVideoFormatDescriptionMatchesImageBuffer() with: kCMFormatDescriptionKey_CleanApertureWidthRational kCMFormatDescriptionKey_CleanApertureHeightRational kCMFormatDescriptionKey_CleanApertureHorizontalOffsetRational kCMFormatDescriptionKey_CleanApertureVerticalOffsetRational Is there any known workaround?
0
0
208
Sep ’24
AVAssetReader init failure -- media services were reset
I work on a video editing app that composes multiple small video clips, sometimes hundreds or thousands. For one user in particular, attempting to export causes a failure 100% of the time. The failure occurs in the initialization of AVAssetReader, and is in the AVFoundationErrorDomain with code -11819 (AVErrorMediaServicesWereReset.) We've done everything we can think of, including quitting other running apps, enabling airplane mode, and even performing the flow on an identical device using the customer's data, and have had no luck pinning down the cause of the error. Does anyone have any suggestion for how we might go about debugging this? Getting ready to file a TSI but thought I should ask here first.
1
0
335
Sep ’24
rendering MV HEVC encoded stereoscopic video frames using RealityKit VideoMaterial and AVSampleBufferVideoRenderer on VisionOS
Hi, Im trying to use this example (https://developer.apple.com/documentation/avfoundation/media_reading_and_writing/converting_side-by-side_3d_video_to_multiview_hevc_and_spatial_video) to encode a stereoscopic (left eye right eye) video frame using MVHEVC. The sample project creates tagged buffers for left and right eye, and uses a writer to write the MVHEC encoded video buffers. But i after i get right and left tagged buffers, i want to use VideoMaterial and its AVSampleBufferVideoRenderer to enqueue these video frames. If i render MVHEVC encoded left eye sample buffer, and right eye sample buffer, sequentially will the AVSampleBufferVideoRenderer render it as a stereoscopic view? How does this work with VideoMaterial and AVSampleBufferVideoRenderer ? Thanks!
1
0
410
Sep ’24
When displaying and playing multiple AVPlayers side by side, some video playback unintentionally speeds up.
When displaying and playing multiple HLS videos (4 or 6 screens) side by side using AVPlayer on iPad devices running iOS 17 or later, even though the videos are set to play at normal speed, some frames appear to be skipped, causing the videos to play faster than intended. This issue occasionally occurs when repeatedly playing and pausing the videos, and the more screens there are, the more frequently it happens. However, the occurrence rate is not very high (about 1 in 50 times). This phenomenon has been reproduced on iPad devices running iOS 17 or later and does not occur on devices running iOS 16 or earlier. Devices where the issue has been confirmed: iPad 6th generation / iOS ver 17.6.1 iPad 9th generation / iOS ver 17.6.1 iPad Pro 11-inch 1st generation / iOS ver 17.4.1 I have tried implementing countermeasures based on information from similar issues, such as those mentioned on the following website, but the problem remains unresolved: https://stackoverflow.com/questions/77224167/avplayer-unexpected-behaviour-after-ios-and-tvos-update-to-17-0 From the console logs, I observed that on devices running iOS 17 or later, the following log was output: AppleD5500: Bad NAL type 10 I suspect that some kind of decoding failure may be occurring, leading to the issue described above. If you have any information or can provide support on this matter, I would greatly appreciate it.
2
0
380
Sep ’24
Memory usage rotating an CVPixelBuffer
I was trying to migrate Core Image based code that's rotating an image in a CVPixelBuffer to the newer VTPixelRotationSession from Video Toolbox. Hoping to increase performance. The original code does: let rotatedImage = CIImage(cvPixelBuffer: origPixelBuffer).oriented(.left) context.render(rotatedImage, to: newPixelBuffer) The new code uses a session: _ = VTPixelRotationSessionRotateImage(rotationSession, origPixelBuffer, newPixelBuffer) However I immediately ran into memory limitations, since my code has to be able to run in an iOS extension. It seems VTPixelRotationSessionRotateImage easily lets memory usage spike over the 50MB of allowed memory. While the CIImage based implementation has no such high memory usage at all. Is this expected? Does the VTPixelRotationSession implementation gain more performance by sacrificing memory? Or is there something I'm overlooking? I was expecting the VTPixelRotationSession at worst to be on par in terms of memory usage and processing speed compared to CIImage. At this moment it seems VTPixelRotationSession is unusable in extensions. See also Feedback: FB14977240
0
0
344
Aug ’24
cannot play a video loaded with AVAssetResourceLoaderDelegate
I'm trying to secure my m3u8 streaming link with a token. To achieve this, I'm using AVAssetResourceLoaderDelegate in my SwiftUI app. However, the video doesn't play in AVPlayer when I'm using the AVAssetResourceLoaderDelegate. I can see that data is being received in the resourceLoader, but the player does not start playback. Here's the code I'm using: @State private var player: AVPlayer? @EnvironmentObject var pilot: UIPilot<AppRoute> var body: some View { VStack { VerticalSpacer(height: 50) HStack { Image(systemName: "arrow.left") .onTapGesture { pilot.pop() } Spacer() Text("liveStreamData.titleShort") .font(.poppins(.semibold, size: 18)) .lineLimit(1) HorizontalSpacer(width: 16) Spacer() } .padding(.horizontal) if let player = player { VideoPlayer(player: player) .onAppear { player.play() } .onDisappear { player.pause() } } else { Text("Loading video...") } } .onAppear { setupPlayer() } } private func setupPlayer() { guard let url = URL(string: "https://assets.afcdn.com/video49/20210722/v_645516.m3u8") else { print("Invalid URL") return } // Replace the scheme with a custom scheme var components = URLComponents(url: url, resolvingAgainstBaseURL: false) components?.scheme = "customscheme" // Change the scheme to a custom one guard let customURL = components?.url else { print("Failed to create custom URL") return } let asset = AVURLAsset(url: customURL) // Set the resource loader delegate let resourceLoaderDelegate = VideoResourceLoaderDelegate() asset.resourceLoader.setDelegate(resourceLoaderDelegate, queue: DispatchQueue.main) let playerItem = AVPlayerItem(asset: asset) player = AVPlayer(playerItem: playerItem) } } class VideoResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate { func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool { guard let url = loadingRequest.request.url else { print("Invalid request URL") return false } // Replace the custom scheme with the original HTTP/HTTPS scheme var components = URLComponents(url: url, resolvingAgainstBaseURL: false) components?.scheme = "https" // Change the scheme back to HTTP/HTTPS guard let originalURL = components?.url else { print("Failed to convert URL back to HTTPS") return false } // Fetch the data from the original URL let urlSession = URLSession.shared let task = urlSession.dataTask(with: originalURL) { data, response, error in if let error = error { print("Error loading resource: \(error)") loadingRequest.finishLoading(with: error) return } if let data = data, let dataRequest = loadingRequest.dataRequest { print("Data loaded: \(data.count) bytes") dataRequest.respond(with: data) loadingRequest.finishLoading() } else { print("No data received") loadingRequest.finishLoading(with: NSError(domain: "VideoResourceLoader", code: -1, userInfo: nil)) } } task.resume() return true } func resourceLoader(_ resourceLoader: AVAssetResourceLoader, didCancel loadingRequest: AVAssetResourceLoadingRequest) { print("Loading request was canceled") } } Problem: The video does not play when using AVAssetResourceLoaderDelegate. The data is being loaded correctly as confirmed by the logs, but AVPlayer fails to start playback. Without the resource loader, the video plays without any issues. Question: What could be causing the player to not play the video when using AVAssetResourceLoaderDelegate? Are there any additional steps or configurations I need to ensure smooth playback while using a resource loader? Any help would be greatly appreciated!
2
0
424
Aug ’24
Metal Performance Shader color issue with yCbCr buffer
I'm making an app that reads a ProRes file, processes each frame through metal to resize and scale it, then outputs a new ProRes file. In the future the app will support other codecs but for now just ProRes. I'm reading the ProRes 422 buffers in the kCVPixelFormatType_422YpCbCr16 pixel format. This is what's recommended by Apple in this video https://developer.apple.com/wwdc20/10090?time=599. When the MTLTexture is run through a metal performance shader, the colorspace seems to force RGB or is just not allowing yCbCr textures as the output is all green/purple. If you look at the render code, you will see there's a commented out block of code to just blit copy the outputTexture, if you perform the copy instead of the scaling through MPS, the output colorspace is fine. So it appears the issue is from Metal Performance Shaders. Side note - I noticed that when using this format, it brings in the YpCbCr texture as a single plane. I thought it's preferred to handle this as two separate planes? That said, if I have two separate planes, that makes my app more complicated as I would need to scale both planes or merge it to RGB. But I'm going for the most performance possible. A sample project can be found here: https://www.dropbox.com/scl/fo/jsfwh9euc2ns2o3bbmyhn/AIomDYRhxCPVaWw9XH-qaN0?rlkey=sp8g0sb86af1u44p3xy9qa3b9&dl=0 Inside the supporting files, there is a test movie. For ease, I would move this to somewhere easily accessible (i.e Desktop). Load and run the example project. Click 'Select Video' Select that video you placed on your desktop It will now output a new video next to the selected one, named "Output.mov" The new video should just be scaled at 50%, but the colorspace is all wrong. Below is a photo of before and after the metal performance shader.
3
0
467
Aug ’24
PiP not launching from a WKWebview Sandboxed app
Hi, I am developing an app that has a WKWebView and it can open sites like Youtube. The app is sandboxed as it is meant to be uploaded to the mac App Store. It has a feature PiP where we start the native PiP by calling a browser Javascript where we tell the WKWEBView to fire the PiP. It works well when we are running the code from XCODE in Debug scheme. When we run the code from release mode by archiving it or directly from the build folder, the WKWebView is not able to fire the PiP Agent and thus the Native PiP window is not visible, while the site shows that PiP is opened and we can here the sound being played. But PiP window is not visible. I cannot see PiPAgent in activity monitor. Why does it not work from within the release build outside xcode. But when I try to run the build directly from the Finder in builds folder, this PiP feature does not work. Request technical help for this. Thanks!
1
1
398
Jul ’24
Enabling EDR on Apple TV for custom HDR video playback with VideoToolbox
How is it possible to enable EDR on Apple TV without AVFoundation for custom HDR video playback? The use case is a custom video player for HDR playback via VideoToolbox and Metal, which seem to render colors correctly on iOS but not on tvOS. All related documentation and WWDC sessions describe APIs that are unavailable for tvOS: let metalLayer = CAMetalLayer() metalLayer.wantsExtendedDynamicRangeContent = true metalLayer.edrMetadata = CAEDRMetadata.hdr10(minLuminance: 0.0, maxLuminance: 1000, opticalOutputScale: 100) What's the alternative path for tvOS to have correct system tone mapping for a setup like: metalLayer.pixelFormat = .rgba16Float // (or .bgr10_xr) metalLayer.colorspace = CGColorSpace(name: CGColorSpace.itur_2100_PQ) Video format: HEVC, YUV 4:2:0 10bit, BT.2020 PQ. We do set the preferredDisplayCriteria on AVDisplayManager and thus video range matching is in place. WWDC Ref: https://developer.apple.com/videos/play/wwdc2022/110565?time=557
1
1
378
Aug ’24