Coder Social home page Coder Social logo

tyzer34 / plexmusicplayer Goto Github PK

View Code? Open in Web Editor NEW
35.0 14.0 19.0 50 KB

Playback music with Alexa from your Plex Server!

Home Page: https://medium.com/@Tyzer34/plex-alexa-the-perfect-wedding-38b14b41faf0#.b71cd6lsn

License: GNU General Public License v3.0

Python 100.00%

plexmusicplayer's Introduction

Plex Music Player

Full blog post available on: https://medium.com/@Tyzer34/plex-alexa-the-perfect-wedding-38b14b41faf0#.b71cd6lsn

The purpose of this project is to give Alexa users a way to playback music, using their own Plex server. However, it is also a way to show developers a method to integrate Plex into Alexa as a music service. The application does however not enable remote control of Plex instances, nor does it (as for this moment) include a global technique of authentication. However, a detailed overview on how to setup this application is provided below.

As a developer, I wanted to broaden the spectrum a bit by giving Alexa users access to their own Plex Music Player. Heroku is used for the deployment of the application, but almost any platform can be used. Do keep in mind that deployment on PythonAnywhere will not work for this application, as their whitelist does not allow access to the Plex servers.

Note that this skill is not made by nor supported by Plex!

The Setup

First, you should have Heroku and Git installed on your local machine. If you have not yet worked with Heroku before, the installation process can be found here. Also, make sure that you are already logged in with Heroku account.

Next, we want to clone the current GitHub repository of this project. First, open up a terminal (or command prompt) and navigate to the directory you want the files to be stored in. Then, use the following command to clone the repo.

git clone https://github.com/tyzer34/plexmusicplayer.git

Now that the files have been cloned locally, they can be deployed on Heroku. To set up this Heroku server, the following commands should be used. Note that yourServerName should be replaced by something else.

heroku create *yourServerName*
git push heroku master

The application should normally be online now! Now we just have to set the authentication variables on the server and set up the Alexa Skill.

Getting Plex Authentication Variables

In order to authenticate the PlexMusicPlayer application, two environmental variables need to be set, namely the Plex token and the base url.

First, you will need to navigate to plex.tv/web/app, select a random episode, show, etc. and click the three dots on the left (as shown in the picture below in Dutch). Next, right click the Download option and select copy link address.

The copied link address form should normally look something like this (with the parts filled in though):

https://your-plex-ip-address.some_long_encoded_string.plex.direct:your_plex_port/library/parts/some_id/some_file_id/file.ext?download=1&X-Plex-Token=your_plex_token

When looking at this long url, both needed variables can be extracted as following. It is important for the base url that the / after your_plex_port is not copied with.

base url = https://your-plex-ip-address.some_long_encoded_string.plex.direct:your_plex_port
Plex token = your_plex_token

Now, we have to set these environmental variables in our Heroku server. To do this, go back to the terminal (or command prompt) and enter the following lines, changed with your extracted variables.

heroku config:set PLEX_TOKEN=your_plex_token
heroku config:set PLEX_URL=https://your-plex-ip-address.some_long_encoded_string.plex.direct:your_plex_port

Lastly, we just have to restart the server so it can cope with the set environmental variables. To do this, just use the following command.

heroku restart

Optional Local URL Variable

If you choose to customise your setup and host Plex Music Player on the same network as your Plex server you can also set a PLEX_LOCAL_URL environment variable. This takes the same format as the PLEX_URL variable, but rather than using a publicly available URL for Plex it uses an address that is only accessible within the local network. This has the advantage of making searches much faster as they do not have to travel outside your network between different servers. The PLEX_URL variable still has to be set to a publicly available URL in order for Alexa to fetch the media being played.

export PLEX_LOCAL_URL=https://192.168.*.*.some_long_encoded_string.plex.direct:your_plex_port

192.168.. would be replaced by the IP address of the machine on which your Plex server is hosted.

Making the Alexa Skill

Now that the backend is fully up and running, the Alexa Skill has to be initialized on Amazon Developers. If you have not done this before, you can follow this step-by-step explenation.

As for the invocation name, I chose plexmusic. However, this can be anything you want. The information needed to fill in the Intent Schema and Sample Utterances can be found in the speech_assets folder.

Next, the endpoint needs to be set to HTTPS with the following link (with the yourServerName changed to the previously selected one)

https://*yourServerName*.herokuapp.com/plex

Lastly, select the 2nd option at certificate for endpoint and save your application.

