×

Utilising Nokia MixRadio API - Music Explorer example application

This article demonstrates how Nokia MixRadio API can be utilised, using a sample application, Music Explorer, as an example. The article begins with an introduction to Music Explorer itself and then proceeds to describing the steps taken to integrate Nokia MixRadio API into the application. You can download the Music Explorer application (with full source code for reference) from GitHub.

Music Explorer example demonstrates the use of Nokia MixRadio API together with standard Windows Phone 8 audio features to create an immersive music experience. It takes advantage of ​Nokia MixRadio API features such as searching for artists by name, requesting top artists and new releases, and launching Nokia MixRadio application from within another application to play mix radio or show artist and product information.

Instead of being just "Nokia MixRadio Lite" type of browser for viewing artists and products, Music Explorer integrates Nokia MixRadio API features with local music in the device in a number of educated ways. Favourite artists are ordered according to the most played artists in the device, recommended list is ordered by how many times an artist is found to be similar to your favourites, and you can also play the local songs from your favourite artists.

User interface and design

The main panorama of the Music Explorer shown below contains six items: favourites, recommended, what's new, who's hot, genres, and mixes.

Figure 1. Main panorama

Favourites shows 20 most played artists in the device, and the artist image is retrieved using Nokia MixRadio API. Recommended shows artists which are determined by Nokia MixRadio API to be similar to your favourite artists and the list is ordered by how many times an artist is found to be similar to your favourites. What's new and who's hot simply show 10 latest products and 10 top artists in Nokia MixRadio service. Genres and mixes show corresponding lists of available genres and mixes in Nokia MixRadio service. The lists are country specific, and genre and mix names are even localized. For this reason locationing services are used to obtain device's current location.

Another main component of the user interface is the artist pivot shown below, reached by selecting an artist from favourites, recommended, who's hot, or from genre sub page shown later. Artist pivot can be used to find out what kind of products are available in Nokia MixRadio service for a certain artist. It is not possible to buy products using Nokia MixRadio API so interaction with a product takes the user to Nokia MixRadio application where the product can be bought. While in artist pivot, it is also possible to launch artist mix in Nokia MixRadio or to listen to local tracks stored in the device.

Figure 2. Artist pivot

Nokia MixRadio API can be used to launch Nokia MixRadio app from the context of a different application. Nokia MixRadio app can be launched to a specified artist or product view or it can be launched directly to play a selected radio mix. A note symbol (as shown above in artist pivot or below in radio mixes) is shown in Music Explorer whenever interaction with a specific item takes the user into Nokia MixRadio app. Below are shown genre and radio mixes sub pages, opened when user selects a genre or mix from genres or mixes on the main panorama.

Figure 3. Genre and radio mix sub pages

Architecture and implementation

Music Explorer is a quite simple application that implements the Model-View-ViewModel (MVVM) design pattern. MVVM is a way to separate data from user interface and is widely used in Windows Phone 8 application development. In the app, the Models (data) are C# classes, and the View (user interface) is a collection of PhoneApplicationPages filled with Windows Phone 8 controls. The MainViewModel, which is the link between the Models and the View, is also a C# class. It is set as the DataContext for all the application pages to enable data binding. To learn more about MVVM, please turn to this MSDN article and the list of links in the section See Also in the bottom of that page. See more detailed architectural description of Music Explorer in code examples code examples.

Here's a table of the most significant APIs used by Music Explorer as well as their capability requirements:

API Name Description Capabilities (specified in WMAppManifest.xml)
Location API Windows Phone Location APIs under the namespace Windows.Devices.Geolocation are used to determine the device's current location. ID_CAP_LOCATION
Maps API ReverseGeocodeQuery under the namespace Microsoft.Phone.Maps.Services is used to obtain a location specific country code for initializing Nokia MixRadio connection to current location. ID_CAP_MAP
XNA Media API Media APIs in namespace Microsoft.Xna.Framework.Media, especially classes MediaLibrary and MediaPlayer, are used to get a list of tracks stored locally in device with artist and play count information, as well as to shuffle and play locally available tracks of an artist in ArtistPivotPage. ID_CAP_MEDIALIB_AUDIO ID_CAP_MEDIALIB_PLAYBACK
Nokia MixRadio API Used to get locale-dependent and up-to-date information on popular artists and new releases, available genres and mix list, linking locally stored tracks in the device correctly to the artists available in Nokia MixRadio service and to launch Nokia MixRadio application into various states (artist, product, mix) directly from Music Explorer. ID_CAP_NETWORKING

