Gaana Music Player
Gaana Music Player
Table of Contents
1 . Overview
2 . Prerequisites
3 . Introduction
6. Logging music
7. MiniPlayerFragment
8. WORKFLOW
This Document will help newcomers to get into pace with the code. This document mainly
focuses on the main idea behind the working and the architecture of the Gaana music player
across different sections Radio,Podcast,Normal Song.
2.Prerequisites
Some of the prerequisites are concepts of activities, fragments, viewmodels ,services and Volley
library. And of course code access.
Create a Bitbucket account and ask your manager to provide the code access. Get Admin
access if possible . IT team provides this one.
3.Introduction
Main landing activity is GaanaActivity which has a bottom bar for navigation and the main home
screen is DynamicHomeFragment which lists all the songs trending albums,top songs etc. It
also contains a mini player on top of the bottom bar once you play any song.
As we can see in the UI of the music player, we have certain ui elements like artwork,lyrics
viewer, song name, artist, hashtag, and player controls( shuffle,next,prev,play,pause,repeat).
For understanding UI better, we have divided the view into top and bottom sections.
Top section contains artwork/clip(hotshot)/video of the song, lyrics viewer, song info.
Bottom section contains player controls (shuffle,next,prev,play,pause,repeat) & title,
hashtags,downloads,likes.
This fragment is the main player container for playing any song,podcast,radio. TrackId of the
current song is passed to get the meta of the song to be played. All the
responsibilities/functionality of this fragment is managed by a helper class PlayerManager.
4.1.1 PlayerCardRvAdapter
This recyclerview adapter class is responsible for displaying the top section of the player UI. As
we discussed, the top section can have artwork/clip(loop video like hotshot) /video of the song.
This adapter class accordingly creates and binds views.
4.1.2 PlayerControls
This class contains the bottom section of the view which we talked about above. This class
contains controls like shuffle,next,prev,play,pause,repeat,seekbar & title,
hashtags,downloads,likes.
PlayerControlsView -
This class creates the view & functionality for the player controls like
seekbar,play/pause,next,prev,shuffle,repeat.
This creates view according to the section we are listening to - podcast, radio,normal advt,song
TrackDetailsPlayerView -
This class creates the view & functionality for the track details,download,like & hashtags info of
the current song being played.
PlayerFragmentTabAdapter:
-> PlayerNextInQueueFragment
-> LyricsLrcDisplayFragment
->PLayerSimilarSectionFragment
RecyclerViewPager - > for swipeable artworks
4.1.4 PlayerLyricsView-
This class is for showing lyrics which is synced with the song seek. You can use full lyrics
screen mode view functionality as well. Encrypted lyrics are being fetched from the server and
then decrypted at our end.
5. GaanaMusicService
When we play any song, a foreground service is started (we can see a notification on the top
containing play/pause,next,prev,like,seekbar functionality.)
PlayerCommandsManager-
This class contains functions for executing Player commands from the notification.
(play/pause,seek,resume,stop,prev,next,update/remove notification)
We have defined the commands to control in PlayerConstants class in which we have defined
an enum - PlayerCommands
For starting the notification service, sendCommand function is called and specific intent is
passed which is being handled inside handleIntent method inside onStartCommand of
GaanaMusicService.
MediaPlayerEngine -
All the commands given to music service are being transferred to this class where for each and
every command a proper action is defined.
GaanaMediaPlayer-
This class prepares media player for playing a song. This class uses AbstractMediaPlayer
which in turn under the hood uses Exoplayer for playing a song.
GaanaExoPlayerTwo - this class is the one which is responsible for using exoplayer for playing
any song.
AdPlayerEngine-
This class is used for managing and playing ads.
Playing ads and then resuming the track being played.
6. GaanaLogger -
This class is used for maintaining and logging ongoing current track being played. For resuming
the track we need to save the state (position,art,name,artist etc).
For saving the state of the current track being played. Duration at which the song was stopped
and playing from that part.
OfflineLogs - save all the details locally when the network is not available and then sync these
offline logs when the network is up.
7. MiniPlayerFragment
The main landing page contains a mini player when you play any song on top of bottom section
tabs. Here we use a bounded service, GaanaMusicService for interacting with the service using
serviceconnection and Ibinder interface.
{
"language": "Hindi",
"seokey": "baby-girl-326",
"name": "Baby Girl",
"artwork": "https://a10.gaanacdn.com/images/albums/99/3439699/crop_175x175_3439699.jpg",
"atw": "https://a10.gaanacdn.com/gn_img/albums/ZaP374RWDy/aP37eqa6bD/size_m.jpg",
"entity_id": "32116657",
"entity_type": "TR",
"artwork_medium":
"https://a10.gaanacdn.com/images/albums/99/3439699/crop_480x480_3439699.jpg",
"favorite_count": 17708,
"premium_content": "0",
"user_favorite": 0,
"entity_map": {
"country": "1",
"artist": [
{
"artist_id": "362437",
"name": "Guru Randhawa",
"seokey": "guru-randhawa"
},
{
"artist_id": "1380321",
"name": "Dhvani Bhanushali*˜#$#˜*ध्वनि भानश
ू ाली",
"seokey": "dhvani-bhanushali"
},
{
"artist_id": "287639",
"name": "Vee",
"seokey": "vee"
}
],
"download_enabled": 0,
"play_ct": "3M+",
"operator": [
{
"name": "JIO",
"st": 1590019200000,
"et": 1747785600000,
"message": "Baby Girl",
"short_code": "56789"
}
],
"total_downloads": 31160,
"duration": "207",
"sap_id": "",
"content_source": 1,
"parental_warning": 0,
"operators": [
{
"name": "JIO",
"st": 1590019200000,
"et": 1747785600000,
"message": "Baby Girl",
"short_code": "56789"
}
],
"stream_type": "rtmp",
"rest_lev": "0",
"lyrics_type": "lrc",
"is_local": "0",
"lyrics_url": "https://a10.gaanacdn.com/gn_img/media/enc/Ly9Q4RQRyO.lrc",
"artwork_large": "http://a10.gaanacdn.com/images/albums/99/3439699/crop_480x480_3439699.jpg",
"av_ad": 0,
"ppd": 0,
"album": [
{
"album_id": "3439699",
"name": "Baby Girl",
"album_seokey": "baby-girl-hindi"
}
],
"mobile": "1",
"secondary_language": "Hindi",
"isrc": "INS182006352",
"youtube_id": "",
"is_most_popular": 0,
"trivia_info": "",
"vgid": "9lN1K",
"modified_on_solr": "1601863850000",
"stream_url": {
"medium": {
"message":
"d0def2d4715a371c43f195988d60b1379a8a891898d8aafc044dc59bf367bbb659904585acab9dd64eb04
4c4c1ac2d863502c4f1da11eead27c5fd50045aa1c3538196214561cdaf761e648c98a3a62f8ce1d5b707d2
ed767370d85c25620fb154a8d05f5d5043c03f01703a7a181536e8cdd171201d7745f9ca1e32cdaf0c01964
2ff42fe35c6a4a154b61c9a45db9e1c90c637620d0ad120a41ef25b80cfd8f3b2f96df26bfb7c498d45feaad3
664ba1f1970d4c499339b5dfdaa10c03a842d0f75c8ba1942f9fb2cf9a796fb97f58b8b68e2da244d627ee35
742ea6a0f9ebfe0134976cdf35133569826bb46a039522138a809108ad7128ed8759f10dfe09d09ed72d00
bf6a12ffe5d1a3b8eec428",
"bitRate": "64",
"expiryTime": 1602062466
},
"high": {
"message":
"d0def2d4715a371c43f195988d60b1379a8a891898d8aafc044dc59bf367bbb659904585acab9dd64eb04
4c4c1ac2d863502c4f1da11eead27c5fd50045aa1c3cc87f87137993ba2fde4b84b9e67aa198ce1d5b707d2
ed767370d85c25620fb154a8d05f5d5043c03f01703a7a181536e8cdd171201d7745f9ca1e32cdaf0c01964
2ff42fe35c6a4a154b61c9a45db9e1c90c637620d0ad120a41ef25b80cfd8f3b2f96df26bfb7c498d45feaad3
664ba8f27b37b4f5e5169c4b0e9c630828845acda0ab5768c26bf10844f8a34ec0bfa3c772a8a9dc65187d3
a11272d2da8cafe8d8b3a7cb27d22ce3c38c365ab5826989e046a24c79bd32b31f8266810f1a0ce3beb789
97c819de63de6fe0a5410ba",
"bitRate": "96",
"expiryTime": 1602062466
},
"auto": {
"message":
"d0def2d4715a371c43f195988d60b1379a8a891898d8aafc044dc59bf367bbb659904585acab9dd64eb04
4c4c1ac2d863502c4f1da11eead27c5fd50045aa1c3e83a89b6d74541691501d992c5200efcc88ff32b3733f
c3a7f8f397d327225abf4e1bb8fd447aee45731b1c0f76f7667e953dcccc789028b2241e225c11a8e0fc2370
6ea0a3cc4af3bd9c90b6f42e50508145cd01aa7a30f2f6b06d148b410ac8df9abcf3a6cadd59d44660f2eb10
5129f4ba25fd715a2936587f9c24d9ab5ef2fce3ca08a833b96dc9cdc879b460ae634762dd6951721bdbbc4
3c60d841322ffeccbaf6e2d0cee90aaccbc596247d335339e327e954cc6f5c73323f46cb629930df764846e0
89b342f7be801d243443ad80d51f3a7c8b688d8bf4a6581b4407c63f5d2e4127ba0d90977ab6f3659763",
"bitRate": "",
"expiryTime": 1602062466
}
}
}
}
8. WORKFLOW:
9. CODE FLOW & WORK FLOW (Binding all components together)
When we try to play any song, all the tracks in that queue are passed to the PlayerManager
which manages it. PlayerManager passes the current track to be played (passes the first song
of the current track list) to the MiniPlayerFragment.
PlayerCommands{
NONE(0),
PLAY(1),
PLAY_TRACK(2),
PAUSE(3),
PLAY_PAUSE(4),
RESUME(5),
STOP(6),
PLAY_STOP(7),
PLAY_PREVIOUS(8),
PLAY_NEXT(9),
SEEK_TO(10),
HANDLE_ERROR(11),
UPDATE_NOTIFICATION(12), // Added in Rev. 416
REMOVE_NOTIFICATION(13), // Added in Rev. 416
CHANGE_STREAMING_QUALITY(14), // Added to change streaming quality in runtime
FETCH_CF_TRACKS(15),
CANCEL_CF_SCHEDULER(16),
FAVORITE_TRACK(17), //Added in 7.7.9 - (Un)Favorite Track
CHANGE_SONG_MODE(18), // Added in 8.0.4
PLAY_FORWARD(19),
PLAY_BACKWARDS(20),
PLAYER_SPEED(21),
RELEASE_ADS_LOADER(22),
SKIP_FOREGROUND_ADS(23),
RELEASE_SECONDARY_PLAYER(24);
}
If we want to interact and send specific command to the service, we can use the
PlayerCommandsManager class and call respective functions.
GaanaMediaUriProvider class provides streaming urls for tracks to be played via exoplayer.