Congratulations! PlexMusicPlayer is now up and running on your favorite Alexa device(s). Now, you are ready to try out some of its functionalities!

##The Functionalities Currently, PlexMusicPlayer is able to playback music based on a provided artist, album or song title. When an artist or album is provided and multiple songs are available for that artist or album in your Plex library, these will be queued and played as a playlist. Furthermore, it is possible to ask information related to the current song or to shuffle the current playlist. Obviously, requests such as next and play are also implemented. Some activation sentences are provided as an example below.

Alexa, ask plexmusic to play Def Leppard.
Alexa, ask plexmusic to play the album AM by Arctic Monkeys.
Alexa, ask plexmusic to tell me the name of this song.
Alexa, ask plexmusic to play “my favorites” playlist.

##The Future As this is only an initial implementation, there is a lot of room for improvement and extra functionality. Below is a list of some of the things I’d like to see implemented in the project. Please note that there is no distinction between minor and major improvements in these examples.

  • Enabling user authentication based on a Plex PIN (node.js implementation)
  • Implementing more playback functionalities, such as playback based on genre or year
  • Adding Alexa cards to show the requested song, album or artist with a picture
  • Making more intents, so the user can request specific actions such as what year the song is from Tracking of these future implementations are provided in the projects tab. User contributions and improvements are also welcome!

Hopefully, this guide was able to allow music playback from your Plex Media Server on Echo devices. If there are any issues or questions, please do not hesitate to open up an issue on GitHub.

plexmusicplayer's People

Contributors

jamesshaw1987 avatar kylebrandonwilson avatar tyzer34 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plexmusicplayer's Issues

Playing all tracks by an artist should shuffle songs

Up for discussion, but when I play everything by an artist I'd like all their songs to be shuffled rather than cycling through their albums in alphabetical order.

A separate intent ("shuffle [artist]"?) would be another option.

"I was not able to find Aerosmith in your library."

Hey Bjorn,

Any idea why Alexa can't find anything in my Plex library?

I've done everything, committed the code to Heroku, did the requested tweaking, and nothing... it's like my library contains 0 songs whereas it contains 17,000...

All responses look like this:

{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "I was not able to find Aerosmith in your library."
},
"shouldEndSession": true
},
"sessionAttributes": {}
}

Where should I start looking?

Thanks!

Shachar

Heroku alternative

As a result of Heroku become payable service, we need to find an alternative to.
I propose CapRover which could be hosted in own Raspberry pi.

I tried to deploy it on CapRover but I got 502 Nginx error.

May we could fix this or in someway collaborate to get a free alternative to Heroku?

Started only playing one song from the queue.

For about two weeks Alexa has only been playing one song from the queue. If I tell Alexa "Next" it will play the next song and then stop again. I added some logging and it appears to get to:-

@ask.on_playback_finished()
def play_back_finished(token):

and select the correct song and then go_next is called but no audio play. This was working so I guess it's something that has changed on Alexa.

plexMusicPlayer.txt

Log with flask-ask logging turned on
Log2.txt

Memory inconsistency with Flask

When requesting the song currently playing, it sometimes returns an outdated value, leading to belief there is some kind of memory inconsistency in the application.

Songs keep stopping

Hi,
Songs keep stopping before finished. Installed this on heroku (free) and songs start via utterances successfully.

Waking my app before playing using the heroku dashboard makes no difference. When songs abruptly stop, Echo Show continues to display "now playing" for a 5-10 seconds before going home. I can issue further utterances successfully (eg "alexa, resume playing" ), so songs appear to be paused rather than stopping completely, but same happens again upon resumption. I have no internet\wifi issues with this or other devices on this network. The time it stops at is inconsistent. Stopped 3m40s then 2m50 twice. Longest I've had is 4m40s. Songs shorter than this will successfully complete and play the next song, but this won't last as long.

Any ideas? Below is my app log from heroku. Are there any other logs I can supply to help diagnose?

2017-12-02T10:41:01.522644+00:00 heroku[web.1]: State changed from down to starting
2017-12-02T10:41:05.553632+00:00 heroku[web.1]: Starting process with command `waitress-serve --port=17974 server:application`
2017-12-02T10:41:07.902458+00:00 app[web.1]: /app/.heroku/python/lib/python3.5/site-packages/fuzzywuzzy/fuzz.py:35: UserWarning: Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning
2017-12-02T10:41:07.902483+00:00 app[web.1]:   warnings.warn('Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning')
2017-12-02T10:41:07.909538+00:00 app[web.1]: Serving on http://0.0.0.0:17974
2017-12-02T10:41:09.214010+00:00 heroku[web.1]: State changed from starting to up