Following services provided by Nokia MixRadio API are used in Music Explorer:

Class Method Used to...
CountryResolver CheckAvailability check the availability of Nokia MixRadio service in a specified region/country.
MusicClient Constructor initialize Nokia MixRadio API to a specific region/country.
SearchArtists link locally stored tracks in the device correctly to the artists available in Nokia MixRadio service, including getting images and additional information for local artists.
GetTopArtists fill out who's hot main panorama item with the most popular artists in current region/country.
GetNewReleases fill out what's new main panorama item with the latest releases in current region/country.
GetGenres fill out genres main panorama item with available genres in current region/country.
GetTopArtistsForGenre fill out genre page with top artists in a selected genre in current region/country.
GetArtistProducts fill out available products (tracks, albums, singles) from a selected artist in artist pivot.
GetSimilarArtists fill out recommended panorama item with artists similar to artists in favourites panorama item. Also used to fill out similar artists for a specific artist in artist pivot.
GetMixGroups fill out mixes panorama item with available mix groups in current region/country.
GetMixes fill out radio mixes page with radio mixes in a selected mix group.
PlayMixTask Show launch Nokia MixRadio application to play artist mixes and radio mixes.
ShowArtistTask Show launch Nokia MixRadio application to show artist page for a specific artist.
ShowProductTask Show launch Nokia MixRadio application to show product page for a specific product.

Prerequisites for Nokia MixRadio API

In order to use Nokia MixRadio API, the application must have a unique app ID and app token (unless using launchers only). These can be obtained by visiting ​API registration page and requesting credentials for Nokia MixRadio API. The app ID for Music Explorer are specified in MusicApi.cs:

namespace MusicExplorer
{
    ...

    public class MusicApi
    {
        // Constants
        public const string MUSIC_EXPLORER_APP_ID = "music_explorer_private_app_id"; // real app id not shown here

        ...
    }
}

Windows Phone 8 application must also add reference to the actual Nokia MixRadio API client, which in turn requires a reference to JSON.Net library to be added to the application. Instructions on how to add necessary references to the solution can be found from README.md in the Music Explorer project.

Localizing the Nokia MixRadio API

Before making any requests to Nokia MixRadio API, Music Explorer checks for Nokia MixRadio availability in current location, which in turn is resolved using Windows Phone Location API. By default, Nokia MixRadio API uses (and checks) phone Region settings with each API call made. This allows users to see relevant, and partly localized, country specific information. This can be seen in the image of main panorama at the top of the page, showing genres and mixes available in Finland, as well as Finland's most popular artists at the moment. These lists would contain different items if another valid country code (such as de for Germany or gb for United Kingdom) was used to initialize the Nokia MixRadio API.

using Nokia.Music;

...

namespace MusicExplorer
{
    ...

    public partial class MainPage : PhoneApplicationPage
    {
        ...

        private CountryResolver resolver = null;

        ...

        private void ReverseGeocodeQuery_QueryCompleted(
            object sender,
            QueryCompletedEventArgs<IList<MapLocation>> e)
        {
            if (e.Error == null)
            {
                if (e.Result.Count > 0)
                {
                    MapAddress address = e.Result[0].Information.Address;
                    string twoLetterCountryCode =
                        CountryCodes.TwoLetterFromThreeLetter(address.CountryCode);
                    InitializeNokiaMusicApi(twoLetterCountryCode);
                }
            }
        }

