MusicKit

RSS for tag

Let users play Apple Music and their local music library from your app using MusicKit.

MusicKit Documentation

Posts under MusicKit tag

210 Posts
Sort by:
Post not yet marked as solved
5 Replies
2.0k Views
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]
Posted
by AppWriter.
Last updated
.
Post marked as solved
3 Replies
55 Views
I'm trying to build a small toy MusicKit app on macOS Ventura (beta 4), and am running into something I think is probably an easy issue. I've started with the single-view application template, and have added a button, the target of which calls MusicKit methods: @IBAction func buttonPushed(_ sender: Any) {     Task {       let status = await MusicAuthorization.request()       switch status {       case .authorized:         print("auth")       case .restricted:         print("restricted")       case .notDetermined:         print("not determined")       case .denied:         print("denied")       @unknown default:         print("default")       }       print(MusicAuthorization.currentStatus)     } } I have added the NSAppleMusicUsageDescription key to the application's Info.plist However, I am always seeing that MusicAuthorization.request() returns denied with no prompt to the user for access. Thank you in advance.
Posted
by nealsid.
Last updated
.
Post not yet marked as solved
0 Replies
28 Views
Hey, Am exploring MusicKit web api. I have a question regarding app key. https://help.apple.com/developer-account/#/deva27624586?sub=dev0416b9004 My question is, do i have to register and pay a developer fee to used the musickit web? @JoeKun and @david-apple if yes could point to the right doc Thanks
Posted Last updated
.
Post not yet marked as solved
2 Replies
148 Views
Hi. I'm trying out some of the new MusicKit functionality using Xcode 14 beta 3 and macOS 13 beta 3 and I'm getting the above error (or similar) whenever I use any of the new classes with a Mac Catalyst destination (an iOS 16 destination works fine). I'm guessing one of my build settings is incorrect on either my project or target, but it's not obvious. So far I've set: Project / IOS Deployment Target = 16.0 Target / Minimum Deployments / iOS = 16.0 Could someone please tell me what I'm missing? Thanks in advance!
Posted
by dutton.
Last updated
.
Post not yet marked as solved
0 Replies
96 Views
When setting the queue with ApplicationMusicPlayer.Queue(for: , startingAt:) in my app built with XCode Version 13.4.1 the app crashes with the message: Thread 1: EXC_BAD_ACCESS (code=1, address=0x8) But the same app with the same code built in Xcode Version 14 beta runs without any single problem. Any ideas how to fix this problem?
Posted
by p_r_a.
Last updated
.
Post not yet marked as solved
1 Replies
90 Views
In this thread it has been stated that getting artist artwork through the MusicKit api isn't allowed because of copyright issues. My question is: Is using the Apple Music REST api to get album artwork via the OpenGraph API also disallowed such that my app would be rejected? Wonder if I should pursue this option that I found or if I need to find another way? Seems like the answer would be no, but wanted to double check. Thanks for your response, this is my first app that I'm trying to publish to the store and I'd like to avoid getting an instant rejection for something like this. Code snippet: import MusicKit import Foundation import OpenGraph extension Artist {     func artwork(width: Int = 1024, height: Int = 1024) async -> URL? {         let id = self.id.rawValue         let countryCode = try? await MusicDataRequest.currentCountryCode         let url = URL(string: "https://music.apple.com/\(countryCode ?? "us")/artist/\(id)")!         return await withCheckedContinuation { continuation in             OpenGraph.fetch(url: url) { result in                 switch result {                     case .success(let og):                         let image = og[.image]?.resizeArtwork(width: width, height: height)                         if let image = image, let url = URL(string: image) {                             continuation.resume(returning: url)                         } else {                             continuation.resume(returning: nil)                         }                     case .failure(_):                         continuation.resume(returning: nil)                 }             }         }     } } extension String {     func resizeArtwork(width: Int, height: Int) -> String? {         do {             let regex = try NSRegularExpression(pattern: "/\\d+x\\d+cw", options: .caseInsensitive)             let newImage = regex.stringByReplacingMatches(in: self, options: [], range: NSRange(0..<self.utf16.count), withTemplate: "/\(width)x\(height)cc")             return newImage         } catch {             return nil         }     } }
Posted Last updated
.
Post not yet marked as solved
1 Replies
178 Views
Hello! I am currently working on a react.js application that is integrating with the MusicKit v3 library. I have followed the documentation to generate a JWT for MusicKit and add the library to my application. Using my token I am able to successfully retrieve song information from the Apple Music API, but I am having trouble with authentication. When I call music.authorize() and successfully go through the Apple sign in popup, I am receiving the following 403 error: https://play.itunes.apple.com/WebObjects/MZPlay.woa/wa/webPlayerLogout 403 musickit.js:44 Uncaught (in promise) AUTHORIZATION_ERROR: Unauthorized After stepping through the music kit API and login popup with breakpoints, I am seeing that the music user token is null, despite the login popup succeeding and returning a proper token/response: {"isAppleMusicSubscriber":"true","musicUserToken":"Ak4ItOgRRRG2y6xgA/OeWQPK0RqPQ/esAJkRN0B/Ua/AWLT52tLhd2TfzMK6uhH+Nczvd7wjYDM1UewG/NledKtimwlrR+s5tdQPk/FG28zqhBqXZ12q6LC516w8ELZDwv5T61kV8xiJ1KSO1q4pGi01JO7SuPMtOqB/QsycYj+xNnrYUEwlP5tm/zxfg7bWmvuWMwfUruYR+A1U9FdXZsdIITVmxCjiHg8ro9xXRzl6Txhsag\u003d\u003d","cid":"REDACTED","itre":"REDACTED","supported":"REDACTED"} I have tested my application with multiple Apple Music users who have paid subscriptions. All accounts are receiving this same error. I have tried regenerating my JWT token multiple times following various guides. My latest attempt used the following node library and parameters: var jwt = require('jsonwebtoken'); var fs = require('fs'); var privateKey = fs.readFileSync('./AuthKey_MYKEY.p8'); let now = new Date(); let nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate()); let nowEpoch = Math.round(now.getTime() / 1000); // number of seconds since Epoch, in UTC let nextMonthEpoch = Math.round(nextMonth.getTime() / 1000); // number of seconds since Epoch, in UTC var payload = {     iss: 'REDACTED', // TEAM ID     iat: nowEpoch,     exp: nextMonthEpoch }; var options = {     algorithm: 'ES256',     header: {         alg: 'ES256',         kid: 'REDACTED' // KEY ID     } }; jwt.sign(payload, privateKey, options, function(error, token) {     console.log(error);     console.log(token); }); I have a valid App Identifier created with the MusicKit App Service enabled. I am stuck! I have no other ideas on the possible root cause here. Is there something I am missing? I have a mobile app currently in Test Flight - does this app need to be released to the app store? I am out of guesses! Any support here would be greatly appreciated! Thank you for your time. Patrick
Posted Last updated
.
Post marked as solved
5 Replies
413 Views
Hi there, I just watched the WWDC22 vids on MusicKit enhancements. In the Explore More Content with MusicKit video, there is a brief mention of "edit playlists" at 24:33. I asked about this a couple years ago here in this forum. The ever-helpful @JoeKun suggested that I submit a Feedback Assistant ticket on the need/justification for this feature, which I did some time ago: FB9798928. Sadly, there's been no traction on that. I'm super hopeful that the ability to remove tracks from a library playlist is now, or at least will soon be, possible; however, I can't find anything in the docs yet to support this notion. Am I being overly optimistic, or are we finally going to get this much requested feature? Thanks.
Posted Last updated
.
Post not yet marked as solved
0 Replies
37 Views
Is there any sample code for obtaining a Music User Token using the JSON web api directly, without using MusicKit? I am writing a utility in C++ to interact with Apple Music, and was not able to figure out how this works from the MusicKit or MusicKit for Android docs. Thank you.
Posted
by nealsid.
Last updated
.
Post not yet marked as solved
9 Replies
480 Views
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!
Posted Last updated
.
Post not yet marked as solved
0 Replies
45 Views
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
Posted Last updated
.
Post not yet marked as solved
0 Replies
62 Views
Hi, Is there a way to get all the episodes (Stations) of a Curator or RadioShow, particularly using the MusicKit enhancements announced at WW22? For example, if I have find an AppleMusic Curator such as "After School Radio" (Curator(id: "1496846020", name: "After School Radio", kind: .editorial)) or a RadioShow (RadioShow(id: "1496846020", name: "After School Radio", hostName: "Mark Hoppus")), is there a way to get all the Stations associated with this curator? There don't seem to be any relationships between Curator, RadioShow, and Station in MusicKit for Swift, and only a relationship from Station to RadioShow in the Apple Music API, but no reverse relationship from RadioShow to Stations. Thanks
Posted
by njooma.
Last updated
.
Post not yet marked as solved
0 Replies
50 Views
I have a few reports of users with music purchased outside iTunes/Apple Music not displaying the album artwork when they play it. I was able to reproduce this on my end, but not sure why this would be happening. Is there a setting that needs to be enabled from Apple Music when adding external music? From my end, is there anything I need to when calling setQueue? async playAlbum(album: string, startPosition: number, shuffle = false) { this.toggleShuffle(shuffle); await this.mkInstance.setQueue({ album, startPosition }); await this.play(); } Right now, I just pass the album ID and call that. Should I be doing this differently?
Posted Last updated
.
Post not yet marked as solved
0 Replies
43 Views
Hey everyone - I'm playing with the Apple Music API, and am looking at using the Get Recently Played Resources endpoint to retrieve the recently played tracks, playlists, and so on for a given user. One common scenario I see happening is the user starting to play a catalog playlist (eg. "Future Hits"); what I'd like to do is display to them the name of that playlist, and then the actual song that's being played. Currently, a call to that endpoint gives me information on the playlist, but nothing about what track is actually being played. If this is possible to retrieve, my guess is it's via the include= or extend= , but I see no documentation about how to use these to get that added information. Does anyone know how/if that is possible?
Posted
by yllus.
Last updated
.
Post not yet marked as solved
0 Replies
55 Views
Hey all - I've noticed that when you launch the login procedure from a custom MusicKit powered app, instead of using the app name (eg. "Apple Music for Vestaboard") it shows the domain name I'm hosting my app at. Is there a way - some META tag or something - to make it use my app name instead?
Posted
by yllus.
Last updated
.
Post not yet marked as solved
1 Replies
76 Views
I'm trying to play an audio file in AndroidMusicKit sample(sdk-test-app). However, the following songs cannot be played. These songs are registered as an AppleMusic library. Songs that cannot be played remain buffered. What should I change to make it playable? Cannot play {  "id" : "269419385",  "title" : "LULU",  "subtitle" : "ZHIVAGO",  "description" : "JUDE",  "browseable" : false,  "playable" : true,  "iconUri" : https://is2-ssl.mzstatic.com/image/thumb/Music123/v4/0b/57/74/0b57744a-a062-0d3d-58cb-423b2e3c303a/4582193800255_cov.jpg/1200x1200bb.jpg,  "type" : "song" } Can play {  "id" : "269417838",  "title" : "**** DEE",  "subtitle" : "ZHIVAGO",  "description" : "JUDE",  "browseable" : false,  "playable" : true,  "iconUri" : https://is2-ssl.mzstatic.com/image/thumb/Music123/v4/0b/57/74/0b57744a-a062-0d3d-58cb-423b2e3c303a/4582193800255_cov.jpg/1200x1200bb.jpg,  "type" : "song" }
Posted Last updated
.
Post not yet marked as solved
1 Replies
118 Views
Is it possible to play songs/playlists on another device on the same account of the user. Effectively, remote control. ex: I own a Mac Book and an iPad, my iPad is connected to speakers, I want to stop and start playing music on the iPad using my Mac Book, through APIs.
Posted
by Afshin9.
Last updated
.
Post not yet marked as solved
5 Replies
491 Views
Hello, I'm using the Get Recently Played Tracks endpoint and I need to know when each track was played. Is there a way to request a timestamp? Thanks!
Posted Last updated
.