I'm in the UK and we have no AMAZON.MusicCreativeWorkType, AMAZON.MusicGroup nor AMAZON.MusicAlbum slot types yet. I've used English (U.S.) Interaction model in an attempt to workaround. Could this be the cause?

I was not able to find {artist} in your library.

Hi,

I try to setup PlexMusicPlayer, but there is a constant problem:
Input Json from skill:
{ "session": { "new": false, "sessionId": "SessionId.9d42446e-36b6-4f95-88be-52f527526cbd", "application": { "applicationId": "amzn1.ask.skill.55b69e44-928e-458f-8694-78478aab2bac" }, "attributes": {}, "user": { "userId": "amzn1.ask.account.AGE6VWIL5OKDU2VVYFNZJ5IIZ5CUXJHKWCXKJHOJL5Y7EYRDTFSOWE4RBMO74XCJ3PDPOJ3IEVPMDZ6NA3XIGHUDMCTHQONH6GEYLPJSO3BD6Q7SYOO4Y7GTOCL2Z4KH2L2TBL4FQT5JNPV2IUSEZWH2GX4E5OHE7FVETJ3NOZSZDNI6N67KEXQHB6UXGWME4WBDBXJQ3BK37CI" } }, "request": { "type": "IntentRequest", "requestId": "EdwRequestId.286236d2-88d0-4035-8867-fed0f6e03204", "intent": { "name": "PlexPlayArtistIntent", "slots": { "artist": { "name": "artist", "value": "zorall" } } }, "locale": "en-US", "timestamp": "2017-08-26T16:25:25Z" }, "context": { "AudioPlayer": { "playerActivity": "IDLE" }, "System": { "application": { "applicationId": "amzn1.ask.skill.55b69e44-928e-458f-8694-78478aab2bac" }, "user": { "userId": "amzn1.ask.account.AGE6VWIL5OKDU2VVYFNZJ5IIZ5CUXJHKWCXKJHOJL5Y7EYRDTFSOWE4RBMO74XCJ3PDPOJ3IEVPMDZ6NA3XIGHUDMCTHQONH6GEYLPJSO3BD6Q7SYOO4Y7GTOCL2Z4KH2L2TBL4FQT5JNPV2IUSEZWH2GX4E5OHE7FVETJ3NOZSZDNI6N67KEXQHB6UXGWME4WBDBXJQ3BK37CI" }, "device": { "supportedInterfaces": {} } } }, "version": "1.0" }

an output is:
{ "version": "1.0", "response": { "outputSpeech": { "text": "I was not able to find zorall in your library.", "type": "PlainText" }, "speechletResponse": { "outputSpeech": { "text": "I was not able to find zorall in your library." }, "shouldEndSession": true } }, "sessionAttributes": {} }

Heroku log's always contains code 200:
2017-08-26T16:25:26.023728+00:00 heroku[router]: at=info method=POST path="/plex" host=plexmusichq.herokuapp.com request_id=9268e2c4-ad03-40ec-8a7e-58c807c0b5bd fwd="72.21.217.139" dyno=web.1 connect=1ms service=145ms status=200 bytes=334 protocol=https
Another info:
Tcpdump doesn't show anything traffic to my port 32400.
If i try to search manually in plex by curl, there is correct:

`
About to connect() to XX.XXXXXXXXXXX.hu port 32400 (#0)
Trying XX.XX.XX.XX...
connected
Connected to XX.XXXXXXXXX.hu (XX.XX.XX.XX) port 32400 (#0)
successfully set certificate verify locations:* CAfile: none
CApath: /etc/ssl/certs
SSLv3, TLS handshake, Client hello (1):
} [data not shown]
SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
SSLv3, TLS handshake, CERT (11):
{ [data not shown]
SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
SSLv3, TLS handshake, Finished (20):
} [data not shown]
SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
SSLv3, TLS handshake, Finished (20):
{ [data not shown]
SSL connection using ECDHE-RSA-AES128-GCM-SHA256
Server certificate:
subject: CN=XX.XXXXXXXXXXX.hu
start date: 2017-08-24 21:00:00 GMT
expire date: 2017-11-22 21:00:00 GMT
subjectAltName: XX.XXXXXXXXXXX.hu matched
issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
SSL certificate verify ok.

GET /search?query=zorall&X-Plex-Token=XXXXXXXXXXXXXXXXXXXXXX&type=10 HTTP/1.1
User-Agent: curl/7.26.0
Host: XX.XXXXXXXXX.hu:32400
Accept: /

additional stuff not fine transfer.c:1037: 0 0
HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Content-Type: text/xml;charset=utf-8
< Content-Length: 14042
< Connection: Keep-Alive
< Keep-Alive: timeout=20
< X-Plex-Protocol: 1.0
< Cache-Control: no-cache
< Date: Sat, 26 Aug 2017 16:33:45 GMT
<
{ [data not shown]

.... `

