Explore the integration of media technologies within your app. Discuss working with audio, video, camera, and other media functionalities.

Post

Replies

Boosts

Views

Activity

MPMusicPlayerController prepareToPlay errors
I'm getting a variety of errors when I call prepareToPlay on the MPMusicPlayerController. Sometimes they happen, sometimes they don't. I'm trying to play songs from the Apple Music service. When I don't get the errors, it plays just fine. I have iOS v13.5.1 on my iPhone Xs and I'm using Xcode 11.5. This is my code: let applicationMusicPlayer = MPMusicPlayerController.applicationMusicPlayer applicationMusicPlayer.setQueue(with: [trackID]) applicationMusicPlayer.prepareToPlay(completionHandler:{ error in if let error = error { print(error.localizedDescription) return } DispatchQueue.main.async{ applicationMusicPlayer.play() } } These are the various errors I'm getting: [SDKPlayback] Failed to prepareToPlay error: Error Domain=MPMusicPlayerControllerErrorDomain Code=2 "Queue was interrupted by another queue" UserInfo={NSDebugDescription=Queue was interrupted by another queue} [SDKPlayback] Failed to prepareToPlay error: Error Domain=MPMusicPlayerControllerErrorDomain Code=9 "Preparing queue timed out" UserInfo={NSDebugDescription=Preparing queue timed out} [SDKPlayback] Failed to prepareToPlay error: Error Domain=MPMusicPlayerControllerErrorDomain Code=6 "Failed to prepare to play" UserInfo={NSDebugDescription=Failed to prepare to play} [SDKPlayback] applicationQueuePlayer _establishConnectionIfNeeded timeout [ping did not pong]
7
0
4.8k
Jun ’20
MusicKit: developer token request failed
The MusicKit video states that you just enable "MusicKit" in your application identifier and "you're done!" Ok, so I did that, and I'm seeing the following error when trying to run a song query: [DataRequesting] Failed retrieving MusicKit tokens: Error Domain=ICErrorDomain Code=-8200 "Media API Token Service's response was invalid (status code: Unauthorized (401))." UserInfo={NSDebugDescription=Media API Token Service's response was invalid (status code: Unauthorized (401))., NSUnderlyingError=0x6000023a0c60 {Error Domain=AMSErrorDomain Code=301 "Invalid Status Code" UserInfo={NSLocalizedDescription=Invalid Status Code, AMSURL=https://sf-api-token-service.itunes.apple.com/apiToken?REDACTED, AMSStatusCode=401, AMSServerPayload={ status = verificationFailure; }, NSLocalizedFailureReason=The response has an invalid status code}}}. Throwing .developerTokenRequestFailed. Is this just broken on Apple's side? Is there some other magic string that needs to be added to the plist other than NSAppleMusicUsageDescription?
7
0
3.9k
Jun ’21
Upstream Service Error when using MusicDataRequest
Hey there! I'm trying to use MusicDataRequest to fetch the contents of a user's library. Most of the documented endpoints I've tried seem to be working as expected, but the /me/library/artists and /me/library/albums endpoints are consistenty giving me a 500 Upstream Service Error. Here's an example of my code, and the resulting error: let url = URL(string: "https://api.music.apple.com/v1/me/library/albums")! let request = MusicDataRequest(urlRequest: URLRequest(url: url)) do { let response = try await request.response()     let string = String(data: response.data, encoding: .utf8)!     print("success: \(string)") } catch {     print("error: \(error)") } MusicDataRequest.Error(   status: 500,   code: 50001,   title: "Upstream Service Error",   detailText: "Error fetching library content",   id: "5OFXMJAGNU2WCTDKNAYYP4BJXI",   originalResponse: MusicDataResponse(    data: 153 bytes,    urlResponse: <NSHTTPURLResponse: 0x0000000280f04dc0>   ) ) If I replace /albums with /songs or /playlists in the above code everything works as expected. Is there something I'm missing from the albums and artists requests? Or is this a bug with the API?
13
0
3.3k
Jul ’21
How to get the album info for a song fetched by MusicDataRequest?
I'm slowly learning the new MusicKit beta for swift. I've learned to successfully retrieve tracks of type Song using MusicDataRequest, using the following: ... let countryCode = try await MusicDataRequest.currentCountryCode if let url = URL(string: "https://api.music.apple.com/v1/catalog/\(countryCode)/songs?filter[isrc]=\(isrc)") {   let dataRequest = MusicDataRequest(urlRequest: URLRequest(url: url))   let dataResponse = try await dataRequest.response() ... However, when I decode the data, there does not seem to be any album information that I can see. I've tried adding includes=albums to the URL, but I don't think that's the right approach, because when I veiw the Song struct in MusicKit, I don't see a reference to an Album type anywhere. Any advice on how to retrieve the album information would be most appreciated. Thanks.
7
0
3.3k
Aug ’21
MPMusicPlayerController queue information
Is there a way to get the current queue items from an MPMusicPlayerController? I need to know when the items I've set to the queue finish playing completely but cannot find any way to do this. I am not using MusicKit but setting the queue via play parameters. From what I can tell so far, after the queue finishes playing, it pauses and resets to the first item in the queue. So even after playback is done, there is no way to know that it finished on its own.
2
0
1.1k
Nov ’21
AVCaptureVideoDataOutput video range value exceed the range
CVPixelBuffer.h defines kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v', /* Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]). baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */ kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange = 'x420', /* 2 plane YCbCr10 4:2:0, each 10 bits in the MSBs of 16bits, video-range (luma=[64,940] chroma=[64,960]) */ But when I set above format camera output, and I find the output pixelbuffer's value is exceed the range.I can see [0 -255] for 420YpCbCr8BiPlanarVideoRange and [0,1023] for 420YpCbCr10BiPlanarVideoRange Is it a bug or something wrong of the output?If it is not how can I choose the correct matrix transfer the yuv data to rgb?
1
0
1.3k
Dec ’21
How to set the Portrait effect on/off in live camera view in AVFoundation in Swift?
I am using AVFoundation for live camera view. I can get my device from the current video input (of type AVCaptureDeviceInput) like: let device = videoInput.device The device's active format has a isPortraitEffectSupported. How can I set the Portrait Effect on and off in live camera view? I setup the camera like this: private var videoInput: AVCaptureDeviceInput! private let session = AVCaptureSession() private(set) var isSessionRunning = false private var renderingEnabled = true private let videoDataOutput = AVCaptureVideoDataOutput() private let photoOutput = AVCapturePhotoOutput() private(set) var cameraPosition: AVCaptureDevice.Position = .front func configureSession() { sessionQueue.async { [weak self] in guard let strongSelf = self else { return } if strongSelf.setupResult != .success { return } let defaultVideoDevice: AVCaptureDevice? = strongSelf.videoDeviceDiscoverySession.devices.first(where: {$0.position == strongSelf.cameraPosition}) guard let videoDevice = defaultVideoDevice else { print("Could not find any video device") strongSelf.setupResult = .configurationFailed return } do { strongSelf.videoInput = try AVCaptureDeviceInput(device: videoDevice) } catch { print("Could not create video device input: \(error)") strongSelf.setupResult = .configurationFailed return } strongSelf.session.beginConfiguration() strongSelf.session.sessionPreset = AVCaptureSession.Preset.photo // Add a video input. guard strongSelf.session.canAddInput(strongSelf.videoInput) else { print("Could not add video device input to the session") strongSelf.setupResult = .configurationFailed strongSelf.session.commitConfiguration() return } strongSelf.session.addInput(strongSelf.videoInput) // Add a video data output if strongSelf.session.canAddOutput(strongSelf.videoDataOutput) { strongSelf.session.addOutput(strongSelf.videoDataOutput) strongSelf.videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)] strongSelf.videoDataOutput.setSampleBufferDelegate(self, queue: strongSelf.dataOutputQueue) } else { print("Could not add video data output to the session") strongSelf.setupResult = .configurationFailed strongSelf.session.commitConfiguration() return } // Add photo output if strongSelf.session.canAddOutput(strongSelf.photoOutput) { strongSelf.session.addOutput(strongSelf.photoOutput) strongSelf.photoOutput.isHighResolutionCaptureEnabled = true } else { print("Could not add photo output to the session") strongSelf.setupResult = .configurationFailed strongSelf.session.commitConfiguration() return } strongSelf.session.commitConfiguration() } } func prepareSession(completion: @escaping (SessionSetupResult) -&gt; Void) { sessionQueue.async { [weak self] in guard let strongSelf = self else { return } switch strongSelf.setupResult { case .success: strongSelf.addObservers() if strongSelf.photoOutput.isDepthDataDeliverySupported { strongSelf.photoOutput.isDepthDataDeliveryEnabled = true } if let photoOrientation = AVCaptureVideoOrientation(interfaceOrientation: interfaceOrientation) { if let unwrappedPhotoOutputConnection = strongSelf.photoOutput.connection(with: .video) { unwrappedPhotoOutputConnection.videoOrientation = photoOrientation } } strongSelf.dataOutputQueue.async { strongSelf.renderingEnabled = true } strongSelf.session.startRunning() strongSelf.isSessionRunning = strongSelf.session.isRunning strongSelf.mainQueue.async { strongSelf.previewView.videoPreviewLayer.session = strongSelf.session } completion(strongSelf.setupResult) default: completion(strongSelf.setupResult) } } } Then to I set isPortraitEffectsMatteDeliveryEnabled like this: func setPortraitAffectActive(_ state: Bool) { sessionQueue.async { [weak self] in guard let strongSelf = self else { return } if strongSelf.photoOutput.isPortraitEffectsMatteDeliverySupported { strongSelf.photoOutput.isPortraitEffectsMatteDeliveryEnabled = state } } } However, I don't see any Portrait Effect in the live camera view! Any ideas why?
2
0
1.9k
May ’22
Thoughts on MusicLibraryRequest as a replacement for MPMediaQuery
I'm very excited about the new MusicLibrary API, but after a couple of days of playing around with it, I have to say that I find the implementation of filtering MusicLibraryRequests a little confusing. MPMediaQuery has a fairly extensive list of predicates that can be applied, including string and persistentID comparisons for artist, album artist genre, and more. It also lets you filter on an item’s title. MusicLibraryRequests let you filter on the item’s ID, or on its MusicKit Artist and Genre relationships. To me, this seems like it adds an extra step.  With an MPMediaQuery, if I wanted to fetch every album by a given artist, I’d apply an MPMediaPropertyPredicate looking at MPMediaItemPropertyAlbumArtist and compare the string. It was also easy to change the MPMediaPredicateComparison to .contains to match more widely. If I wanted to surface albums by “Aesop Rock” or “Aesop Rock & Blockhead,” I could use that. In the MusicLibraryRequest implementation, it looks like I need to perform a MusicLibraryRequest<Artist> first in order to get the Artist objects. There’s no filter for the name property, so if I don’t have their IDs, I’ve got to use filter(text:). From there, I can take the results of that request and apply them to my MusicLibraryRequest<Album> using the filter(matching:memberOf) function.  I could use filter(text:) on the MusicLibraryRequest<Album>, but that filters across multiple properties (title and artistName?) and is less precise than defining the actual property I want to match against. I think my ideal version of the MusicLibraryRequest API would offer something like filter(matching:equalTo:) or filter(matching:contains:) that worked off of KeyPaths rather than relationships. That seems more intuitive to me. I’m not saying we need every property from every filterable MPMediaItemProperty key, but I’d love to be able to do it on title, artistName, and other common metadata. That might look something like: filter(matching: \.title, contains: “Abbey Road”) filter(matching: \.artistName, equalTo: “Between The Buried And Me”) I noticed that filter(text:) is case insensitive, which is awesome, and something I’ve wanted for a long time in MPMediaPropertyPredicate. As a bonus, it would be great if a KeyPath based filter API supported a case sensitivity flag. This is less of a problem when dealing with Apple Music catalog content, but users’ libraries are a harsh environment, and you might have an artist “Between The Buried And Me” and one called “Between the Buried and Me.” It would be great to get albums from both with something like: filter(matching: \.artistName, equalTo: “Between The Buried And Me”, caseSensitive: false)  I've submitted the above as FB10185685. I also submitted another feedback this morning regarding filter(text:) and repeating text as FB10184823. My last wishlist item for this API (for the time being!) is exposing the MPMediaItemPropertyAlbumPersistentID as an available filter attribute. I know, I know… hear me out. If you take a look at the other thread I made today, you’ll see that due to missing metadata in MusicKit, I still have some use cases where I need to be able to reference an MPMediaItem and might need to fetch its containing MPMediaItemCollection to get at other tracks on the album. It would be nice to seamlessly be able to fetch the MPMediaItemCollection or the library Album using a shared identifier, especially when it comes to being able to play the album in MusicKit’s player rather than Media Player’s.  I've submitted that list bit as FB10185789 Thanks for bearing with my walls of text today. Keep up the great work!
11
1
3.2k
Jun ’22
Issue setting a queue with library and non-library items at the same time (plus a couple more MusicKit issues)
As the summer continues, I have been diving deeper and deeper into MusicKit, largely with great results. A few issues have arisen that I've outlined here, feedbacks already filed and numbers included here. All of this happens on the lasted developer beta and latest Xcode beta. Thanks! FB10967343 - Setting the queue with library and non-library items at the same time doesn't work correctly In my app, I am working on a feature that lets a user shuffle songs from a collection of albums that may or may not be in their library. However, I’ve discovered an issue where the queue does not seem to work correctly when mixing these types. I’ve attempted to load ApplicationMusicPlayer by creating a Queue and to load applicationQueuePlayer using a MPMusicPlayerPlayParametersQueueDescriptor, but the same issue occurs each time. The queue is able to play songs from the same source, but if it’s been playing a library song and tries to move to a non-library song, the queue stops.  The first thing I do is pick random songs from each album, using a MusicLibraryRequest or a MusicCatalogResourceRequest as appropriate, then taking a randomElement() from the ensuing MusicItemCollection for the album.  I append each track to an array, which I then cast to MusicItemCollection so I’ve now got a MusicItemCollection consisting of the tracks I want. If I’m in MusicKit land, I simply set the queue as follows:  player.queue = ApplicationMusicPlayer.Queue(for: tracks) It takes a bit more doing in MediaPlayer, but in theory this should also work, right?    do {         let paramObjects = tracks.compactMap {             $0.playParameters         }         let params = try paramObjects.map({try JSONEncoder().encode($0)}) let dicts = try params.compactMap {               try JSONSerialization.jsonObject(with: $0, options: []) as? [String:Any]           }           let finalParams = dicts.compactMap {                 MPMusicPlayerPlayParameters(dictionary: $0)             } let descriptor = MPMusicPlayerPlayParametersQueueDescriptor(playParametersQueue: finalParams) mediaPlayer.setQueue(with: descriptor) } catch { print(error) } In either case, the following issue occurs: say that I end up with a queue made up of one library song, then one non-library song. The player will play just the first song, then it acts as if the queue has ended. Say that it has two non-library songs, then one library song. Just the two non-library songs play. Indeed, printing queue.entries shows just the number of items that were from the same source type. FB10967076 - Publishing changes from background thread error when inserting queue items When using the .insert method on ApplicationMusicPlayer.Queue on the last iOS 16 and Xcode betas, it returns a “Publishing changes from background thread” error even though the function I’m doing in is marked as a @MainActor and the stacktace indicates it was on the main thread. FB10967277 - song.with([.albums], preferredSource: .library) generates thousands of lines of EntityQueries in the console I’ve noticed that when using the preferredSource: .library when requesting additional properties on a library item creates ~6,000 of “EntityQuery” entries in the console, all in the span of a second. This doesn’t seem to be leading to any major performance issues, but it sure seems like something isn't right. let request = MusicLibraryRequest<Song>.init() do { let response = try await request.response() guard let song = response.items.first else { return } let songWithAlbums = try await song.with([.albums], preferredSource: .library) } catch { print(error) } generates the following output (except... 6,000 of them) 2022-07-31 13:02:07.729003-0400 MusicKitFutzing[9405:2192606] [EntityQuery] Finished fetching results in 0s 2022-07-31 13:02:07.729047-0400 MusicKitFutzing[9405:2192605] [EntityQuery] Finished executing query in 0.00100017s 2022-07-31 13:02:07.729202-0400 MusicKitFutzing[9405:2192611] [EntityQuery] Finished executing query in 0s 2022-07-31 13:02:07.729240-0400 MusicKitFutzing[9405:2192605] [EntityQuery] Finished fetching results in 0s
1
1
1.4k
Jul ’22
Detect the end of queue in MPMusicPlayerController
Hello, this is building off of another post in which several other posters and I had already attempted solving the issue in hacky ways. I am using MPMusicPlayerController.applicationQueuePlayer. My end goal here is to dynamically add items to the queue when it has ended based on my application's business logic. There is no way for me to know what these items will be when I am initially setting the queue. I have an updated implementation that seems to cover most edge cases, except for a glaringly obvious one – if there is just one item in the queue, and the user skips the track via MPRemoteCommandCenter (eg. lock screen), then it does not work. Currently, when I receive a MPMusicPlayerControllerPlaybackStateDidChange notification, I run this block: if player.playbackState == .paused,            player.currentPlaybackTime == 0,            player.indexOfNowPlayingItem == 0 {             EndOfQueueManager.handle()         } In the absence of a mechanism to detect the end of the queue from the framework, I would love to add the ability to add a target to MPRemoteCommand, like you can do for AVPlayer. I have tried to do exactly that, but it does not work: MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in         if queue.count == 1 {             EndOfQueueManager.handle() }         return .success } I already have a functioning AVPlayer implementation that achieves my goal without any compromises or edge cases. I would be very disappointed if there is no way to do this with MPMusicPlayerController – being notified about the queue ending feels like a fairly rudimentary API hook.
1
2
937
Oct ’22
Is it possible to get only audio from ScreenCaptureKit?
I'm creating app that listening other app's sound. in this use case, screen data is not needed. but if I don't call SCStream#addStreamOutput(_, type: .screen, ...), console shows this error: [ERROR] _SCStream_RemoteVideoQueueOperationHandlerWithError:701 stream output NOT found. Dropping frame currently I'm setting SCStreamConfiguration#minimumFrameInterval to large value (e.g. 0.1fps) as workaround, but it would be good if i can completely disable screen capture for best performance. there is any way to disable screen capture and only captures apps audio?
5
1
2.2k
Oct ’22
iOS 16 Music Kit MusicLibrary methods have stopped working
Hi there, I have a related forum thread here and a Feedback Assistant ticket open, but this issue seems different. Sometime within the last 2-3 weeks, code related to MusicLibrary has stopped working. None of my code has changed. For example, the below two snippets used to work fine:  for track in newTracks {    try await MusicLibrary.shared.add(track, to: targetPlaylist)  } try await MusicLibrary.shared.edit(targetPlaylist, items: items) newTracks and items are both fetched using: try await targetPlaylist.with(.tracks, preferredSource: .catalog).tracks Using preferredSource: .catalog was a workaround used to address the issue in the aforementioned post above. All iOS 16 capable functions are decorated with: @available(iOS 16, *) or in an if block: if #available(iOS 16, *) {... What's happening is that the following is showing up in the console: 2022-11-28 23:31:11.279648+0700 MyApp[38653:6736450] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-28 23:31:11.279718+0700 MyApp[38653:6736450] [Default] <ICUserIdentityStoreACAccountBackend: 0x282adb520> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 2022-11-28 23:31:11.279758+0700 MyApp[38653:6736450] [Default] ICUserIdentity - Unable to retrieve DSID for userIdentity=<ICUserIdentity 0x2806eb120: [Active Account: <unresolved>]> - error=Error Domain=com.apple.accounts Code=7 "(null)" These errors are not caught by a do/catch block, but I assume they are related to the issue, and I believe they have to do with MyApp trying to access things that Music Kit thinks it's not supposed to. For example, if MyApp attempts to work with a playlist that it did not create, errors would be expected, thrown errors. The thing is that I know I'm working with resources that are created by MyApp. In fact, in trying to test this, I just tried to create a playlist with the below, and the same behavior is occurring: @available(iOS 16, *) func createPlaylist2(name: String, description: String) async -> MusicKit.Playlist? {     do {         Logger.log(.info, "Creating Playlist: \(name)")         Logger.log(.shrug, "Does this work?")         let newPlaylist = try await MusicLibrary.shared.createPlaylist(name: name, description: description) // <= Things stop here!         Logger.log(.success, "New playlist created: \(newPlaylist)") // <= this isn't logged.         return newPlaylist // <= nothing is returned     } catch {         Logger.log(.error, "Could not create new playlist: \(error)") // <= no error logged.     }     return nil } The result is: 2022-11-29 00:15:01.875064+0700 MyApp[38794:6760471] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-29 00:15:01.875372+0700 MyApp[38794:6760471] [Default] <ICUserIdentityStoreACAccountBackend: 0x283005720> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 2022-11-29 00:15:01.876677+0700 MyApp[38794:6760323] [EntityQuery] Finished executing query in 0.000999928s 2022-11-29 00:15:01.889055+0700 MyApp[38794:6760323] [EntityQuery] Finished fetching results in 0.0120001s 2022-11-29 00:15:01.891235+0700 MyApp[38794:6760329] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-29 00:15:01.891684+0700 MyApp[38794:6760329] [Default] <ICUserIdentityStoreACAccountBackend: 0x283005720> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 📘 Creating Playlist: TEST PLAYLIST 🤷🏻‍♀️ Does this work? 2022-11-29 00:15:06.697374+0700 MyApp[38794:6760329] [] nw_path_necp_check_for_updates Failed to copy updated result (22) What's really nasty is that errors are not thrown, so they can't be caught and handled in a catch block. I know that iOS 16.1 got released around the end of October, but I really don't know what's going on here. The behavior is showing up in both prod and when testing locally. Any help would be most appreciated. @JoeKhun: Did I miss the memo?
10
1
4.6k
Nov ’22
Ventura Hack for FireWire Core Audio Support on Supported MacBook Pro and others...
Hi all,  Apple dropping on-going development for FireWire devices that were supported with the Core Audio driver standard is a catastrophe for a lot of struggling musicians who need to both keep up to date on security updates that come with new OS releases, and continue to utilise their hard earned investments in very expensive and still pristine audio devices that have been reduced to e-waste by Apple's seemingly tone-deaf ignorance in the cries for on-going support.  I have one of said audio devices, and I'd like to keep using it while keeping my 2019 Intel Mac Book Pro up to date with the latest security updates and OS features.  Probably not the first time you gurus have had someone make the logical leap leading to a request for something like this, but I was wondering if it might be somehow possible of shoe-horning the code used in previous versions of Mac OS that allowed the Mac to speak with the audio features of such devices to run inside the Ventura version of the OS.  Would it possible? Would it involve a lot of work? I don't think I'd be the only person willing to pay for a third party application or utility that restored this functionality. There has to be 100's of thousands of people who would be happy to spare some cash to stop their multi-thousand dollar investment in gear to be so thoughtlessly resigned to the scrap heap.  Any comments or layman-friendly explanations as to why this couldn’t happen would be gratefully received!  Thanks,  em
51
8
22k
Dec ’22
MusicKit MusicCatalogResourceRequest for artists with top-songs returns 504 in non-json format
I'm making a request to get 10 artists with their top songs at once, but for some artists it will always fail with a 504. The response is also in HTML which leads to a decoding error. This is my code var request = MusicCatalogResourceRequest<Artist>(matching: \.id, memberOf: ids) request.properties = properties let response = try await request.response() where ids is MusicItemId. Below I have an input which will always fail 100% of the time, even when retried. 10 elements  - 0 : "51639"  - 1 : "331584"  - 2 : "120199"  - 3 : "45058"  - 4 : "284786497"  - 5 : "44984"  - 6 : "37299"  - 7 : "518462"  - 8 : "39525"  - 9 : "73568" Example response: [DataRequesting] Failed to parse body of response with status code Unknown (504):  <!DOCTYPE html> <html lang="en"> <head>   <style>     body {       font-family: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;       font-size: 15px;       font-weight: 200;       line-height: 20px;       color: #4c4c4c;       text-align: center;     }     .section {       margin-top: 50px;     }   </style> </head> <body> <div class="section">   <h1>&#63743;</h1>   <h3>Gateway Timeout</h3>   <p>Correlation Key: WFRI6Q5HXAUJYXGNRKQ6YTBYIM</p> </div> </body> </html> I have also tried batching these into 2 requests of 5 artists instead of 1 request of 10 artists which still fails. However, I do have sets of 10 artists that work fine. Anyone know why?
3
1
2.3k
Jan ’23
[Metal] 9072 by 12096 iosurface is too large for GPU
I take a picture using the iPhone's camera. The taken resolution is 3024.0 x 4032. I then have to apply a watermark to this image. After a bunch of trial and error, the method I decided to use was taking a snapshot of a watermark UIView, and drawing that over the image, like so: // Create the watermarked photo. let result: UIImage=UIGraphicsImageRenderer(size: image.size).image(actions: { _ in   image.draw(in: .init(origin: .zero, size: image.size))   let watermark: Watermark = .init(     size: image.size,     scaleFactor: image.size.smallest / self.frame.size.smallest   )   watermark.drawHierarchy(in: .init(origin: .zero, size: image.size), afterScreenUpdates: true) }) Then with the final image — because the client wanted it to have a filename as well when viewed from within the Photos app and exported from it, and also with much trial and error — I save it to a file in a temporary directory. I then save it to the user's Photo library using that file. The difference as compared to saving the image directly vs saving it from the file is that when saved from the file the filename is used as the filename within the Photos app; and in the other case it's just a default photo name generated by Apple. The problem is that in the image saving code I'm getting the following error: [Metal] 9072 by 12096 iosurface is too large for GPU And when I view the saved photo it's basically just a completely black image. This problem only started when I changed the AVCaptureSession preset to .photo. Before then there was no errors. Now, the worst problem is that the app just completely crashes on drawing of the watermark view in the first place. When using .photo the resolution is significantly higher, so the image size is larger, so the watermark size has to be commensurately larger as well. iOS appears to be okay with the size of the watermark UIView. However, when I try to draw it over the image the app crashes with this message from Xcode: So there's that problem. But I figured that could be resolved by taking a more manual approach to the drawing of the watermark then using a UIView snapshot. So it's not the most pressing problem. What is, is that even after the drawing code is commented out, I still get the iosurface is too large error. Here's the code that saves the image to the file and then to the Photos library: extension UIImage {   /// Save us with the given name to the user's photo album.   /// - Parameters:   ///  - filename: The filename to be used for the saved photo. Behavior is undefined if the filename contain characters other than what is represented by this regular expression [A-Za-z0-9-_]. A decimal point for the file extension is permitted.   ///  - location: A GPS location to save with the photo.   fileprivate func save(_ filename: String, _ location: Optional&lt;Coordinates&gt;) throws {           // Create a path to a temporary directory. Adding filenames to the Photos app form of images is accomplished by first creating an image file on the file system, saving the photo using the URL to that file, and then deleting that file on the file system.     //   A documented way of adding filenames to photos saved to Photos was never found.     // Furthermore, we save everything to a `tmp` directory as if we just tried deleting individual photos after they were saved, and the deletion failed, it would be a little more tricky setting up logic to ensure that the undeleted files are eventually     // cleaned up. But by using a `tmp` directory, we can save all temporary photos to it, and delete the entire directory following each taken picture.     guard       let tmpUrl: URL=try {         guard let documentsDirUrl=NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {           throw GeneralError("Failed to create URL to documents directory.")         }         let url: Optional&lt;URL&gt; = .init(string: documentsDirUrl + "/tmp/")         return url       }()     else {       throw GeneralError("Failed to create URL to temporary directory.")     }           // A path to the image file.     let filePath: String=try {               // Reduce the likelihood of photos taken in quick succession from overwriting each other.       let collisionResistantPath: String="\(tmpUrl.path(percentEncoded: false))\(UUID())/"               // Make sure all directories required by the path exist before trying to write to it.       try FileManager.default.createDirectory(atPath: collisionResistantPath, withIntermediateDirectories: true, attributes: nil)               // Done.       return collisionResistantPath + filename     }()     // Create `CFURL` analogue of file path.     guard let cfPath: CFURL=CFURLCreateWithFileSystemPath(nil, filePath as CFString, CFURLPathStyle.cfurlposixPathStyle, false) else {       throw GeneralError("Failed to create `CFURL` analogue of file path.")     }           // Create image destination object.     //     // You can change your exif type here.     //   This is a note from original author. Not quite exactly sure what they mean by it. Link in method documentation can be used to refer back to the original context.     guard let destination=CGImageDestinationCreateWithURL(cfPath, UTType.jpeg.identifier as CFString, 1, nil) else {       throw GeneralError("Failed to create `CGImageDestination` from file url.")     }           // Metadata properties.     let properties: CFDictionary={               // Place your metadata here.       // Keep in mind that metadata follows a standard. You can not use custom property names here.       let tiffProperties: Dictionary&lt;String, Any&gt;=[:]               return [         kCGImagePropertyExifDictionary as String: tiffProperties       ] as CFDictionary     }()           // Create image file.     guard let cgImage=self.cgImage else {       throw GeneralError("Failed to retrieve `CGImage` analogue of `UIImage`.")     }     CGImageDestinationAddImage(destination, cgImage, properties)     CGImageDestinationFinalize(destination)             // Save to the photo library.     PHPhotoLibrary.shared().performChanges({       guard let creationRequest: PHAssetChangeRequest = .creationRequestForAssetFromImage(atFileURL: URL(fileURLWithPath: filePath)) else {         return       }       // Add metadata to the photo.       creationRequest.creationDate = .init()       if let location=location {         creationRequest.location = .init(latitude: location.latitude, longitude: location.longitude)       }     }, completionHandler: { _, _ in       try? FileManager.default.removeItem(atPath: tmpUrl.absoluteString)     })   } } If anyone can provide some insight as to what's causing the iosurface is too large error and what can be done to resolve it, that'd be awesome.
3
0
2k
Jan ’23
AVSampleBufferDisplayLayer crash on flush
I am calling AVSampleBufferDisplayLayer.flush from a background queue but this seems to occasionally crash the app. I am calling it from the same thread I pass to - (void)requestMediaDataWhenReadyOnQueue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block;. My question is, is this API threadsafe, or do I need to call flush from the main thread? Or is there another issue that I am not considering? It seems strange to me that this API would trigger an autolayout pass. 0 CoreFoundation 0x00000001bb384e38 __exceptionPreprocess + 164 1 libobjc.A.dylib 0x00000001b451b8d8 objc_exception_throw + 59 2 CoreAutoLayout 0x00000001d7e09e84 _AssertAutoLayoutOnAllowedThreadsOnly + 327 3 CoreAutoLayout 0x00000001d7e00e60 -[NSISEngine withBehaviors:performModifications:] + 35 4 UIKitCore 0x00000001be58fd40 -[UIView _postMovedFromSuperview:] + 671 5 UIKitCore 0x00000001bd56dfec -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1903 6 UIKitCore 0x00000001bda57ccc -[_UITextLayoutCanvasView textViewportLayoutController:configureRenderingSurfaceForTextLayoutFragment:] + 455 7 UIFoundation 0x00000001c588bc9c __48-[NSTextViewportLayoutController layoutViewport]_block_invoke_4 + 151 8 UIFoundation 0x00000001c5836b50 __80-[NSTextLayoutManager enumerateViewportElementsFromLocation:options:usingBlock:]_block_invoke + 43 9 UIFoundation 0x00000001c580e158 __83-[NSTextLayoutManager enumerateTextLayoutFragmentsFromLocation:options:usingBlock:]_block_invoke_2 + 535 10 CoreFoundation 0x00000001bb385350 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 23 11 CoreFoundation 0x00000001bb3b24dc -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:] + 91 12 UIFoundation 0x00000001c580de28 __83-[NSTextLayoutManager enumerateTextLayoutFragmentsFromLocation:options:usingBlock:]_block_invoke + 775 13 UIFoundation 0x00000001c57f7504 -[NSTextLayoutManager enumerateTextLayoutFragmentsFromLocation:options:usingBlock:] + 659 14 UIFoundation 0x00000001c57f7264 -[NSTextLayoutManager enumerateViewportElementsFromLocation:options:usingBlock:] + 99 15 UIFoundation 0x00000001c57f6d7c -[NSTextViewportLayoutController layoutViewport] + 1299 16 UIKitCore 0x00000001bd580a3c +[UIView(Animation) performWithoutAnimation:] + 75 17 UIKitCore 0x00000001bd5582d0 -[_UITextLayoutCanvasView layoutSubviews] + 139 18 UIKitCore 0x00000001bd5544c8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1979 19 QuartzCore 0x00000001bca277fc CA::Layer::layout_if_needed(CA::Transaction*) + 499 20 QuartzCore 0x00000001bca3aeb0 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 147 21 QuartzCore 0x00000001bca4c234 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 443 22 QuartzCore 0x00000001bca81630 CA::Transaction::commit() + 651 23 MediaToolbox 0x00000001ca8d0da0 videoQueueRemote_SetProperty + 367 24 AVFCore 0x00000001cad191b4 __63-[AVSampleBufferVideoRenderer _setContentLayerOnFigVideoQueue:]_block_invoke + 179 25 libdispatch.dylib 0x00000001c299cf88 _dispatch_client_callout + 19 26 libdispatch.dylib 0x00000001c29ac574 _dispatch_lane_barrier_sync_invoke_and_complete + 55 27 AVFCore 0x00000001cad190d0 -[AVSampleBufferVideoRenderer _setContentLayerOnFigVideoQueue:] + 167 28 AVFCore 0x00000001cad14674 -[AVSampleBufferVideoRenderer _createVideoQueue:errorStep:] + 195 29 AVFCore 0x00000001cad14ac8 -[AVSampleBufferVideoRenderer createVideoQueue:] + 55 30 AVFCore 0x00000001cad179cc -[AVSampleBufferVideoRenderer flushWithRemovalOfDisplayedImage:completionHandler:] + 439 31 App 0x0000000102370214 -[AVSampleBufferDisplayLayer flush] + 51
1
0
680
Mar ’23