AskNavidrome Alexa Skill Documentation

AskNavidrome is an Alexa skill which allows you to play music hosted on a SubSonic API compatible media server, like Navidrome.

This allows to you stream your own music collection to your Echo devices without the restrictions you would normally face with regular streaming services like Amazon Music or Spotify. AskNavidrome allows you to:

  • Skip backwards and forwards in your current queue or playlist without limitation.

  • Avoid paying subscription costs.

  • Avoid being forced to listen to adverts at regular intervals.

  • Actually use the music collection you have already paid for!

  • Run the service on a PC directly or inside a Docker container.

This skill was inspired by AskSonic, however AskSonic was missing two features I required, the ability to play playlists and the ability to play an individual song. Instead of contributing to that project I have opted to create a new skill based on the Alexa Skills Kit SDK for Python as this has been updated more recently than flask-ask which is used by AskSonic, AskNavidrome is not a replacement for AskSonic and it does not implement all of AskSonic’s features, it is however a viable alternative for those that would like a simple skill to let you stream your own music collection.

Warning

The skill requires a username and password for your Navidrome installation which is stored in clear text. As the web service needs to be publicly accessible there is a chance that this password could be compromised. Please do not use an administrative account for your Navidrome installation or a password that you use on any other service. This software is distributed under the MIT license and no warranty is provided.

Requirements

In order to use AskNavidrome you will need:

Your Music Collection

Your collection needs to have been converted to a digital format like MP3. There are many tutorials available on the web to help you do this, but do be aware that there are limitations on the types of files that Echo devices can stream. You should review these before converting your collection as if you do not meet the requirements they will need to be transcoded before your Echo device can stream them. This article explains Amazon’s Audio Stream Requirements

A SubSonic API Compatible Media Server

I use Navidrome, but you can use any flavour of SubSonic that you like. For information on getting and setting up Navidrome check out their website Navidrome. Your media server must be available on port 443 and serve requests using https with a valid TLS certificate, these are requirements dictated by Amazon and you must meet them or you will be unable to stream your collection. The media server needs to be publicly accessible from the Internet, in addition to allowing you to use this skill you will then be able to use any SubSonic API compatible mobile app to listen to your collection too.

You can get free TLS certificates from Let’s Encrypt

You can set up dynamic DNS to make your media server accessible for free with afraid.org

Tags

This may seem obvious but you need to make sure that your collection is accurately tagged with information like the artist, title, track number etc. as this is the only way that your media server can identify the music in your collection. If you need a tool to help with this have a look at MusicBrainz Picard.

An Amazon Echo Device

You need something to listen to your music on!

About the AskNavidrome Skill

AskNavidrome Overview Diagram

The skill consists of two parts, the actual Alexa skill and the web service service which allows the skill to connect to your SubSonic API compatible media server. The web service needs to have a valid TLS certificate, the easiest way to enable this is to run the web service behind a reverse proxy, the web service also needs to be publicly accessible on the Internet to allow the Alexa skill to access the service.

Supported Intents

Intent Name

Description

Example

NaviSonicPlayMusicByArtist

Play music by a specific artist

Play Where is my Mind by The Pixies

NaviSonicPlayAlbumByArtist

Play a specific album by a specific artist

Play The Blue Album by The Beatles

NaviSonicPlaySongByArtist

Play a specific song by a specific artist

Play the song Help by The Beatles

NaviSonicPlayPlaylist

Play a playlist

Play the playlist work music

NaviSonicPlayMusicByGenre

Play music with a specific genre

Play jazz music

NaviSonicPlayMusicRandom

Play a random mix of songs

Play random songs

NaviSonicPlayFavouriteSongs

Play your starred / favourite songs

Play my favourite songs

NaviSonicRandomiseQueue

Shuffle / randomise the current play queue

Shuffle the queue

NaviSonicSongDetails

Give details on the playing track

What is playing

NaviSonicStarSong

Star / favourite a song

Star this song

NaviSonicUnstarSong

Unstar / unfavourite a song

Unstar this song

The following control intents are also supported:

Due to the way that Alexa skills operate there are some limitations. Full music Alexa skills require a catalog of content to be provided and this defeats the purpose of being able to search and stream from your own server directly. Because of this a custom skill type is used along with the AudioPlayer interface, but this has some limitations in how the skill is invoked.

The following voice commands should be successful (thanks to Raul824)

  • Alexa ask Navisonic What is Playing?

  • Alexa ask Navisonic to star this song.

  • Alexa ask Navisonic to unstar this song.

  • Alexa ask Navisonic to play rock music

  • Alexa ask Navisonic to play playlist “Playlist Name”

If you have any problems with these, you can open the skill manually with Alexa, open Navisonic. Similarly this can be done when a track is playing, for example if you want to get information on the track that is playing you will need to invoke the skill and call the intent by saying the following while the track is playing:

  • Alexa, open Navisonic

  • What is playing?

Installation and Setup

Creating the AskNavidrome Alexa Skill

  1. Login to the Amazon Alexa Skills Kit Builder at https://developer.amazon.com. - You must use the same account that is set on your Echo devices.

  2. Click Create Skill

  3. Configure the skill:

    Skill Creation Step 1
    • Set Skill name to the name you wish to use to invoke the skill. This should be two words or a warning will be raised, I have found that a single word still works when testing. It can be hard to find a good skill name so feel free to experiment!

    • Set Primary locale to your locale, this must also be the locale set on your Echo device.

      Note

      The locale setting is extremely important, if the skill locale and the locale set on your Echo device do not match the skill will not work. In addition there are no error messages generated making the issue quite difficult to troubleshoot. The locale on your Echo device can be set via the Alexa Android app. Please do check the locale setting if you have trouble setting up the skill as the Alexa Skill Builder will default to your local locale, but Echo devices are set to the US locale by default. Checking this first will save you a few hours of troubleshooting!

    • Set sync locales to No

    • Choose Custom as the model.

    • Choose Provision your own as the hosting method for backend resources.

    • Click Create skill again

  4. Choose the template

    Skill Creation Step 2
    • Choose Start from Scratch

    • Click Continue with template and wait while the skill is created.

  5. Upload the intents

    Skill Creation Step 3
    • Click Interaction Model, then JSON Editor

    • Delete everything that is currently in the editor and paste in the contents of alexa.json

    • Click Save Model

  6. Configure playlists

    To be able to play your playlists you must add the name of each playlist to the playlist_names slot type. You will need to maintain the list and add additional playlist names as you create them to allow them to be played via the AskNavisonic skill.

    Skill Creation Step 4
    • Click Slot Types.

    • Click playlist_names.

    • Add and remove names as required.

    • Click the Save Model button when you are done.

  7. Enable the Audio Player interface

    Skill Creation Step 5
    • Click Interfaces, enable Audio Player, then click Save Interfaces

  8. Set the endpoint

    The skill’s endpoint is the location of the AskNavidrome web service.

    Skill Creation Step 6
    • Click Endpoint

    • Select HTTPS

    • Enter the the URL to the web service in the Default Region box.

    • Select the SSL certificate type. This will depend on your setup, if you are using Let’s Encrypt choose My development endpoints has a certificate from a trusted certificate authority

    • Click Save Endpoints

  9. Build the skill

    Skill Creation Step 7
    • Click Invocations, Skill Invocation Name.

    • Click Save Model.

    • Click Build Model, the process will take a few minutes.

  10. Add the skill to your Echo devices.

    The skill you just created should now be available as a development skill in your Alexa app, you can add the development skill to your Echo devices.

    Warning

    It is important that you do not publish the skill. If you do anyone that uses the skill will be able to stream your music collection, it may also be possible for credentials to be retrieved.

Deploying the AskNavidrome Web Service

The AskNavidrome Web Service is written in Python and can be run directly on a PC with a Python installation, or as a Docker container (recommended). Whichever method you use, the service and your Navidrome installation must be available via HTTPS with a well known certificate. One of the easiest ways to implement this is with a reverse proxy. There are several available for free:

Run on your PC

