# GSoc Proposal for Integrating Apple Music with ListenBrainz

**URL:** https://community.metabrainz.org/t/gsoc-proposal-for-integrating-apple-music-with-listenbrainz/631010
**Category:** GSoC applications
**Tags:** gsoc-2023, listenbrainz
**Created:** [April 2, 2023, 5:59am UTC](https://community.metabrainz.org/t/gsoc-proposal-for-integrating-apple-music-with-listenbrainz/631010 "2023-04-02T05:59:32Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![vardansaini](https://community.metabrainz.org/letter_avatar_proxy/v4/letter/v/41988e/32.png) [@vardansaini](https://community.metabrainz.org/u/vardansaini)
#### Post date: [April 2, 2023, 5:59am UTC](https://community.metabrainz.org/t/gsoc-proposal-for-integrating-apple-music-with-listenbrainz/631010/1 "2023-04-02T05:59:32Z")

</div>

# Personal Information

Name: Vardan Saini  
School: University of Alberta  
Github: `https://github.com/vardansaini`  
Linkedin: [https://www.linkedin.com/in/vardansaini/](https://www.linkedin.com/in/vardansaini/)  
Portfolio: [Vardan Saini](https://vardansaini.github.io/vardansaini/)  
IRC nickname: vscode  
email: vardan1@ualberta.ca

My contributions:

> <https://github.com/metabrainz/listenbrainz-server/pull/2427>
>
> \# Problem
> 
> 
> 
> The Android App needed a way to know whether the user has conne…cted their CritiqueBrainz account with ListenBrainz. Therefore, I added a new API endpoint to return the list of services a user has connected to their account.
> https://tickets.metabrainz.org/browse/LB-1240
> 
> \# Solution
> 
> 
> 
> I added a new API endpoint to return the list of services a user has connected to their account.
> 
> \# Action
> 
> 
> 
> I am slightly confused about tests so I might need help with that.

> <https://github.com/metabrainz/listenbrainz-server/pull/2033>
>
> \# Problem
> 
> Spotify search was not being tested
> https://tickets.metabrainz.org…/browse/LB-583
> 
> 
> \# Solution
> 
> Added test for Spotify Search
> 
> 
> \# Action
> 
> in utils.test I added tests using Jest for Spotify search and I added a JSON file for response

> <https://github.com/metabrainz/listenbrainz-server/pull/2022>
>
> \# Problem
> 
> 
> Dead link on https://listenbrainz.org/lastfm-proxy/
> LB-…1083
> 
> 
> 
> 
> \# Solution
> 
> 
> incorrect link:- https://github.com/metabrainz/listenbrainz-server/blob/master/API\_compatible\_README.md
> correct link:- https://listenbrainz.readthedocs.io/en/latest/users/api-compat/
> 
> 
> 
> \# Action
> 
> 
> link has been fixed

# Project Overview

By linking their Apple Music account with ListenBrainz, individuals are able to use ListenBrainz to play their music selections. The integration into BrainzPlayer allows for this capability. By utilizing a content resolver, we can match the MusicBrainz Identifier (MBID) to the Apple Music catalog, permitting users to transfer playlists to their Apple Music account.

# Introduction

ListenBrainz currently supports integration with Spotify, but there is a growing demand for integration with other music services. Apple Music is a popular music streaming service, and integrating it into ListenBrainz will provide more options for users to access personalized recommendations. This proposal outlines the steps to integrate Apple Music into ListenBrainz.

## OAuth Integration

### Frontend

1. The first step in integrating Apple Music into ListenBrainz is to configure OAuth on the frontend. The MusicKit  
JavaScript library can be used to authenticate users with their Apple Music accounts using the OAuth protocol.

```html
<script src="https://js-cdn.music.apple.com/musickit/v3/musickit.js" data-web-components async></script>

```

2. The developer token needs to be generated on the backend and sent to the frontend. Once the MusicKit library is  
included in the web page, the `configure` method is called to configure an instance of MusicKit on the Web.

```javascript
document.addEventListener('musickitloaded', async function () {
    try {
        await MusicKit.configure({
            developerToken: 'DEVELOPER-TOKEN',
            app: {
                name: 'ListenBrainz',
                build: 'GIT-COMMIT-SHA',
            },
        });
    } catch (err) {
        // Handle configuration error
    }
    const music = MusicKit.getInstance();
});

```

3. The `authorize` method can be used to authenticate the user and access their Apple Music account. This step involves  
the following:

```javascript
music.authorize().then(musicUserToken => {
    submitMusicUserTokenToLB(musicUserToken);
});

```

### Backend

1. The music services callback URL (`/music-services/{service}/callback`) receives the authorization code in case of  
of other music services. However, in the case of Apple Music there is no client secret oauth available. Instead we  
do OAuth client side using MusicKit and once the user has granted access, the Music-User-Token is sent to server at  
callback URL.

2. Apple Music’s catalog varies with the user’s storefront so store we should retrieve and store it.

3. The token and storefront can be stored in the database to be used later.

## Integrate Apple Music in BrainzPlayer

The BrainzPlayer is a web-based player used to play music on ListenBrainz from various services. It already supports playing music from [Spotify](https://github.com/metabrainz/listenbrainz-server/blob/master/frontend/js/src/brainzplayer/SpotifyPlayer.tsx), [Youtube](https://github.com/metabrainz/listenbrainz-server/blob/master/frontend/js/src/brainzplayer/YoutubePlayer.tsx) and [Soundcloud](https://github.com/metabrainz/listenbrainz-server/blob/master/frontend/js/src/brainzplayer/SoundcloudPlayer.tsx).

1. MusicKit can be loaded on the page in the same as shown in the OAuth Frontend section.

2. Once the player is loaded, we can use [`MusicKitInstance.{play,pause}`](https://js-cdn.music.apple.com/musickit/v3/docs/index.html?path=/docs/reference-javascript-musickit-instance--page#pause)  
etc. controls and add callbacks to `playbackStateWillChange` and `playbackStateDidChange` events to integrate with BrainzPlayer controls.

3. Tracks can be enqueued in the MusicKit player using `setQueue` or `playNext` method and its Apple Music Identifier:

4. If the listen does not have an Apple Music Identifier in it, we can query the search API as follows:

## Build Content Resolver

The metadata content resolver is used to store metadata of the entire catalog present in an external service’s database.  
Currently, ListenBrainz has such a resolver for Spotify. As a part of this project, I intend to add a similar content resolver for Apple Music as well.

1. Use the Apple Music API to get all storefronts (`https://api.music.apple.com/v1/storefronts`)

2. Get catalog charts for each storefront to seed metadata resolver (`https://api.music.apple.com/v1/catalog/us/charts?types=songs,albums`)

3. Get all albums of the artist (`https://api.music.apple.com/v1/catalog/us/artists/{artist_id}/albums`)

4. Get all tracks of multiple albums (`https://api.music.apple.com/v1/catalog/us/albums?ids={album_ids}`)

5. Store data in a normalized tables in a database [schema](https://github.com/metabrainz/listenbrainz-server/blob/b28e14f2843f221cd5cbe555c9eabdc50c1a6e36/admin/timescale/create_tables.sql#L143-L190) similar to spotify content resolver and set a cache expiry.

6. Before retrieving data from API, check if it exists already in database and update cache accordingly.

# Timeline

Week 1-4: Integrating Apple Music in BrainzPlayer (without OAuth), setting up controls, searching tracks and playing previews

Week 5-7: Getting Music User Token, storefront, storing it in database

Week 8-11: Build the content resolver to store Apple Music catalog metadata in ListenBrainz

Week 12-13: Buffer Period

# Other Information

### Tell us about the computer(s) you have available for working on your SoC project!

I have a Macbook pro 16 inch with 2.3 GHz 8 core intel i9 (9th gen)  
, AMD Radeon Pro 5500M 4 GB, 16 GB 2667 MHz DDR4 and 1 TB SSD.

### When did you first start programming?

Since 2011, I’ve been involved in programming using Java, and over time, I’ve had the opportunity to work on numerous projects.

### What type of music do you listen to? (Please list a series of MBIDs as examples.)

I listen to Punajbi, English and Hindi music.  
Here are MBID’s of some of my favourite artists:-

Name: Karan Aujla  
MBID: `4a779683-5404-4b90-a0d7-242495158265`

Name: Sam Smith  
MBID: `5a85c140-dcf9-4dd2-b2c8-aff0471549f3`

Name: Imagine Dragons  
MBID: `012151a8-0f9a-44c9-997f-ebd68b5389f9`

### What aspects of the project you’re applying for (e.g., MusicBrainz, AcousticBrainz, etc.) interest you the most?

Music is an essential part of my life, and I listen to it while doing everything. It is particularly crucial for me when I work out at the gym, which I do daily. As a software engineer who works on computer allot, I rely on Apple Music, and I wanted to integrate it with Listenbrainz, which supports various other platforms. Therefore, this project is a perfect blend of my favorite things.

### Have you ever used MusicBrainz to tag your files?

Not much but I have heard allot about it from my friends at univeristy.

### Have you contributed to other Open Source projects? If so, which projects and can we see some of your code?

I have previously made contributions to ListenBrainz, as well as to an open-source project called Capstone Dashboard which is available on GitHub at Capstone-dashboard-open-UofA(`https://github.com/open-uofa/capstone-course-dashboard`).

### What sorts of programming projects have you done on your own time?

I am conducting NLP research utilizing transformers, and have also applied my knowledge in PCGML and unity to develop a no-code platform for creating 2D games without programming. In addition, I have completed contract work involving MERN techstack to deliver websites, created my own portfolio using React, and have dabbled in Flutter to develop apps for leisure. Additionally, I have experimented with Flask. For more examples of my work, please visit my Github profile.

---

<div class="post-metadata">

### Author: ![lucifer](https://community.metabrainz.org/letter_avatar_proxy/v4/letter/l/ad7895/32.png) [@lucifer](https://community.metabrainz.org/u/lucifer)
#### Post date: [April 2, 2023, 12:50pm UTC](https://community.metabrainz.org/t/gsoc-proposal-for-integrating-apple-music-with-listenbrainz/631010/2 "2023-04-02T12:50:47Z")

</div>

Hi!

Thanks for the proposal. It is detailed and shows good research of the various APIs that need to be used in the project. I can think of 2 gaps in it:

1. In spotify, each track is associated with a list of regions (markets) in which the track is available. But to query a track we do not need to specify a region. This is not the case for Apple Music, where the region (storefront) is mandatory to query any catalog resource. It will require a bit of investigation to work out how much the catalogs vary across regions, whether the same track has different ids in different regions etc. Depending on the result, we may need an extra storefront column or an extra relation table in the normalized schema.

2. The Music-User-Token can be retrieved from MusicKit and sent to the backend but there is no way to refresh the token. MusicKit’s documentation hints that these tokens are expiring which kind of puts us in a spot of bad UX. The documentation doesn’t mention how long the tokens last though so again it will need some investigation to proceed. Further, @mr_monkey needs to be involved in this discussion and he won’t be around for a few days.

Therefore, I guess its fine to leave these both aspects open-ended for now. But if you do have some thoughts, feel free to add those in your proposal.