There aren't any more logs

Plex Music Deploy errors

First of all, this has been exactly what I've been looking to to. I want to be able to put on music using my echo. I saw this and was very excited to see that this application solves the problem. I tried to deploy the application to heroku (which I've never used before) and got it up and running. When I interact with the echo however, it times out. I was testing using hte service simulator on developer.amazon.com as well. A couple of questions first before I post the error:

  1. I have multiple plex clients running on my network and my plex server is a headless ubuntu server. What plex client is supposed to play when music is executed by the echo?
  2. From your instructions, you download a file from the server. The ip that is returned is the local ip of the server. I assume that I should be using the outside ip address instead of the local one as the call is coming from heroku.com? Is it possible to use a domain instead of an ip as I have DDNS setup?

Now the error:
I asked alexa: "ask plex to play counting stars" via the developer.amazon.com service simulator.

heroku logs:
Traceback (most recent call last):
2017-01-03T17:26:17.499331+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
2017-01-03T17:26:17.499332+00:00 app[web.1]: response = self.full_dispatch_request()
2017-01-03T17:26:17.499332+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request
2017-01-03T17:26:17.499333+00:00 app[web.1]: rv = self.handle_user_exception(e)
2017-01-03T17:26:17.499334+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2017-01-03T17:26:17.499334+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception
2017-01-03T17:26:17.499335+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
2017-01-03T17:26:17.499336+00:00 app[web.1]: raise value
2017-01-03T17:26:17.499336+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request
2017-01-03T17:26:17.499338+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request
2017-01-03T17:26:17.499339+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask_ask/core.py", line 516, in _flask_view_func
2017-01-03T17:26:17.499339+00:00 app[web.1]: result = self._map_intent_to_view_func(self.request.intent)()
2017-01-03T17:26:17.499337+00:00 app[web.1]: rv = self.dispatch_request()
2017-01-03T17:26:17.499338+00:00 app[web.1]: return self.view_functionsrule.endpoint
2017-01-03T17:26:17.499345+00:00 app[web.1]: speech, playlist = methods.processQuery(artist, MediaType.Artist)
2017-01-03T17:26:17.499340+00:00 app[web.1]: File "/app/plexmusicplayer/intents/plex_intents.py", line 26, in playArtist
2017-01-03T17:26:17.499346+00:00 app[web.1]: File "/app/plexmusicplayer/methods.py", line 80, in processQuery
2017-01-03T17:26:17.499346+00:00 app[web.1]: json_obj = getJsonFromPlex(searchQueryUrl)
2017-01-03T17:26:17.499347+00:00 app[web.1]: File "/app/plexmusicplayer/methods.py", line 23, in getJsonFromPlex
2017-01-03T17:26:17.499348+00:00 app[web.1]: response = requests.get(url)
2017-01-03T17:26:17.499348+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/requests/api.py", line 70, in get
2017-01-03T17:26:17.499349+00:00 app[web.1]: return request('get', url, params=params, **kwargs)
2017-01-03T17:26:17.499349+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/requests/api.py", line 56, in request
2017-01-03T17:26:17.499350+00:00 app[web.1]: return session.request(method=method, url=url, **kwargs)
2017-01-03T17:26:17.499351+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/requests/sessions.py", line 488, in request
2017-01-03T17:26:17.499351+00:00 app[web.1]: resp = self.send(prep, **send_kwargs)
2017-01-03T17:26:17.499352+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/requests/sessions.py", line 609, in send
2017-01-03T17:26:17.499353+00:00 app[web.1]: r = adapter.send(request, **kwargs)
2017-01-03T17:26:17.499353+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/requests/adapters.py", line 487, in send
2017-01-03T17:26:17.499354+00:00 app[web.1]: raise ConnectionError(e, request=request)
2017-01-03T17:26:17.499355+00:00 app[web.1]: requests.exceptions.ConnectionError: HTTPSConnectionPool(host='68.84.99.171.ee51a749bffb4ba6a60b868cba10a375.plex.direct', port=32400): Max retries exceeded with url: /search?query=counting%20stars&X-Plex-Token=&type=8 (Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f5d1b42fba8>: Failed to establish a new connection: [Errno -5] No address associated with hostname',))
2017-01-03T17:26:17.524319+00:00 heroku[router]: at=info method=POST path="/plex" host=alexaplexmusic.herokuapp.com request_id=d1abdda2-2a76-4e19-8fd5-075c7e3b5f9c fwd="72.21.217.104" dyno=web.1 connect=2ms service=179ms status=500 bytes=456

I'm not sure what that fwd ip is as that is not my external ip that is listed. Any idea?

Different results for two songs in the same album

Hi again,

There is a strange behavior related to indexing the songs, I guess. Please see the following two requests, for two songs from the same album (Dark side of the moon by Pink Floyd)

Successful request:
"alexa ask my pc to play the song money by pink floyd"

Request #1:
{
"session": {
"sessionId": "SessionId.ed583f0e-3820-4891-858f-1dd5e51bf2f0",
"application": {
"applicationId": "amzn1.ask.skill.7b83d8df-896f-4ea9-ac28-be42c5ce6665"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.AELT5B7UNT6V6R4NCALAGQKCP7BXUAYP6OGGOXTFGX6MA76ZSBAA3FBNZ5PZKDUSE2SJEZBPKGICO75R3WWVTHMN2D4HZQGQHCX4GOP42BJCPV3PNUR3KMKBG3DH672VMOEHHXFPF4DLFFLHBGBC7QRX7OLAFIQVXAZYZCMXIO7AXTSQWSXB6N7IRXQP3GD44U2ZCOH6E5MNR2Y"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.71a43879-0f08-4040-9def-91cb2f2072c7",
"locale": "en-US",
"timestamp": "2017-02-06T13:10:30Z",
"intent": {
"name": "PlexPlayTrackByArtistIntent",
"slots": {
"artist": {
"name": "artist",
"value": "pink Floyd"
},
"track": {
"name": "track",
"value": "money"
}
}
}
},
"version": "1.0"
}

Response:
{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "Playing Money by Pink Floyd from your PC."
},
"shouldEndSession": true
},
"sessionAttributes": {}
}