Please remember that the web service needs to be publicly accessible, if you are running it directly on your PC this means your PC is publicly accessible.

  1. Install Python 3
  2. Install git tools
  3. Create a directory for the web service

  4. Change to the directory and clone the repository from GitHub

    cd directory
    git clone https://github.com/rosskouk/asknavidrome.git
    
  5. Change directory to the skill folder

    cd asknavidrome/skill
    
  6. Start the skill by setting the required environment variables and executing the application you can find details of what each option does in the configuration section.

    NAVI_SKILL_ID=<your-skill-id> \
    NAVI_SONG_COUNT=50 \
    NAVI_URL=https://your-navidrome-server.test \
    NAVI_USER=<username> \
    NAVI_PASS=<password> \
    NAVI_PORT=443 \
    NAVI_API_PATH=/rest \
    NAVI_API_VER=1.16.1 \
    NAVI_DEBUG=0 \
    python3 app.py
    

Run inside a Docker container

A Dockerfile has been provided and a prebuilt container is hosted on github.com. Please note that the prebuilt container was created on an amd64 platform. If you require a different architecture such as arm for a Raspberry Pi, you will need to build a new image using the Dockerfile provided with the repository.

You can configure the service by passing environment variables to the docker run command.

docker run -p 5000:5000 \
-e NAVI_SKILL_ID=<your-skill-id> \
-e NAVI_SONG_COUNT=50 \
-e NAVI_URL=https://your-navidrome-server.test \
-e NAVI_USER=<username> \
-e NAVI_PASS=<password> \
-e NAVI_PORT=443 \
-e NAVI_API_PATH=/rest \
-e NAVI_API_VER=1.16.1 \
-e NAVI_DEBUG=0 \
ghcr.io/rosskouk/asknavidrome:<tag>

If you intent to use the container to build a Kubernetes pod, I have created a side car container which can automatically configure and renew TLS certificates with the Kubernetes Nginx Ingress. More information.

Configuration

The AskNavidrome Web Service reads it’s configuration from environment variables and needs the following configuration information to run:

Environment Variable

Description

Example

NAVI_SKILL_ID

The ID of your Alexa skill, this prevents other skills from connecting to the web service.

amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

NAVI_SONG_COUNT

The minimum number of songs to add to a playlist. If playing random music, music by genre or music by an artist the web service will ensure the minimum number of tracks added to the queue is at least this value

50

NAVI_URL

The URL to the Subsonic API server

https://navidrome.example.test

NAVI_USER

The user name used to connect to the Subsonic API server

bob

NAVI_PASS

The password used to connect to the Subsonic API server

Sup3rStrongP@ssword

NAVI_PORT

The port the Subsonic API server is listening on

443

NAVI_API_PATH

The path to the Subsonic API, this should be /rest if you are using Navidrome and haven’t changed anything

/rest

NAVI_API_VER

The version of the Subsonic API in use

1.16.1

NAVI_DEBUG

Enable debugging, by setting this variable to 1, or 3.

1

Troubleshooting

Troubleshooting and debugging Alexa skills can be a little frustrating, here are the best ways I have found to do it.

  1. Understand that the Alexa skill is effectively just a set of buttons. All the skill does is call functions in the web service, it does nothing other than translate what you say to the function name that will perform the task. Very little can go wrong with this, but here is a list of things to check:

    • Does the locale of the skill match the locale on your Echo device? If this is mismatched it looks like nothing happens when you try to invoke the skill.

    • Is the endpoint set correctly? The endpoint is the URL to the web service, if the skill cannot communicate with the web service check this first. you must ensure that the URL is https and the certificate is compatible with Amazon services.

    • If an intent does not work, you might need to add an additional phrase to the intent in the developer console. The included phrases work for me, you might want to make some changes though.

  2. Enable debugging and look at the logs generated by the web service.

  3. When level 3 debugging is enabled the following web pages are available from the web service

    • url-to-web-service/queue

      • Shows the tracks in the current queue

    • url-to-web-service/history

      • Shows the tracks that have already been played

    • url-to-web-service/buffer

      • Shows the tracks in the buffer. Note that the buffer and queue differ as Amazon will request the next track to be queued before the track playing is finished. The buffer can be thought of as the list of tracks still to be sent to Amazon, where as the queue is the list of tracks still to be played.

  4. Use the test page in the developer console The test page will show you the responses between Amazon and an simulated Echo device, this can help you uncover error messages that are normally hidden.

    debugging Step 1
    • Click test and make sure you tick Device Log

    • You can type instructions in the box or use the microphone on your device

    debugging Step 2
    • After you have entered a command you will get the Alexa response back, scroll down to the Device Log section and click through the entries the entries will contain any errors that were thrown.