        private void InitializeNokiaMusicApi(string twoLetterCountryCode)
        {
            if (resolver == null)
            {
                resolver = new CountryResolver(MusicApi.MUSIC_EXPLORER_APP_ID);
            }

            if (twoLetterCountryCode != null)
            {
                resolver.CheckAvailability((Response<bool> response) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        if (!response.Result)
                        {
                            MessageBox.Show("Sorry, Nokia MixRadio is not available in this locale.");
                            twoLetterCountryCode = null;
                        }
                    });
                },
                twoLetterCountryCode.ToLower());
            }

            // If country code is null, phone region settings are used
            App.MusicApi.Initialize(twoLetterCountryCode);

            ...
        }
    }
}

Creating the client

In Music Explorer application the communication with Nokia MixRadio API, with the exception of CountryResolver usage described above, is encapsulated into MusicApi class for easy reference. All requests to Nokia MixRadio service are made using MusicClient class, and therefore the next step after confirming Nokia MixRadio availability is creating MusicClient in Initialize method of MusicApi.

using Nokia.Music;
using Nokia.Music.Tasks;
using Nokia.Music.Types;

...

namespace MusicExplorer
{
    ...

    public class MusicApi
    {
        // Constants
        public const string MUSIC_EXPLORER_APP_ID = "music_explorer_private_app_id"; // real app id not shown here

        // Members
        private MusicClient client = null;
        private bool initialized = false;

        ...

        public void Initialize(string countryCode)
        {
            // Create a music client with correct AppId
            if (countryCode == null || countryCode.Length != 2)
            {
                client = new MusicClient(MUSIC_EXPLORER_APP_ID);
            }
            else
            {
                client = new MusicClient(MUSIC_EXPLORER_APP_ID,
                                         countryCode.ToLower());
            }
            initialized = true;
        }

        ...
    }  
}

Making requests

Requests to Nokia MixRadio service can be sent after creating a localized MusicClient instance. For example, the GetTopArtists method of MusicApi requests 10 most popular artists of Nokia MixRadio service (in the country the MusicClient was initialized with) and populates the TopArtists of the MainViewModel accordingly. The main panorama's who's hot panorama item uses data binding to display the contents of the TopArtists in the user interface. As the process with other requests (new releases, genres, etc.) is almost identical to requesting 10 most popular artists, they are not described in this article. See the project source of Music Explorer for exact implementation reference.

namespace MusicExplorer
{
    ...

    public class MusicApi
    {
        ...

        // Members
        private MusicClient client = null;
        private bool initialized = false;

        ...

        public void GetTopArtists()
        {
            if (!initialized)
            {
                return;
            }

            client.GetTopArtists((ListResponse<Artist> response) =>
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // Use results
                    if (response != null && response.Result != null && response.Result.Count > 0)
                    {
                        App.ViewModel.TopArtists.Clear();

                        // Insert a place holder for title text
                        App.ViewModel.TopArtists.Add(new ArtistModel()
                        {
                            Name = "TitlePlaceholderwho's hot",
                            ItemHeight = "110",
                            ItemWidth = "450"
                        });

                        foreach (Artist a in response.Result)
                        {
                            App.ViewModel.TopArtists.Add(new ArtistModel()
                            {
                                Name = a.Name,
                                Country = CountryCodes.CountryNameFromTwoLetter(a.Country),
                                Genres = a.Genres[0].Name,
                                Thumb100Uri = a.Thumb100Uri,
                                Thumb200Uri = a.Thumb200Uri,
                                Thumb320Uri = a.Thumb320Uri,
                                Id = a.Id,
                                ItemWidth = "205",
                                ItemHeight = "205"
                            });
                        }
                    }

                    if (response != null && response.Error != null)
                    {
                        ShowNokiaMusicApiError();
                    }
                    HideProgressIndicator("GetTopArtists()");
                });
            });
            ShowProgressIndicator("GetTopArtists()");
        }

        ...
    }
}

Nokia MixRadio launchers

The following method from Music Explorer's MusicApi shows how simple it is to launch Nokia MixRadio application to play artist mix. Nokia MixRadio app can be launched just as easily into a product or artist state using Nokia MixRadio API. Some of the launcher methods in Nokia MixRadio API require unique ids of artists, mixes and products. These ids are received in responses from Nokia MixRadio API's other services.