Unsuccessful request:
"alexa ask my pc to play the song time by pink floyd"

Request #2:

{
"session": {
"sessionId": "SessionId.3ae42441-56ea-48c4-9350-2799f5c3f64d",
"application": {
"applicationId": "amzn1.ask.skill.7b83d8df-896f-4ea9-ac28-be42c5ce6665"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.AELT5B7UNT6V6R4NCALAGQKCP7BXUAYP6OGGOXTFGX6MA76ZSBAA3FBNZ5PZKDUSE2SJEZBPKGICO75R3WWVTHMN2D4HZQGQHCX4GOP42BJCPV3PNUR3KMKBG3DH672VMOEHHXFPF4DLFFLHBGBC7QRX7OLAFIQVXAZYZCMXIO7AXTSQWSXB6N7IRXQP3GD44U2ZCOH6E5MNR2Y"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.a160fe85-c146-4b97-b379-9acb72b4f5f9",
"locale": "en-US",
"timestamp": "2017-02-06T13:16:56Z",
"intent": {
"name": "PlexPlayTrackByArtistIntent",
"slots": {
"artist": {
"name": "artist",
"value": "pink Floyd"
},
"track": {
"name": "track",
"value": "time"
}
}
}
},
"version": "1.0"
}

Unsuccessful response:

{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "I was not able to find time by pink Floyd in your library."
},
"shouldEndSession": true
},
"sessionAttributes": {}
}

Any ideas?

Pause and resume

Thoughts on supporting pause and resume of tracks across listening sessions? I'd love to be able to use this to play audiobooks and resume where I left off in the previous listening session.

Better handling of requests that fetch large amounts of tracks

This is something that only really applies when trying to play everything by an artist for whom you have a lot of albums/tracks.

If, for example, you have 20 albums by an artist, each containing 10 tracks, you'd have to make 221 requests (1 for the artist, 20 for the albums and 200 for the tracks) to Plex when using the "play artist" intent. This can obviously take a while to conplete, often longer than Alexa allows for the response.

Not sure of the best approach for handling this and I don't now Python well enough to know the options available. Add the first album to the queue and fetch the rest asynchronously maybe? Or pull back, say, 100 tracks and have some placeholder at the end of the queue telling it to fetch the next batch when it gets to that point? Or maybe just limit each request to ~100 tracks and let the user know that they'll have to be more specific to play others?

