Skip to content
This repository was archived by the owner on Sep 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ On the next tab, you'll have to paste the `alexa.intents` file into the first fi

Now, let's setup the custom slot types. To make it as easy as possible, I wrote a little webapp that will give you the information you need: [here.](https://sleepy-wave-26412.herokuapp.com/)

Just enter in the information about your Kodi box into the form and it'll pull the data you need. There are 3 custom slots that you'll create. SHOWS, MOVIES, MUSIC. Just copy the data from the webapp into your Alexa skill page.
Just enter in the information about your Kodi box into the form and it'll pull the data you need. There are 4 custom slots that you'll create. SHOWS, MOVIES, MUSICARTISTS, MUSICPLAYLISTS. Just copy the data from the webapp into your Alexa skill page.

![2nd tab alt](http://i.imgur.com/SkGcyPQ.png)

Expand Down
15 changes: 14 additions & 1 deletion alexa.intents
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,23 @@
"slots": [
{
"name": "Artist",
"type": "MUSIC"
"type": "MUSICARTISTS"
}
]
},
{
"intent": "ListenToPlaylist",
"slots": [
{
"name": "Playlist",
"type": "MUSICPLAYLISTS"
}
]
},
{
"intent": "ListenToPlaylistRecent",
"slots": []
},
{
"intent": "PlayRandomEpisode",
"slots": [
Expand Down
32 changes: 31 additions & 1 deletion alexa.utterances
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,36 @@ ListenToArtist listen to {Artist}
ListenToArtist shuffle artist {Artist}
ListenToArtist shuffle music by {Artist}
ListenToArtist shuffle {Artist}
ListenToPlaylist listen to playlist {Playlist}
ListenToPlaylist listen to {Playlist} playlist
ListenToPlaylist shuffle playlist {Playlist}
ListenToPlaylist shuffle {Playlist} playlist
ListenToPlaylist play playlist {Playlist}
ListenToPlaylist play {Playlist} playlist
ListenToPlaylistRecent listen to playlist recent
ListenToPlaylistRecent listen to playlist recently added
ListenToPlaylistRecent listen to recent playlist
ListenToPlaylistRecent listen to recent songs
ListenToPlaylistRecent listen to recent music
ListenToPlaylistRecent listen to recently added playlist
ListenToPlaylistRecent listen to recently added songs
ListenToPlaylistRecent listen to recently added music
ListenToPlaylistRecent shuffle playlist recent
ListenToPlaylistRecent shuffle playlist recently added
ListenToPlaylistRecent shuffle recent playlist
ListenToPlaylistRecent shuffle recent songs
ListenToPlaylistRecent shuffle recent music
ListenToPlaylistRecent shuffle recently added playlist
ListenToPlaylistRecent shuffle recently added songs
ListenToPlaylistRecent shuffle recently added music
ListenToPlaylistRecent play playlist recent
ListenToPlaylistRecent play playlist recently added
ListenToPlaylistRecent play recent playlist
ListenToPlaylistRecent play recent songs
ListenToPlaylistRecent play recent music
ListenToPlaylistRecent play recently added playlist
ListenToPlaylistRecent play recently added songs
ListenToPlaylistRecent play recently added music
Menu open menu
NewShowInquiry if there are any episodes of {Show}
NewShowInquiry if there are any new episodes of {Show}
Expand Down Expand Up @@ -302,4 +332,4 @@ WhatNewShows what shows do we have
WhatNewShows what shows do you have
WhatNewShows what shows i have
WhatNewShows what shows we have
WhatNewShows what shows you have
WhatNewShows what shows you have
31 changes: 21 additions & 10 deletions kodi.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,26 +160,30 @@ def matchHeard(heard, results, lookingFor='label'):
return located


# This is a little weak because if there are multiple active players,
# it only returns the first one and assumes it's the one you want.
# In practice, this works OK in common cases.
# Get the first active Audio or Video player, since all we deal with
# currently.

def GetPlayerID():
def GetPlayerID(playertype=['audio', 'video']):
info = SendCommand(RPCString("Player.GetActivePlayers"))
result = info.get("result", [])
if len(result) > 0:
return result[0].get("playerid")
else:
return None

for curitem in result:
if curitem.get("type") in playertype:
return curitem.get("playerid")
return None


def ClearPlaylist():
return SendCommand(RPCString("Playlist.Clear", {"playlistid": 0}))

def ClearVideoPlaylist():
return SendCommand(RPCString("Playlist.Clear", {"playlistid": 1}))

def StartPlaylist():
return SendCommand(RPCString("Player.Open", {"item": {"playlistid": 0}}))
def StartPlaylist(playlist_file=None):
if playlist_file is not None and playlist_file != '':
return SendCommand(RPCString("Player.Open", {"item": {"file": playlist_file}}))
else:
return SendCommand(RPCString("Player.Open", {"item": {"playlistid": 0}}))

def AddSongToPlaylist(song_id):
return SendCommand(RPCString("Playlist.Add", {"playlistid": 0, "item": {"songid": int(song_id)}}))
Expand Down Expand Up @@ -296,6 +300,9 @@ def Replay():
if playerid:
return SendCommand(RPCString("Player.Seek", {"playerid":playerid, "value":"smallbackward"}))

def GetMusicPlaylists():
return SendCommand(RPCString("Files.GetDirectory", {"directory": "special://musicplaylists"}))

def GetMusicArtists():
data = SendCommand(RPCString("AudioLibrary.GetArtists"))
return data
Expand All @@ -308,6 +315,10 @@ def GetArtistSongs(artist_id):
data = SendCommand(RPCString("AudioLibrary.GetSongs", {"filter": {"artistid": int(artist_id)}}))
return data

def GetRecentlyAddedSongs():
data = SendCommand(RPCString("AudioLibrary.GetRecentlyAddedSongs"))
return data

def GetTvShows():
data = SendCommand(RPCString("VideoLibrary.GetTVShows"))
return data
Expand Down
9 changes: 8 additions & 1 deletion utterances.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ UpdateAudio update (audio/music) library

ListenToArtist (listen to/shuffle) (/music by/artist) {Artist}

ListenToPlaylist (play/listen to/shuffle) playlist {Playlist}

ListenToPlaylistRecent (play/listen to/shuffle) (/playlist) recent
ListenToPlaylistRecent (play/listen to/shuffle) (/playlist) recently added
ListenToPlaylistRecent (play/listen to/shuffle) recent (/songs/music/playlist)
ListenToPlaylistRecent (play/listen to/shuffle) recently added (/songs/music/playlist)

PlayRandomMovie (play/watch) (/a) random (movie/film)

PlayRandomEpisode (play/watch) (/a) (/random) episode of {Show}
Expand All @@ -59,4 +66,4 @@ NewShowInquiry if (there is/we have) a new (/episode of) {Show}
NewShowInquiry if (there are/we have) any (/(/new )episodes of) {Show}
NewShowInquiry if (there is/we have) {Show}

PlayLatestEpisode (play/watch) (/the) (newest/latest) episode of {Show}
PlayLatestEpisode (play/watch) (/the) (newest/latest) episode of {Show}
52 changes: 49 additions & 3 deletions wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def alexa_stop(slots):
answer = "Playback Stopped"
return build_alexa_response(answer)

# Suffle all music by an artist
# Shuffle all music by an artist
def alexa_play_artist(slots):
heard_artist = str(slots['Artist']['value']).lower().translate(None, string.punctuation)

Expand Down Expand Up @@ -183,7 +183,51 @@ def alexa_play_artist(slots):
return build_alexa_response('Could not find %s' % (heard_artist))
else:
return build_alexa_response('Could not find %s' % (heard_artist))


# Shuffle all recently added songs
def alexa_play_recently_added_songs(slots):
print('Trying to play recently added songs')
sys.stdout.flush()

songs_result = kodi.GetRecentlyAddedSongs()
if songs_result:
songs = songs_result['result']['songs']

kodi.Stop()
kodi.ClearPlaylist()

songs_array = []

for song in songs:
songs_array.append(song['songid'])

kodi.AddSongsToPlaylist(songs_array)

kodi.StartPlaylist()
return build_alexa_response('Playing recently added songs')
return build_alexa_response('No recently added songs found')

def alexa_play_playlist(slots):
heard_playlist = str(slots['Playlist']['value']).lower().translate(None, string.punctuation)

print('Trying to play playlist "%s"' % (heard_playlist))
sys.stdout.flush()

playlists = kodi.GetMusicPlaylists()
if 'result' in playlists and 'files' in playlists['result']:
playlists_list = playlists['result']['files']
located = kodi.matchHeard(heard_playlist, playlists_list, 'label')

if located:
print 'Playing playlist "%s"' % (located['file'])
sys.stdout.flush()
kodi.StartPlaylist(located['file'])
return build_alexa_response('Playing playlist %s' % (heard_playlist))
else:
return build_alexa_response('Could not find %s' % (heard_playlist))
else:
return build_alexa_response('Could not find %s' % (heard_playlist))

def alexa_start_over(slots):
print('Starting current item over')
sys.stdout.flush()
Expand Down Expand Up @@ -576,6 +620,8 @@ def prepare_help_message():
['PlayPause', alexa_play_pause],
['Stop', alexa_stop],
['ListenToArtist', alexa_play_artist],
['ListenToPlaylist', alexa_play_playlist],
['ListenToPlaylistRecent', alexa_play_recently_added_songs],
['Skip', alexa_skip],
['Prev', alexa_prev],
['StartOver', alexa_start_over],
Expand Down Expand Up @@ -689,4 +735,4 @@ def application(environ, start_response):
</body></html>
""" % {'url':environ['PATH_INFO'], 'address':environ['SERVER_SIGNATURE'], 'details':details}
start_response('404 Not Found', [('Content-type', 'text/html')])
return [output]
return [output]