Debug Options

You can enable the following debug options by setting the NAVI_DEBUG environment variable.

  • 0 = Logging set to WARNING and higher.

  • 1 = Logging set to INFO and higher.

  • 2 = Logging set to DEBUG and higher and request / response interceptors are enabled.

  • 3 = All features of level 2 and the web ui. Note the UI will be publicly available while this is enabled.

Known Issues

  1. The skill appears to work but no music is played. Errors similar to below appear in the web service log

    2022-11-19 13:16:45,478 - root - DEBUG - In PlaybackFailedHandler
    2022-11-19 13:16:45,479 - root - ERROR - Playback Failed: {'message': 'Device playback error', 'object_type': 'MEDIA_ERROR_UNKNOWN'}
    2022-11-19 13:16:45,480 - werkzeug - INFO - 10.44.17.62 - - [19/Nov/2022 13:16:45] "POST / HTTP/1.1" 200 -
    2022-11-19 13:16:48,599 - root - DEBUG - In PlaybackFailedHandler
    2022-11-19 13:16:48,600 - root - ERROR - Playback Failed: {'message': 'Device playback error','object_type': 'MEDIA_ERROR_INTERNAL_DEVICE_ERROR'}
    
    • I have not found a reason as to why this happens from time to time, however it can be resolved by doing a hard reboot of your Echo device. Disconnect the power for a minute and plug it back in then try again and music should play

  2. The following error is displayed when you try to run the Docker container

    exec /opt/env/bin/python3: exec format error
    
    • You are using the prebuilt container on a non amd64 based system. You will need to build your own Docker image using the Dockerfile included with the repository.

Code Documentation

AskNavidrome main

Classes:

CheckAudioInterfaceHandler()

Check if device supports audio play.

GeneralExceptionHandler()

Handle general exceptions

HelpHandler()

Handle HelpIntent

LaunchRequestHandler()

Handle LaunchRequest and NavigateHomeIntent

LoggingRequestInterceptor()

Intercept all requests

LoggingResponseInterceptor()

Intercept all responses

NaviSonicPlayAlbumByArtist()

Handle NaviSonicPlayAlbumByArtist

NaviSonicPlayFavouriteSongs()

Handle the NaviSonicPlayFavouriteSongs intent

NaviSonicPlayMusicByArtist()

Handle NaviSonicPlayMusicByArtist

NaviSonicPlayMusicByGenre()

Play songs from the given genere

NaviSonicPlayMusicRandom()

Handle the NaviSonicPlayMusicRandom intent

NaviSonicPlayPlaylist()

Handle NaviSonicPlayPlaylist

NaviSonicPlaySongByArtist()

Handle the NaviSonicPlaySongByArtist intent

NaviSonicRandomiseQueue()

Handle NaviSonicRandomiseQueue Intent

NaviSonicSongDetails()

Handle NaviSonicSongDetails Intent

NaviSonicStarSong()

Handle NaviSonicStarSong Intent

NaviSonicUnstarSong()

Handle NaviSonicUnstarSong Intent

NextPlaybackHandler()

Handle NextIntent

PausePlaybackHandler()

Handler for stopping audio.

PlaybackFailedEventHandler()

AudioPlayer.PlaybackFailed Directive received.

PlaybackFinishedHandler()

AudioPlayer.PlaybackFinished Directive received.

PlaybackNearlyFinishedHandler()

AudioPlayer.PlaybackNearlyFinished Directive received.

PlaybackStartedHandler()

AudioPlayer.PlaybackStarted Directive received.

PlaybackStoppedHandler()

AudioPlayer.PlaybackStopped Directive received.

PreviousPlaybackHandler()

Handle PreviousIntent

ResumePlaybackHandler()

Handler for resuming audio on different events.

SkillEventHandler()

Close session for skill events or when session ends.

SystemExceptionHandler()