Band names should be parsed correctly

I've been testing some artists. I've noticed that the matching doesn't always find the artist I want. For instance the band OneRepublic is spelled without the space. But when you say the band, it is two separate words. I don't know if this can be pattern matched or not but thought I would list it as a bug/feature.

*Almost* working via Centos7+httpd+wsgi+ssl+python2.7

I'm so excited to get this working!! I'm not sure if you can help me, but everything is working: Httpd/SSL---->WSGI--->Plexmusicplayer (with correct permissions). I've been putting some print statements in my wsgi log to see if the URL is correct and it is. I see your script spitting out the correct XML MediaContainer when I request the artist/song, but amazon isn't seeing it for some reason and sending this response:

{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "I was not able to find blackened by Metallica in your library."
},
"shouldEndSession": true
},
"sessionAttributes": {}
}

Can you verify if this is correct modification in the methods.py file below? Basically, I just replaced the os.environ variables with my plex server info (which I have changed below for security):

stream_base_url = "https://999-9-9-9.029438lakfmlskfjlkjlsksfjdld472a45345345534.plex.direct:32400"
plex_token = "X-Plex-Token=" + "kalskfjdlsdkfjlsdkjslfdksdfsdf"
try:
base_url = "https://192-168-1-2.029438lakfmlskfjlkjlsksfjdld472a45345345534.plex.direct:32400"
except:
base_url = stream_base_url

Anything else I missed? Thoughts?

I'd be glad to help out with the project in any way! After I get this working, I'd be happy to provide documentation for those trying to set this up from scratch on their local boxes and skipping the third party (Heroku).

Suggest to loosen the dependency on fuzzywuzzy

Hi, your project plexMusicPlayer requires "fuzzywuzzy==0.14.0" in its dependency. After analyzing the source code, we found that some other versions of fuzzywuzzy can also be suitable without affecting your project, i.e., fuzzywuzzy 0.15.0. Therefore, we suggest to loosen the dependency on fuzzywuzzy from "fuzzywuzzy==0.14.0" to "fuzzywuzzy>=0.14.0,<=0.15.0" to avoid any possible conflict for importing more packages or for downstream projects that may use plexMusicPlayer.

May I pull a request to loosen the dependency on fuzzywuzzy?

By the way, could you please tell us whether such dependency analysis may be potentially helpful for maintaining dependencies easier during your development?



For your reference, here are details in our analysis.

Your project plexMusicPlayer(commit id: 8b4b4da) directly uses 1 APIs from package fuzzywuzzy.

fuzzywuzzy.process.extractOne

From which, 2 functions are then indirectly called, including 1 fuzzywuzzy's internal APIs and 1 outsider APIs, as follows (neglecting some repeated function occurrences).

[/Tyzer34/plexMusicPlayer]
+--fuzzywuzzy.process.extractOne
|      +--fuzzywuzzy.process.extractWithoutOrder
|      |      +--logging.warning

We scan fuzzywuzzy's versions among [0.15.0] and 0.14.0, the changing functions (diffs being listed below) have none intersection with any function or API we mentioned above (either directly or indirectly called by this project).

diff: 0.14.0(original) 0.15.0
['fuzzywuzzy.utils.validate_string', 'fuzzywuzzy.fuzz.WRatio', 'fuzzywuzzy.fuzz.QRatio', 'fuzzywuzzy.fuzz.UQRatio']

As for other packages, the APIs of @outside_package_name are called by fuzzywuzzy in the call graph and the dependencies on these packages also stay the same in our suggested versions, thus avoiding any outside conflict.

Therefore, we believe that it is quite safe to loose your dependency on fuzzywuzzy from "fuzzywuzzy==0.14.0" to "fuzzywuzzy>=0.14.0,<=0.15.0". This will improve the applicability of plexMusicPlayer and reduce the possibility of any further dependency conflict with other projects/packages.

Fork

I ended up forking your code base mostly because I wanted to change the intents. I fixed a couple bugs in the methods.py when tracks, artists, and albums return multiple results. I just take the first one in the list and send it on its way. Here is the link if you want to see the code. I can push to your repo too if you would like.

https://github.com/tdelesio/plexMusicPlayer/blob/master/plexmusicplayer/methods.py