using Nokia.Music;
using Nokia.Music.Tasks;

...

namespace MusicExplorer
{
    ...

    public class MusicApi
    {
        ...
          
        public void LaunchArtistMix(string artistName)
        {
            ...

            PlayMixTask task = new PlayMixTask();
            task.ArtistName = artistName;
            task.Show();
        }

        ...
    }
}

Local music as a starting point

The list of artists in main panorama's favourites item is created in LoadData method of MainViewModel. Comments in the code describe the steps taken to create the list.

using Microsoft.Xna.Framework.Media;

...

namespace MusicExplorer.Models
{
    ...

    public class MainViewModel : INotifyPropertyChanged
    {
        ...

        public ObservableCollection<ArtistModel> LocalAudio { get; private set; }

        ...

        MediaLibrary mediaLib = null; // For accessing local artists and songs

        ...

        public MainViewModel()
        {
            LocalAudio = new ObservableCollection<ArtistModel>();

            ...

            // Insert a place holder for title text
            LocalAudio.Add(new ArtistModel() {
                Name = "TitlePlaceholder",
                ItemHeight = "110",
                ItemWidth = "450"
            });

            ...
        }

        ...

        public void LoadData()
        {
            mediaLib = new MediaLibrary();
            int totalTrackCount = 0;
            int totalArtistCount = 0;

            foreach (Artist a in mediaLib.Artists)
            {
                if (a.Songs.Count <= 0) continue; // Skip artists without tracks
                string artist = a.Name;
                int trackCount = a.Songs.Count;
                int playCount = 0;

                // Check the play count of artist's tracks
                foreach (Song s in a.Songs)
                {
                    playCount += s.PlayCount;
                }

                // Insert artist before less played artists...
                bool artistAdded = false;
                for (int i = 1; i < LocalAudio.Count; i++) // Index 0 reserved for title item
                {
                    if (Convert.ToInt16(LocalAudio[i].PlayCount) < playCount)
                    {
                        this.LocalAudio.Insert(i, new ArtistModel()
                        {
                            Name = artist,
                            LocalTrackCount = Convert.ToString(trackCount),
                            PlayCount = Convert.ToString(playCount)
                        });
                        artistAdded = true;
                        break;
                    }
                }

                // ...Or add artist to the end of the list if it's least played
                if (artistAdded == false)
                {
                    this.LocalAudio.Add(new ArtistModel()
                    {
                        Name = artist,
                        LocalTrackCount = Convert.ToString(trackCount),
                        PlayCount = Convert.ToString(playCount)
                    });
                }

                totalTrackCount += trackCount;
                totalArtistCount++;
            }

            // Continue with only the top 20 favourite artists
            int removeIndex = App.ViewModel.LocalAudio.Count - 1;
            while (removeIndex > 20)
            {
                App.ViewModel.LocalAudio.RemoveAt(removeIndex);
                removeIndex--;
            }

            // Divide local artists into two "size categories"
            foreach (ArtistModel m in App.ViewModel.LocalAudio)
            {
                if (m.Name.Contains("TitlePlaceholder")) continue;
                if (Convert.ToInt16(m.LocalTrackCount) > (totalTrackCount / totalArtistCount))
                {
                    m.ItemHeight = "205";
                    m.ItemWidth = "205";
                }
                else
                {
                    m.ItemHeight = "102";
                    m.ItemWidth = "205";
                }
            }

            if (LocalAudio.Count <= 1) // There's always the favourites title
            {
                NoFavouritesVisibility = Visibility.Visible;
            }
            else
            {
                NoFavouritesVisibility = Visibility.Collapsed;
            }

            this.IsDataLoaded = true;
        }

        ...
    }
}

After creating the list of local favourite artists, an artist search is made using Nokia Mix Radio API to get a list of similar artists for each favourite artist. This list is then ordered based on how many times a specific artist is found to be similar to the favourites. In addition, artists with tracks stored locally in the device are removed from the list, as the idea is to present and promote interesting new artists to the user instead of artists which the user is already familiar with.


Last updated 19 March 2014

Back to top

×