Handle System.ExceptionEncountered

class app.CheckAudioInterfaceHandler

Check if device supports audio play.

This can be used as the first handler to be checked, before invoking other handlers, thus making the skill respond to unsupported devices without doing much processing.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.GeneralExceptionHandler

Handle general exceptions

Handles exceptions and prints error information in the log

Methods:

can_handle(handler_input, exception)

Checks if the handler can support the exception raised during dispatch.

handle(handler_input, exception)

Process the handler input and exception.

can_handle(handler_input: HandlerInput, exception: Exception) bool

Checks if the handler can support the exception raised during dispatch.

Parameters:
  • handler_input (HandlerInput) – Handler Input instance.

  • exception (Exception) – Exception raised during dispatch.

Returns:

Boolean whether handler can handle exception or not.

Return type:

bool

handle(handler_input: HandlerInput, exception: Exception) Response

Process the handler input and exception.

Parameters:
  • handler_input (HandlerInput) – Handler Input instance.

  • exception (Exception) – Exception raised during dispatch.

Returns:

Optional response object to serve as dispatch return.

Return type:

Union[None, Response]

class app.HelpHandler

Handle HelpIntent

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.LaunchRequestHandler

Handle LaunchRequest and NavigateHomeIntent

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.LoggingRequestInterceptor

Intercept all requests

Intercepts all requests sent to the skill and prints them in the log

Methods:

process(handler_input)

Process the input before the Handler is run.

process(handler_input: HandlerInput)

Process the input before the Handler is run.

Parameters:

handler_input (HandlerInput) – Handler Input instance.

Return type:

None

class app.LoggingResponseInterceptor

Intercept all responses

Intercepts all responses sent from the skill and prints them in the log

Methods:

process(handler_input, response)

Process the input and the response after the Handler is run.

process(handler_input: HandlerInput, response: Response)

Process the input and the response after the Handler is run.

Parameters:
  • handler_input (HandlerInput) – Handler Input instance.

  • response (Union[None, ask_sdk_model.response.Response]) – Execution result of the Handler on handler input.

Return type:

None

class app.NaviSonicPlayAlbumByArtist

Handle NaviSonicPlayAlbumByArtist

Play a given album by a given artist

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlayFavouriteSongs

Handle the NaviSonicPlayFavouriteSongs intent

Play all starred / liked songs, songs are automatically shuffled.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlayMusicByArtist

Handle NaviSonicPlayMusicByArtist

Play a selection of songs for the given artist

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlayMusicByGenre

Play songs from the given genere

50 tracks from the given genere are shuffled and played

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlayMusicRandom

Handle the NaviSonicPlayMusicRandom intent

Play a random selection of music.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlayPlaylist

Handle NaviSonicPlayPlaylist

Play the given playlist

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicPlaySongByArtist

Handle the NaviSonicPlaySongByArtist intent

Play the given song by the given artist if it exists in the collection.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicRandomiseQueue

Handle NaviSonicRandomiseQueue Intent

Shuffle the current play queue

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicSongDetails

Handle NaviSonicSongDetails Intent

Returns information on the track that is currently playing

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicStarSong

Handle NaviSonicStarSong Intent

Star / favourite the current song

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NaviSonicUnstarSong

Handle NaviSonicUnstarSong Intent

Star / favourite the current song

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.NextPlaybackHandler

Handle NextIntent

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PausePlaybackHandler

Handler for stopping audio.

Handles Stop, Cancel and Pause Intents and PauseCommandIssued event.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PlaybackFailedEventHandler

AudioPlayer.PlaybackFailed Directive received.

Logging the error and restarting playing with no output speech.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PlaybackFinishedHandler

AudioPlayer.PlaybackFinished Directive received.

Confirming that the requested audio file completed playing. Do not send any specific response.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PlaybackNearlyFinishedHandler

AudioPlayer.PlaybackNearlyFinished Directive received.

Replacing queue with the URL again. This should not happen on live streams.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PlaybackStartedHandler

AudioPlayer.PlaybackStarted Directive received.

Confirming that the requested audio file began playing. Do not send any specific response.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PlaybackStoppedHandler

AudioPlayer.PlaybackStopped Directive received.

