Solved [HOW-TO] Amazon Alexa Integration for Kodi (and whatever), RE: "Alexa Feature wi..."
#1
Here's how to integrate Alexa with Kodi (and whatever else), in response to https://forum.kodi.tv/showthread.php?tid=309723 and possibly more.

This how-to assumes knowledge of Android, command line interfacing and programmatic procedures. Only general Examples provided.

So there's four key components needed to integrate.

1) Event detection so you know when there has been an Alexa request.
2) Retrieve the request
3) Perform an action for the request.
4) Respond to Alexa that an action has been performed.

There are any number of ways to trigger an event that there has been an Alexa request, for my use case I am using a FireTV cube so the easiest way is to watch logcat entries from com.amazon.vizzini (the alexa process).

You can do this many ways, for this example we're watching logcat from a python subprocess call to adb.

python:

p = subprocess.Popen(["adb", "logcat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

while True:
    inline = p.stdout.readline().decode("utf-8")

This generates a new trigger each time a new line is added to logcat from the system acting as a pseudo device event trigger.

What we're going to watch for is CSMSIM#directive_received, these are added from the vizzini process when a request has been received.

DeviceEvent: CSMSIM#directive_received#1#NameSpace#Directive#null#EventID

Specifically we care about NameSpace "Alexa.RemoteVideoPlayer" so we can filter by and trigger from that.

Other systems without this trigger you're not out of luck because the actual call is never in logcat so you can do whatever you like to create a trigger.

What now? We have a notification of an Alexa event but we don't know what it was. Well, good old amazon logs Alexa events to our account and we will use this.

You can see the events from your account at https://www.amazon.com/alexa-privacy/apd/rvh and even better it's backed by a JSON request so we can pull events, even better still these are updated near instantly.

JSON Backend: https://www.amazon.com/alexa-privacy/apd...lNav=false

Yes, those are timestamps in the request url and yes you can filter up to the last 60 seconds. We will pull records with a startTime 60 seconds before and after now.

python:

    import time
    ns = time.time_ns()
    startTime = int(str(ns)[:-6]) # Get ms from ns, as good as any math function
    remoteurl="https://www.amazon.com/alexa-privacy/apd/rvh/customer-history-records?startTime={}&endTime={}&disableGlobalNav=false".format(startTime-60000,startTime+60000) # Events 1 minute before and after now

You need to do a url request with whatever you like, add your amazon cookies to the headers.

With some customization you can decide what to do from here, for this we only want the most recent record.

python:

    events = json.loads(data)
    if len(events['customerHistoryRecords'])>0:
        alexaRequest = events['customerHistoryRecords'][0]['voiceHistoryRecordItems'][0]['transcriptText']

Now alexaRequest will be something like "alexa play a random movie" or "alexa play a random movie from firetv", whatever you asked it to do.

Great now we have successfully detected and received an Alexa request, by now something has already happened on your TV, most likely prime video opened or it's showed search results or whatever.

Before we proceed it would be best to eliminate competing apps so we can handle the request ourselves, there's 2 methods I found each with merit, it's a preference.

Option 1

adb shell am force-stop com.amazon.firebat
adb shell am force-stop com.amazon.tv.launcher
adb shell am force-stop com.amazon.avod

This will kill the apps that are handling or have handled the request, messy, murderous, makes Kodi do weird things after the fact such as video playing without the video window visible.

Option 2

adb shell pm disable-user --user 0 com.amazon.firebat

This disables firebat which likes to handle these requests as a result no other competing apps try to process the request, minimal impact and doesn't break the system. If you want to re-enable it's adb shell pm enable com.amazon.firebat

Great now we can do things with the request, our example "alexa play a random movie" is an easy one you just need to call Kodi with some JSONRPC calls.

Ask Kodi for a movies list, limit 1 record, sorted by random with a playcount of 0 (unwatched).

{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties": [ "title", "lastplayed", "studio", "cast", "plot", "writer", "director", "fanart", "runtime", "mpaa", "thumbnail", "file","year", "genre", "tag", "trailer" ], "sort": { "order": "ascending", "method": "random" }, "limits":{"end":1},"filter":{"field":"playcount","operator":"is", "value":"0"} }, "id": 1 }

Get movieid, data["result"]["movies"][0]["movieid"]

Ask Kodi to play it, resume if in progress.

{"jsonrpc":"2.0","id":1,"method":"Player.Open","params":{"item":{"movieid":'+str(movieid)+'},"options":{"resume":true}}}

Now Kodi should be playing the movie, success you have now started a media playback from an Alexa command.

There's the first 3 of the 4 components for an Alexa request, as far as responding I have not found a way but I'm not bothered once Kodi starts playing Alexa informs me the it's "playing (something) from prime video" which it's not, it'll also respond "Here's what I found".


Other notes.

Obviously you need to enable "Control From Other Applications" in Kodi JSONRPC settings.
I recommend not abusing the history url just in case Amazon decides they don't like Skills being sidestepped.
While you're watching the logcat anyway you can find some other useful triggers to do things:
    An event of "ActivityManager: Displayed" will have the current active activity name.
    You can track active activity and if it's "com.amazon.tv.launcher" you can do "adb shell am start org.xbmc.kodi/.Main" to kick Kodi back on screen (sort of makes Kodi the Home launcher)

If you are unable to:
    Work out how to perform url requests with cookies.
    Work out how adb works over tcp
    Generally script something.
Then this is not the guide for you.

I could never decide the best implementation for this, on one hand it would be easy to put into a kodi service addon but then you couldn't process requests when Kodi isn't running so for my application I'm running it as a background service on a server in the same network.

Hope this helps.

Have a great new year Kodi fans and I look forward to seeing some responses noting either integrations on other systems or just telling me how this is a terrible idea.
Reply
#2
A little follow up on this, I have found some new information.

Disabling com.amazon.firebat actually disables the native prime video app, if you're using the Kodi addon it's not a big deal but worth a note.

On re-enabling com.amazon.firebat it may become difficult to locate prime video (native app) from the home launcher and may require a restart.

I found it best to enable it when exiting Kodi and disable it when entering Kodi so it's only ever disabled when Kodi is active.

There appears to be a bug in Kodi when starting video playback from a JSONRPC call so there will be no video displayed.
    It'll be playing the video, the UI thinks it's playing a video, there is audio from the video, all the controls are for the video, play pause works like it's a video, OSD shows up for video however there is no actual video output on screen.
    I have not reported this as an official bug because I can't find anything in the log that indicates an error, everything looks normal.
    So just be aware if you attempt this integration that even though it's not playing a video the integration did in fact work (Alexa request was processed and Kodi was called) but there's other factors not working.

Something to do with Alexa's learning ability is impacting voice responses post-command, I have noted several instances where there is no voice response at all, I have no fix for this until I work out how to create a response to Alexa from Kodi.

I have found that translated requests from Alexa with regards to numbers it presents digits as words so Kodi may not find a result for "Home Alone Two" when the movie is actually "Home Alone 2", something I had to account for but very simple to overcome.
Reply

Logout Mark Read Team Forum Stats Members Help
[HOW-TO] Amazon Alexa Integration for Kodi (and whatever), RE: "Alexa Feature wi..."0