I also added two separate intents. From my testing, it seamed that the intents were getting confused. I would be asking for a track and/or album, and amazon thought I was looking for an artist. To try and make it less confused I added two more intents. Is there a better way to test this locally? I have been pushing to herkou everything but it is slow. I launched the server.py file locally and tried to post the json from the service simulator, but it gave me some token error (not the environment variables token).

Numbers in names

I found another issue too where bands with numbers in them aren't found. For example twenty one pilots. I don't know if this is the translation of the number or not. When I get some more time I will investigate this further.

Unable to find my library

Hey first off thanks for doing this if i can get it working it will be awesome.
Following the instructions Alexa keeps timing out. I set up heroku and did all the steps. When i say "Alexa ask plex" She responds with plexmusic welcome message. When i ask to play a song it always comes back with "The requested skill took too long to respond".
When testing the skill in amazon dev tab.
"ask plex play song cumbersome" i receive The remote endpoint could not be called, or the response it returned was invalid.
i set up both Plex URL and Local URL. I am not sure where to go from here. Any help would be greatly appreciated. Thanks

I am impressed by this

Not an issue! Just wanted to express myself by saying this is really cool! Nice initiative 😸

Using waitress might prove to be too slow

When asking for playback of a certain artist, it takes quite a long time to fetch the results. This frequently ends up in a timeout, as there is only a 10s gap to respond back to the Echo Dot.
Asking the same query for a second time, gives back a response quickly, as most of the data is already cached.

newb help

hi can someone assist me on the part with creating skill in alexa console ..how to set up the intents etc

Can't get playback working on 2nd Gen Dot

I can't get the echo to queue up any songs or play any songs. Any ideas on what I might be doing wrong?

First request works;
"Alexa open Plex Music"
2017-05-27T13:22:29.204944+00:00 heroku[router]: at=info method=POST path="/plex" host=eric-plex-echo.herokuapp.com request_id=18265e92-9af4-4b9b-a2b1-582c3640c55d fwd="72.21.217.141" dyno=web.1 connect=0ms service=52ms status=200 bytes=473 protocol=https

but the i get an error when I ask to play something;
"Play Janet Jackson"
2017-05-27T13:22:37.750753+00:00 heroku[router]: at=info method=POST path="/plex" host=eric-plex-echo.herokuapp.com request_id=d1135be3-5047-448f-835d-d59557d79234 fwd="72.21.217.141" dyno=web.1 connect=0ms service=2122ms status=200 bytes=610 protocol=https
2017-05-27T13:22:37.930617+00:00 heroku[router]: at=info method=POST path="/plex" host=eric-plex-echo.herokuapp.com request_id=a5904f35-09a4-47ee-ab83-bd2e8786daad fwd="72.21.217.141" dyno=web.1 connect=0ms service=83ms status=500 bytes=449 protocol=https
2017-05-27T13:22:37.898075+00:00 app[web.1]: [2017-05-27 13:22:37,897] ERROR in app: Exception on /plex [POST]
2017-05-27T13:22:37.898095+00:00 app[web.1]: Traceback (most recent call last):
2017-05-27T13:22:37.898099+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
2017-05-27T13:22:37.898100+00:00 app[web.1]: response = self.full_dispatch_request()
2017-05-27T13:22:37.898101+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request
2017-05-27T13:22:37.898102+00:00 app[web.1]: rv = self.handle_user_exception(e)
2017-05-27T13:22:37.898102+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception
2017-05-27T13:22:37.898103+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2017-05-27T13:22:37.898104+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
2017-05-27T13:22:37.898105+00:00 app[web.1]: raise value
2017-05-27T13:22:37.898105+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request
2017-05-27T13:22:37.898106+00:00 app[web.1]: rv = self.dispatch_request()
2017-05-27T13:22:37.898107+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request
2017-05-27T13:22:37.898108+00:00 app[web.1]: return self.view_functionsrule.endpoint
2017-05-27T13:22:37.898109+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask_ask/core.py", line 499, in _flask_view_func
2017-05-27T13:22:37.898110+00:00 app[web.1]: self._update_stream()
2017-05-27T13:22:37.898111+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask_ask/core.py", line 468, in _update_stream
2017-05-27T13:22:37.898111+00:00 app[web.1]: fresh_stream.dict.update(self._from_context())
2017-05-27T13:22:37.898117+00:00 app[web.1]: TypeError: 'NoneType' object is not iterable
2017-05-27T13:22:37.898198+00:00 app[web.1]: ERROR:plexmusicplayer:Exception on /plex [POST]
2017-05-27T13:22:37.898200+00:00 app[web.1]: Traceback (most recent call last):
2017-05-27T13:22:37.898200+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
2017-05-27T13:22:37.898201+00:00 app[web.1]: response = self.full_dispatch_request()
2017-05-27T13:22:37.898202+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request
2017-05-27T13:22:37.898203+00:00 app[web.1]: rv = self.handle_user_exception(e)
2017-05-27T13:22:37.898203+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception
2017-05-27T13:22:37.898204+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2017-05-27T13:22:37.898205+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
2017-05-27T13:22:37.898205+00:00 app[web.1]: raise value
2017-05-27T13:22:37.898206+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request
2017-05-27T13:22:37.898207+00:00 app[web.1]: rv = self.dispatch_request()
2017-05-27T13:22:37.898208+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request
2017-05-27T13:22:37.898208+00:00 app[web.1]: return self.view_functionsrule.endpoint
2017-05-27T13:22:37.898209+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask_ask/core.py", line 499, in _flask_view_func
2017-05-27T13:22:37.898210+00:00 app[web.1]: self._update_stream()
2017-05-27T13:22:37.898210+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/flask_ask/core.py", line 468, in _update_stream
2017-05-27T13:22:37.898211+00:00 app[web.1]: fresh_stream.dict.update(self._from_context())
2017-05-27T13:22:37.928737+00:00 app[web.1]: TypeError: 'NoneType' object is not iterable