Confirming that the requested audio file stopped playing. Do not send any specific response.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.PreviousPlaybackHandler

Handle PreviousIntent

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.ResumePlaybackHandler

Handler for resuming audio on different events.

Handles PlayAudio Intent, Resume Intent.

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.SkillEventHandler

Close session for skill events or when session ends.

Handler to handle session end or skill events (SkillEnabled, SkillDisabled etc.)

Methods:

can_handle(handler_input)

Returns true if Request Handler can handle the Request inside Handler Input.

handle(handler_input)

Handles the Request inside handler input and provides a Response for dispatcher to return.

can_handle(handler_input: HandlerInput) bool

Returns true if Request Handler can handle the Request inside Handler Input.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Boolean value that tells the dispatcher if the current request can be handled by this handler.

Return type:

bool

handle(handler_input: HandlerInput) Response

Handles the Request inside handler input and provides a Response for dispatcher to return.

Parameters:

handler_input (HandlerInput) – Handler Input instance with Request Envelope containing Request.

Returns:

Response for the dispatcher to return or None

Return type:

Union[Response, None]

class app.SystemExceptionHandler

Handle System.ExceptionEncountered

Handles exceptions and prints error information in the log

Methods:

can_handle(handler_input, exception)

Checks if the handler can support the exception raised during dispatch.

handle(handler_input, exception)

Process the handler input and exception.

can_handle(handler_input: HandlerInput, exception: Exception) bool

Checks if the handler can support the exception raised during dispatch.

Parameters:
  • handler_input (HandlerInput) – Handler Input instance.

  • exception (Exception) – Exception raised during dispatch.

Returns:

Boolean whether handler can handle exception or not.

Return type:

bool

handle(handler_input: HandlerInput, exception: Exception) Response

Process the handler input and exception.

Parameters:
  • handler_input (HandlerInput) – Handler Input instance.

  • exception (Exception) – Exception raised during dispatch.

Returns:

Optional response object to serve as dispatch return.

Return type:

Union[None, Response]

AskNavidrome controller

Functions:

add_screen_background(card_data)

Add background to card.

enqueue_songs(api, queue, song_id_list)

Enqueue songs

start_playback(mode, text, card_data, ...)

Function to play audio.

stop(handler_input)

Stop playback

asknavidrome.controller.add_screen_background(card_data: dict) AudioItemMetadata | None

Add background to card.

Cards are viewable on devices with screens and in the Alexa app.

Parameters:

card_data (dict) – Dictionary containing card data

Returns:

An Amazon AudioItemMetadata object or None if card data is not present

Return type:

AudioItemMetadata | None

asknavidrome.controller.enqueue_songs(api: SubsonicConnection, queue: MediaQueue, song_id_list: list) None

Enqueue songs

Add Track objects to the queue deque

Parameters:
  • api (SubsonicConnection) – A SubsonicConnection object to allow access to the Navidrome API

  • queue (MediaQueue) – A MediaQueue object

  • song_id_list (list) – A list of song IDs to enqueue

Returns:

None

asknavidrome.controller.start_playback(mode: str, text: str, card_data: dict, track_details: Track, handler_input: HandlerInput) Response

Function to play audio.

Begin playing audio when:

  • Play Audio Intent is invoked.

  • Resuming audio when stopped / paused.

  • Next / Previous commands issues.

Note

Parameters:
  • mode (str) – play | continue - Play immediately or enqueue a track

  • text (str) – Text which should be spoken before playback starts

  • card_data (dict) – Data to display on a card

  • track_details (Track) – A Track object containing details of the track to use

  • handler_input (HandlerInput) – The Amazon Alexa HandlerInput object

Returns:

Amazon Alexa Response class

Return type:

Response

asknavidrome.controller.stop(handler_input: HandlerInput) Response

Stop playback

Parameters:

handler_input (HandlerInput) – The Amazon Alexa HandlerInput object

Returns:

Amazon Alexa Response class

Return type:

Response

AskNavidrome media queue

class asknavidrome.media_queue.MediaQueue

The MediaQueue class

This class provides a queue based on a Python deque. This is used to store the tracks in the current play queue

Returns:

None

