Music Kit JS with Multiple Songs (not in playlist)

I'm trying to stream an array of Apple music songs that are not tied to a single playlist. I have all the id's of these songs and I can play them individually if I use "setQueue" such as this:

   await musicKit.value.setQueue({
    songs: ["1616228595", "1564530724"],
    autoplay: true,
    });

After the first song finishes playing it just stops altogether. How can I have the next song in the array play? I'm able to use:

  await musicKit.value.skipToNextItem();
  await musicKit.value.skipToPreviousItem();

And that works fine to toggle between the songs in the array, but I haven't found anything that shows an example of how this would be done with an array of songs such as I have. What do I need to add in order to get this playing songs back to back in from the song array?

Replies

Thanks for reaching out, @gonzosan

Assuming that musicKit.value in your example above is the MusicKit instance (i.e. return value of MusicKit.getInstance()), and based on the other information you provided, your example should work as you expected, which is to say that the first song ending should trigger playback of the next.

The autoplay property is deprecated, but still supported, in our V3 MusicKit framework. The preferred property is startPlaying, but there should not be a practical impact currently.

It would be helpful to see more of your code example. Could you please file a ticket in the Feedback Assistant with more information, including any console or network errors you're seeing, and more of your MusicKit integration, for instance the MusicKit.configure call?

This is the whole function used to load and start the music kit instance:

const loadAppleMusic = async () => {
  const mk = await (window as any).MusicKit;
  console.log("mk", mk);

  const token = await getAppleDevToken();
  await mk.configure({
    developerToken: token,
    app: {
      name: "MusicKit Music Example",
      build: "1.0.0",
    },
  });

  musicKit.value = mk.getInstance();

  musicKit.value.volume = 0.5;

};

I also previously had it as:

musicKit.value = await mkConfigure({})

Then I use this function to play the songs by their id:

const loadDynamicTracks = async () => {
  await musicKit.value.setQueue({
    songs: ["1616228595", "1564530724"],
    startPlaying: true,
  });
};

I also added these event listeners:

  musicKit.value.addEventListener("queueIsReady", (data: any) => {
    console.log("Queue is ready", data);
  });

  musicKit.value.addEventListener("queueItemsDidChange", (data: any) => {
    console.log("Queue items changed", data);
  });

These fire off once everything is loaded, and it looks like I'm getting the proper songs in the queue from what I've seen. Is there something else I need to update? Seems like I'm missing something that would move to the next song in the queue. Is there an event listener I should add that would help me troubleshoot this? I added this one as well, but it doesn't get called:

  musicKit.value.addEventListener("mediaPlaybackError", (data: any) => {
    console.log("Playback Error", data);
  });

I appreciate the help.

Also this is what I'm getting in the console:

Right after the song plays "now playing" shows undefined for the item. As you can see in the Queue items changed there are two media items so I don't know what's going on.

So I tested this again today, this time using different tracks and it seems to be working. I did notice that if I use a specific track from Billie Eilish that it would either not play or would play for a second then stop and sometimes even continue to the next track. From the events I have set up, I didn't see any errors. I'm not entirely sure what the issue is, but using a few different tracks works just fine. If I continue to have issues with this then I'll submit a ticket.

Thank you for the response, @gonzosan

I attempted to reproduce with the song IDs you listed in your example, and it seems that the song with Adam ID 1616228595 may not be available in Apple Music at this time. The Apple Music API response for this song returns a 404 with a message: "Resource with requested id was not found".

It's possible that the track is available in some storefronts, but not all. I tried a few including us, jp, and fr, which were all 404s.

Is there a way for me to verify which storefronts a track is available in through an API? With the application, I'm building I search for tracks based on ISRC. Initially, I'm able to find these tracks just fine, but when I go to play them using the Player I will randomly encounter one of these tracks that are not available and get a popup. What are my options for this? If I could verify these tracks are not available in certain countries that would help alleviate this issue. These tracks would be played worldwide so I need a way to verify that tracks can be played before they get to the streaming aspect.

Thank you for following up, @jgonzosan

It is possible that your initial post was hitting the same issue seen in this forum post:

https://developer.apple.com/forums/thread/701357

There have been changes to the service since then, such that searching for tracks based on ISRC in the context of a storefront should return playable results from that storefront. If you are seeing issues still, please file a ticket including steps to reproduce in the Feedback Assistant.

An item being playable in one storefront does not guarantee that it will also be playable in other storefronts, however. For situations such as this, you can query for equivalencies within the storefront. See Apple Music API: Managing Content Ratings, Alternate Versions, and Equivalencies for more information.

There is also a WWDC 2021 session which may be helpful: Cross reference content with the Apple Music API