Cannot find anything in library, and errors on status

I have the app deployed in heroku, I updated a lot of the required packages to their latest versions. I am able to get the service to start and it will respond to requests using the Alexa skills dashboard, but it never finds anything from my library.

Example: Using the utterance "play songs by radiohead" returns "I was not able to find radiohead in your library." Heroku logs show the request status 200.

If I use the utterance "give me a status update" i get a 500 status error and the heroku logs show errors:

2017-08-31T15:00:49.455022+00:00 heroku[router]: at=info method=POST path="/plex" host=jmahlman-plex.herokuapp.com request_id=12cc5ddf-77b8-4ad6-a3b3-ba26c93d36c3 fwd="72.21.217.77" dyno=web.1 connect=0ms service=97ms status=500 bytes=449 protocol=https
2017-08-31T15:00:49.454057+00:00 app[web.1]: [2017-08-31 15:00:49,453] ERROR in app: Exception on /plex [POST]
2017-08-31T15:00:49.454076+00:00 app[web.1]: Traceback (most recent call last):
2017-08-31T15:00:49.454078+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
2017-08-31T15:00:49.454079+00:00 app[web.1]: response = self.full_dispatch_request()
2017-08-31T15:00:49.454080+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
2017-08-31T15:00:49.454081+00:00 app[web.1]: rv = self.handle_user_exception(e)
2017-08-31T15:00:49.454082+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
2017-08-31T15:00:49.454082+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2017-08-31T15:00:49.454083+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
2017-08-31T15:00:49.454084+00:00 app[web.1]: raise value
2017-08-31T15:00:49.454085+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
2017-08-31T15:00:49.454085+00:00 app[web.1]: rv = self.dispatch_request()
2017-08-31T15:00:49.454086+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
2017-08-31T15:00:49.454087+00:00 app[web.1]: return self.view_functionsrule.endpoint
2017-08-31T15:00:49.454088+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask_ask/core.py", line 629, in _flask_view_func
2017-08-31T15:00:49.454089+00:00 app[web.1]: result = self._map_intent_to_view_func(self.request.intent)()
2017-08-31T15:00:49.454089+00:00 app[web.1]: File "/app/plexmusicplayer/intents/plex_intents.py", line 93, in status
2017-08-31T15:00:49.454090+00:00 app[web.1]: return statement(queue.status)
2017-08-31T15:00:49.454090+00:00 app[web.1]: File "/app/plexmusicplayer/utils.py", line 19, in status
2017-08-31T15:00:49.454091+00:00 app[web.1]: ' | Current Song is ' + str(self.current) + " | Songs left to Play are: "
2017-08-31T15:00:49.454091+00:00 app[web.1]: File "/app/plexmusicplayer/utils.py", line 34, in current
2017-08-31T15:00:49.454091+00:00 app[web.1]: return self._playlist[self._counter.value]
2017-08-31T15:00:49.454095+00:00 app[web.1]: IndexError: list index out of range

Resuming playback failure

Resuming the song, restarts the song currently being played. Also, due to the memory inconsistency problem, it sometimes returns a NullType object, which is not yet handled.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.