Methods:

add_track(track)

Add tracks to the queue

clear()

Clear queue, history and buffer deques

enqueue_next_track()

Get the next buffered track

get_history_count()

Get the number of tracks in the history deque

get_next_track()

Get the next track

get_prevous_track()

Get the previous track

get_queue_count()

Get the number of tracks in the queue

shuffle()

Shuffle the queue

sync()

Syncronise the buffer with the queue

Attributes:

buffer

Deque to contain the list of tracks to be enqueued

current_track

Property to hold the current track object

history

Deque to hold tracks that have already been played

logger

Logger

queue

Deque containing tracks still to be played

add_track(track: Track) None

Add tracks to the queue

Parameters:

track (Track) – A Track object containing details of the track to be played

Returns:

None

clear() None

Clear queue, history and buffer deques

Returns:

None

enqueue_next_track() Track

Get the next buffered track

Get the next track from the buffer without updating the current track attribute. This allows Amazon to send the PlaybackNearlyFinished request early to queue the next track while maintaining the playlist

Returns:

The next track to be played

Return type:

Track

get_history_count() int

Get the number of tracks in the history deque

Returns:

The number of tracks in the history deque

Return type:

int

get_next_track() Track

Get the next track

Get the next track from self.queue and add it to the history deque

Returns:

The next track object

Return type:

Track

get_prevous_track() Track

Get the previous track

Get the last track added to the history deque and add it to the front of the play queue

Returns:

The previous track object

Return type:

Track

get_queue_count() int

Get the number of tracks in the queue

Returns:

The number of tracks in the queue deque

Return type:

int

shuffle() None

Shuffle the queue

Shuffles the queue and resets the previous track IDs required for the ENQUEUE PlayBehaviour

Returns:

None

sync() None

Syncronise the buffer with the queue

Overwrite the buffer with the current queue. This is useful when pausing or stopping to ensure the resulting PlaybackNearlyFinished request gets the correct. In practice this will have already queued and there for missing from the current buffer

Returns:

None

buffer: deque

Deque to contain the list of tracks to be enqueued

This deque is created from self.queue when actions such as next or previous are performed. This is because Amazon can send the PlaybackNearlyFinished request early. Without self.buffer, this would change self.current_track causing us to lose the real position of the queue.

current_track: Track

Property to hold the current track object

history: deque

Deque to hold tracks that have already been played

logger

Logger

queue: deque

Deque containing tracks still to be played

AskNavidrome subsonic API

class asknavidrome.subsonic_api.SubsonicConnection(server_url: str, user: str, passwd: str, port: int, api_location: str, api_version: str)

Class with methods to interact with Subsonic API compatible media servers

Parameters:
  • server_url (str) – The URL of the Subsonic API compatible media server

  • user (str) – Username to authenticate against the API

  • passwd (str) – Password to authenticate against the API

  • port (int) – Port the Subsonic compatibe server is listening on

  • api_location (str) – Path to the API, this is appended to server_url

  • api_version (str) – The version of the Subsonic API that is in use

Returns:

None

Methods:

albums_by_artist(id)

Get the albums for a given artist

build_random_song_list(count)

Build a shuffled list of random songs

build_song_list_from_albums(albums, length)

Get a list of songs from given albums

build_song_list_from_favourites()

Build a shuffled list favourite songs

build_song_list_from_genre(genre, count)

Build a shuffled list songs of songs from the given genre.

build_song_list_from_playlist(id)

Build a list of songs from a given playlist

get_song_details(id)

Get details about a given song ID

get_song_uri(id)

Create a URI for a given song

ping()

Ping a Subsonic API server

search_album(term)

Search the media server for the given album

search_artist(term)

Search the media server for the given artist

search_playlist(term)

Search the media server for the given playlist

search_song(term)

Search the media server for the given song

star_entry(id, mode)

Add a star to the given entity

unstar_entry(id, mode)

Remove a star from the given entity

albums_by_artist(id: str) list[dict]

Get the albums for a given artist

Parameters:

id (str) – The artist ID

Returns:

A list of albums

Return type:

list of dict

build_random_song_list(count: int) list | None

Build a shuffled list of random songs

Parameters:

count (int) – The number of songs to return

Returns:

A list of song IDs or None if no tracks are found.

Return type:

list | None

build_song_list_from_albums(albums: list[dict], length: int) list

Get a list of songs from given albums

Build a list of songs from the given albums, keep adding tracks until song_count is greater than of equal to length

Parameters:
  • albums (list[dict]) – A list of dictionaries containing album information

  • length (int) – The minimum number of songs that should be returned, if -1 there is no limit

Returns:

A list of song IDs

Return type:

list

build_song_list_from_favourites() list | None

Build a shuffled list favourite songs

Returns:

A list of song IDs or None if no favourite tracks are found.

Return type:

list | None

build_song_list_from_genre(genre: str, count: int) list | None

Build a shuffled list songs of songs from the given genre.

Parameters:
  • genre (str) – The genre, acceptible values are with the getGenres Subsonic API call.

  • count (int) – The number of songs to return

Returns:

A list of song IDs or None if no tracks are found.

Return type:

list | None

build_song_list_from_playlist(id: str) list

Build a list of songs from a given playlist

Parameters:

id (str) – The playlist ID

Returns:

A list of song IDs

Return type:

list

get_song_details(id: str) dict

Get details about a given song ID

Parameters:

id (str) – A song ID

Returns:

A dictionary of details about the given song.

Return type:

dict

get_song_uri(id: str) str

Create a URI for a given song

Creates a URI for the song represented by the given ID. Authentication details are embedded in the URI

Parameters:

id (str) – A song ID

Returns:

A properly formatted URI

Return type:

str

ping() bool

Ping a Subsonic API server

Verify the connection to a Subsonic compatible API server is working

Returns:

True if the connection works, False if it does not

Return type:

bool

search_album(term: str) dict | None

Search the media server for the given album

Parameters:

term (str) – The name of the album

Returns:

A dictionary of albums or None if no results are found

Return type:

dict | None

search_artist(term: str) dict | None

Search the media server for the given artist

Parameters:

term (str) – The name of the artist

Returns:

A dictionary of artists or None if no results are found

Return type:

dict | None

search_playlist(term: str) str | None

Search the media server for the given playlist

Parameters:

term (str) – The name of the playlist

Returns:

The ID of the playlist or None if the playlist is not found

Return type:

str | None

search_song(term: str) dict | None

Search the media server for the given song

Parameters:

term (str) – The name of the song

Returns:

A dictionary of songs or None if no results are found

Return type:

dict | None

star_entry(id: str, mode: str) None

Add a star to the given entity

Parameters:
  • id (str) – The Navidrome ID of the entity.

  • mode (str) – The type of entity, must be song, artist or album

Returns:

None.

unstar_entry(id: str, mode: str) None

Remove a star from the given entity

Parameters:
  • id (str) – The Navidrome ID of the entity.

  • mode (str) – The type of entity, must be song, artist or album

Returns:

None.

AskNavidrome track

class asknavidrome.track.Track(id: str = '', title: str = '', artist: str = '', artist_id: str = '', album: str = '', album_id: str = '', track_no: int = 0, year: int = 0, genre: str = '', duration: int = 0, bitrate: int = 0, uri: str = '', offset: int = 0, previous_id: str = '')

An object that represents an audio track

Parameters:
  • id (str) – The song ID. Defaults to ‘’

  • title (str) – The song title. Defaults to ‘’

  • artist (str) – The artist name. Defaults to ‘’

  • artist_id (str) – The artist ID. Defaults to ‘’

  • album (str) – The album name. Defaults to ‘’

  • album_id (str) – The album ID. Defaults to ‘’

  • track_no (int) – The track number. Defaults to 0

  • year (int) – The release year. Defaults to 0

  • genre (str) – The music genre. Defaults to ‘’

  • duration (int) – The length of the track in seconds. Defaults to 0

  • bitrate (int) – The bit rate in kbps. Defaults to 0

  • uri (str) – The song’s URI for streaming. Defaults to ‘’

  • offset (int) – The position in the track to start playback in milliseconds. Defaults to 0

  • previous_id (str) – The ID of the previous song in the playlist. Defaults to ‘’

Returns:

None