GSOC-2023 Control Remote Playback in the Spotify App from ListenBrainz:

Personal Information:

Name: Susmita Bhattacharya
Github: SB2318
IRC UserName: sb2318
Country Of Residence: India
Timezone: IST(UTC +5:30)
Expected Working Hours: 31 hours/week
Email: bhattacharyas161@gmail.com

GSOC-2023 Control Remote Playback in the Spotify App from ListenBrainz:

Expected Project Area: SettingsActivity, ListenViewModel, RemotePlayerActivity, etc.

Tech-Stack: Android, Android Jetpack, Kotlin, REST APIS

Project Proposal:

As the name suggest The project aims to give a feature to the application, with the help of which we can control the playback in the Spotify App from Listenbrainz application.

When user click on a listen in the ListenBrainz application, we inform the Spotify to turn on and play that song for us.

This feature is the extend from on the existing available Spotify Feature of the application.

Yes, the Spotify API is already integrated in the application. In the settings section there is also an option by which an user can enable submitting listens from Spotify.

So, The aim of my proposal is to extend the feature in this way, so that If “Enable submitting listens from Spotify” is enabled, then when a user clicks on a music to listen we inform the Spotify to turn on and play that song for the User.

we can store the auth token or something as a flag in the local storage which indicates that Spotify-listening enabled in our device. Based on which we can move furthur.

Deliverables:

  • Fixing The Existing Bugs on Spotify.

  • Remote Player Integration

  • User can control the play track of Spotify from ListenBrainz

  • Additonal Support:

    • Listen Submitter feature added
    • Revamp the UI (If needed)

Implementation:

We will going to use Spotify Android SDK. With the help of this SDK, we can achieve this amazing feature within our ListenBrainz application.

The SDK consists of two libraries:

Authorization Libraries:

This library is responsible for authorizing our app and fetching the access token that later can be used to send requests to the Spotify Web API.

App Remote Libraries:

The app remote module allows a user to control playback in the Spotify app after the user logs in with the access token.

Step 1: Integrate Spotify android SDK into our application. (From here we can get our Spotify-client-id and also can fix a redirectUrl)

This is already implemented in the application.

What is redirect-uri?

To redirect a URI that the Spotify Accounts Service will use to callback to our app after authorization. To access the Spotify app from our application user needs to complete the auth flow

Step 2: Complete the auth flow to allow the app to use Spotify on their behalf.

For these, we will be going to use com.spotify.sdk.android.auth.AuthorizationClient

This client provides two versions of authorization:

(I) Single Sign-on using Spotify Android Application:

If Spotify is installed on the device, the SDK will connect to the Spotify client and try to fetch the authorization code/access token for the current user. Since the user is already logged into Spotify they don’t need to fill in their username and password. If the SDK application requests scopes that have not been approved, the user will see a list of scopes and can choose to approve or reject them.

If Spotify is not installed on the device, SDK will open a dialog and load Spotify Accounts Service into a Custom Tab. Users will have to enter their username and password to login to Spotify. They will also need to approve any scope of the SDK application requests that they haven’t approved before. After the authorization flow is completed, the result is returned to the activity that invoked the AuthorizationClient.

We have to associate one LoginActivity (From spotidy.auth package) which need to registered in the AndroidManifest.xml file.

 <activity            
android:name="com.spotify.sdk.android.auth.LoginActivity"            
android:theme="@android:style/Theme.Translucent.NoTitleBar">       
 </activity>

Code Called from our particular activity:

private static final int REQUEST_CODE = 1337;
final AuthorizationRequest request = new
AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.TOKEN,
REDIRECT_URI)
.setScopes(new String[]{"user-read-private", "playlist-read",
"playlist-read-private", "streaming"})
.build();
AuthorizationClient.openLoginActivity(this, REQUEST_CODE, request);

Code called from a fragment:

//To start LoginActivity from a Fragment:
Intent intent =
AuthorizationClient.createLoginActivityIntent(getActivity(), request);
startActivityForResult(intent, REQUEST_CODE);

Close LoginActivity:


AuthorizationClient.stopLoginActivity(getActivity(), REQUEST_CODE);

OnActivityResult:

protected void onActivityResult(int requestCode, int resultCode, Intent
intent) {
super.onActivityResult(requestCode, resultCode, intent);
// Check if result comes from the correct activity
if (requestCode == REQUEST_CODE) {
AuthorizationResponse response =
AuthorizationClient.getResponse(resultCode, intent);
switch (response.getType()) {
// Response was successful and contains auth token
case TOKEN:
// Handle successful response
String token = response.getAccessToken();
break;
// Auth flow returned an error
case ERROR:
// Handle error response
break;
// Most likely auth flow was cancelled
default:
// Handle other cases
}
}
}

(II) Opening Spotify Accounts Service in a web browser.

In this scenario, the SDK creates an intent that will open the browser. Authorization takes part in the browser (not in the SDK application). After authorization is completed browser redirects back to the SDK app.

Code called from the activity:

// Code called from an activity
final AuthorizationRequest request = new
AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.TOKEN,
REDIRECT_URI)
.setScopes(new String[]{"user-read-private", "playlist-read",
"playlist-read-private", "streaming"})
.build();
AuthorizationClient.openLoginInBrowser(this, request);

AndroidManifest.xml

// The activity that should process the response from auth flow
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance" >
<intent-filter>
// Any other intent filters that this activity requires
</intent-filter>
// An intent filter that will receive the response from the
authorization service
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
// this needs to match the scheme and host of the redirect uri
<data
android:host="callback"
android:scheme="ourcustomprotocol"/>
</intent-filter>
</activity>

(In the onActivityResult section, we can store the auth token or something as a flag in the local storage which indicates that Spotify-listening enabled in our device. Based on this we will move furthur.)

Bug, which we can face,

"message": "Explicit user authorization is required to use Spotify. The user has tocomplete the auth-flow to allow the app to use Spotify on their behalf"

Step 3: Then we need to set up the environment for Spotify Remote Player API.

(I) Initialize SpotifyRemote class from com.spotify.android.appremote.api
(II) Before going further we need to check whether spotify authentication is done or not.

if (done){
// Build Connection Params
ConnectionParams connectionParams = new ConnectionParams.Builder(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
.showAuthView(true)
.build();
// Connect with SpotifyRemote
SpotifyAppRemote.connect(this, connectionParams, new
Connector.ConnectionListener(){
@Override
public void onConnected(SpotifyAppRemote appRemote) {
spotifyAppRemote = appRemote;
Log.d("MainActivity", "Connected! Yay!");
// Now we can start interacting with App Remote
connected();
}
@Override
public void onFailure(Throwable error) {
Log.e("MainActivity", error.getLocalizedMessage());
}
});
}

Step 4: Interaction with Spotify

Here is the code example. (Some codes are present in the application also)

if(spotifyAppRemote != null) {
spotifyAppRemote.getPlayerApi()
.play("spotify:playlist:37i9dQZF1DX7K31D69s4M1");
}

Now this is static data, or we can say as of now we passing a static id of a playlist.
So, in the next part, we have to make it dynamic.

Now this is static data, or we can say as of now we passing a static id of a playlist. So, in the next part, we have to make it dynamic.

Step 5: Integration of Remote Player with Brainz Player

First of all we have to create an application that we already covered in the authentication phase. All we need to do is, we have to store the authentication token,(which we received inside onActivityResult() after successful authentication) in our local storage.

AuthorizationClient.getResponse(resultCode, intent);
switch (response.getType()) {
// Response was successful and contains auth token
case TOKEN:
// Handle successful response
String token = response.getAccessToken();
break;
// Auth flow returned an error
case ERROR:
// Handle error response
break;
// Most likely auth flow was cancelled
default:
// Handle other cases
}
}
}

(ii) Now, we can create the required model and with the help of Retrofit or Volley, we can
get the data from spotify, by creating a Service class for every API.
These are the following endpoints.

  1. Get Current user profile
    2.Fetch recently played songs

We can also use some other endpoints according to our requirements.
Some other examples of endpoints are:
(i) Adding a song to our favorite song.

Another Support:

S6: Track Listening History From Remote Player:

Feature Overview: Users listen to songs from Spotify and youtube, and they want to see all the songs they listen to over a while, to know the total number of songs they listen to, and see what songs they listen to from different platforms. If users want to see all the songs they listen to over a while, with this feature they will be able to do it. They are also able to see what kind of songs they recently played on spotify or youtube. (We have to make a separate screen for this.)

Spotify:

We can implement this feature by using “Fetch Recently Playedsongs” from Spotify

Youtube:

Before we set up with youtube, a user needs to complete the following set up.

  • Must have a google account.

There are different types of resources available, that we can interact with the help of Youtube api.

One such kind of resource is activity: Contains information about an action that a particular user has taken on the YouTube site. User actions that are reported in activity feeds include rating a video, sharing a video, marking a video as a favorite, and posting a channel bulletin, among others.

Another resource is playlist:

Represents a single YouTube playlist. A playlist is a collection of videos that can be viewed sequentially and shared with other users. From these two resources, we can get our required information. And Youtube API is already integrated in this application.

S7: Revamp UI

S8: Write Unit test cases.

TimeLine: (Week Plan Details):

Pre-Community Bonding Period:(7 April -3 May):


  • Will try to understand the project flow, especially the area where I am going to contribute.
  • Will try to create some PR by giving some new small features or fixing some small bugs.
  • Will start to work mainly in the spotify section, trying to find out how spotify affects the whole application and also how can I attach my code to the application properly.

Community Bonding Period (4 May -25 May) (Week 1- Week 3):


  • Will start working in my field, step by step trying to cover the work.

  • Communicate with my respective mentor. Try to figure out the listener in the application, which listens for the Spotify authentication.(We can send the user for spotify authentication, when they enable the spotify listening service in the SettingsActivity.)

  • Target : (i)Step 1 and Step 2 of the implementation
    (ii) Bug fixing (This is an existing Bug of the application.)

Offline Coding Period Begins (26 May to 15 June) (Week 4 -Week 6):


  • Integration of Remote player (Spotify API) with the application.
  • Clustering the requirements and endpoints with the mentor.
  • Creating model, integration of endpoint and creating service for each endpoint.
  • Fixing the ListenScreen API (if needed)
  • Target : Step 3 and 5

(Week 7-Week 8)(16 June- 29 June):


  • Interaction with Spotify Player
  • Write some Unit Tests for it. (With the guidance of the respective Mentor.)

(Week 9 -Week 11) (30 June- 20 July):


  • Start working for Track Listening History From Remote Player.
  • Create a figma design for it with the approval and guidance of the Mentor.
  • Logic building for fetching data from the online platform like Spotify and Youtube which are currently associated with the application.
  • Implementation of the logic

(Week 12 - Week 13)(21 July - 2 August):


  • Write some UI Tests for Listen Submitter.

(Week 14-Week 16)(3 August - 20 August):


  • Revamp UI
  • Sum up all the work
  • Fix Bugs

This is only the initial work plan. (may be change later with the guidance of the respective Mentor.)

Committed Time: 31 hours per week

1 Like