Giter Club home page Giter Club logo

gmusicproxy's Introduction

GMusicProxy - Google Play Music Proxy

"Let's stream Google Play Music using any media-player"

GitHub release (latest SemVer) Python Versions

contributors:

License: GPL v3

About

This program permits the use of Google Play Music with All Access subscription with any music player that is able to stream MP3 files and to manage playlists (e.g., MPD server, VLC, ...). It can work also with a free account without All Access extras.

Google has a music service with the possibility to stream all the available music using an All Access subscription. The Google-way to listen your collection and the stations is by means of Android devices, web browser, or Chromecast devices to integrate with TVs or HiFi audio systems. These devices are typically closed or limited in someway. Many people use music-systems based on Raspberry-PIs, MPD, or other software and GMP provide an integration point.

The project is based on the great Unofficial Google Play Music API by Simon Weber: it already permits to create URLs to stream the tracks as regular MP3 but they expire in 1 minute! Keeping this proxy running, it can generate persistent local URLs that never expire and that can be used in any media-player.

This project is not supported nor endorsed by Google. Its aim is not the abuse of the service but the one to improve the access to it. The maintainers are not responsible for misuse.

Features

  • create persistent URLs to all the tracks, albums and stations available on the Google Play Music + All Access platform
  • get access to all the songs in your collection, playlists and registered stations
  • search by name any artist, album or song
  • request a transient (it will be not registered in your account) station based on any search (a.k.a. "Instant Mix")
  • stream any songs as standard MP3 complete of IDv3 tag with all the information and album image

URL-based interface

The only way to use the service is to query the proxy by means of properly formatted HTTP requests over the configured TCP port. Such URLs can be used directly in music programs or in scripts or in any browser. A URL looks like this: http://host:port/command?param_1=value&param_2=value. Validation on submitted values is minimal, please be aware.

Consider that any song, album, artist, playlist or station got a unique ID in Google Music API but there are many methods to discover them.

Here a list of the supported requests (with some restricted by the availability of a All Access subscription):

  • /get_collection: reports a playlist with all the songs in your personal collection; the resulting list can be shuffled and/or filtered using the rating; note that not all the rated (liked) songs belong to your collection. Allowed parameters:
    • See common request options
    • rating: an integer value (typically between 1-5) to filter out low rated or unrated songs form your collection
  • /search_id: reports the unique ID as result of a search for an artist, a song or an album. Allowed parameters:
    • type: search for artist, album or song [required]
    • title: a string to search in the title of the album or of the song
    • artist: a string to search in the name of the artist in any kind of search
    • exact: a yes implies an exact match between the query parameters artist and title and the real data of the artist/album/song [default: yes]
    • See common request options
  • /get_by_search: makes a search for artist/album/song as /search_id and returns the related content (a list for the album or for the top songs of an artist and the MP3 file for a song); it is also possible to get the full list of matches reported by Google Music using search with type=matches [requires A.A.]. Allowed parameters:
    • type: search for artist, album, song or matches [required]
    • title: a string to search in the title of the album or of the song
    • artist: a string to search in the name of the artist in any kind of search
    • exact: a yes implies an exact match between the query parameters artist and title and the real data of the artist/album/song; it doesn't make sense with a search for matches [default: no]
    • See common request options
  • /get_all_stations: reports a list of registered stations as a playlist (with URLs to each station playlist) [requires A.A.]. Allowed parameters:
    • exact: a yes implies an exact match between the query parameters artist and title and the real data of the artist/album/song [default: no]
    • See common request options
  • /get_all_playlists: reports the playlists registered in the account as playlist (with URLs to other playlist) The allowed parameters are the same as /get_all_stations.
  • /get_new_station_by_search: returns a playlist containing songs from a new (transient or permanent) station created on the result of a search for artist/album/song (a.k.a. "Instant Mix") [requires A.A.]. Allowed parameters:
    • type: search for artist, album or song [required]
    • title: a string to search in the title of the album or of the song
    • artist: a string to search in the name of the artist in any kind of search
    • exact: a yes implies an exact match between the query parameters artist and title and the real data of the artist/album/song [default: no]
    • transient: a no creates a persistent station that will be registered into the account [default: yes]
    • name: the name of the persistent station to create [required if transient is no]
    • See common request options
  • /get_new_station_by_id: returns a playlist containing tracks from a new (transient or permanent) station created on a specified id of an artist/album/song [requires A.A.]. Allowed parameters:
    • id: the unique identifier of the artist/album/song [required]
    • type: the type of id specified among artist, album and song [required]
    • transient: a no creates a persistent station that will be registered into the account [default: yes]
    • name: the name of the persistent station to create [required if transient is no]
    • See common request options
  • /get_station: reports a playlist of tracks associated to the given station [requires A.A.]. Allowed parameters:
  • /get_ifl_station: reports a playlist of tracks associated to the automatic "I'm feeling lucky" station [requires A.A.]. Allowed parameters:
  • /get_playlist: reports the content of a registered playlist Allowed parameters:
  • /get_album: reports the content of an album as a playlist. Allowed parameters:
  • /get_song: streams the content of the specified song as a standard MP3 file with IDv3 tag. Allowed parameters:
    • id: the unique identifier of the song [required]
  • /get_song_info: returns JSON Metadata for the specified song. Allowed parameters:
    • id: the unique identifier of the song [required]
  • /get_top_tracks_artist: reports a playlist with the top songs of a specified artist [requires A.A.]. Allowed parameters:
    • id: the unique identifier of the artist [required]
    • type: the type of id specified among artist, album and song [required]
    • See common request options
  • /get_discography_artist: reports the list of available albums of a specified artist as a playlist (with URLs to other playlists) or as plain-text list (with one album per line) [requires A.A.]. Allowed parameters:
  • /get_top_songs: Returns a playlist of top songs
  • /get_situations: Returns a collection of situations, e.g. Today's biggest hits
  • /get_listen_now: Provides 'Listen Now' playlists by either album or artist. Allowed Parameters:
  • /get_listen_now_list: Call for specific Listen Now playlist
  • /like_song: reports a positive rating on the song with specified id. Allowed parameters:
    • id: the unique identifier of the song [required]
  • /dislike_song: reports a negative rating on the song with specified id. Allowed parameters:
    • id: the unique identifier of the song [required]
  • /get_version: displays current version in JSON format

Common request options

The proxy supports common options for responses:

  • format or HTTP Accept header: See Output Format
  • shuffle: Set to yes to shuffle the list [default: no]
  • num_tracks: Maximum number of items to return. If shuffle is set to yes, shuffle is applied prior to limiting the results.

Note: these parameters are not valid for get_song.

Examples:

# request XSPF/XML format
curl http://[gmp host|ip]:9999/get_all_playlists?format=xsfp
# request shuffled output
curl http://[gmp host|ip]:9999/get_all_playlists?shuffle=yes
# Return playlist with 10 items
curl http://[gmp host|ip]:9999/get_all_playlists?num_tracks=10

Output Format

Beginning with version 2.2.0, Accept headers should be the preferred way to request a specific output format. e.g. for JSON:

curl -H 'Accept: application/json' http://[gmp host|ip]:9999/get_all_playlists

The format parameter can be used to generate output in the following formats:

  • m3u: Generates an M3U formatted list.
  • xm3u: lines of the produced M3U lists to a non-standard format like artist - song title - album title
  • text|txt: for a plain-text list with lines like Name of the Station|URL to a song or playlist
    • separator: when requesting text formatted output, the separator to delineate fields [default: |]
    • only_url: a yes creates a list of just URLs in the plain-text lists (the name of the album is totally omitted) [default: no]
  • xspf|xml: Returns an XSPF formatted playlist
  • json: Returns a json formatted playlist following the XSPF json format

Changelog

  • See RELEASES.md for release information.

Related projects

Support

Issues

Feel free to open bug reports (complete of verbose output produced with options --debug and --log) on GitHub, to fork the project and to make pull requests for your contributions.

Setup

Requirements

  • a Google Play Music account with All Access subscription (some functionalities continue to work even with a free account)
  • a Python 3.8 interpreter.
  • some python libs, see setup.py

Installation

The following instructions have a Debian/Ubuntu GNU/Linux system as reference: nevertheless they work on any other GNU/Linux system using the right substitute of apt-get. It is known to work also on Mac OS X and Windows systems.

In order to build/install GMusicProxy, the following should work on Ubuntu/Debian based systems:

sudo apt install python3 python3-dev git
git clone https://github.com/gmusicproxy:/gmusicproxy.git
cd gmusicproxy
virtualenv -p python3.8 venv
. venv/bin/activate
pip install -r requirements.txt
python GMusicProxy
  • The pip install command could require the options --allow-external eyed3 --allow-unverified eyed3 on some systems in order to validate the installation of eyed3.

Usage

With the service running on a computer on the LAN, it can be used by any others of the same network.

To use the proxy, you first need to login via OAuth2. If you haven't authorized gmusicapi yet (or the credentials were revoked or deleted), when you first launch GMusicProxy, your browser will open letting you login and authorize gmusicapi. If no browser is available, the URL printed out can be used to login. After this, OAuth2 credentials (not your email and password) are cached to disk so future uses don't require you to login again.

Another useful information would be the device ID of an Android/iOS device registered in your account: you can discover it using the option --list-devices on the command-line. As default a fake-id, based on the mac address of the main network card of the server running the service, is used.

You can provide such necessary information, as well as other options, on the command-line of the program or using a configuration file.

Command-line

Here a list of the supported options on the command-line:

  • --email: [DEPRECATED] email address of the Google account
  • --password: [DEPRECATED] password of the Google account
  • --device-id: the ID of a registered Android/iOS device [default: fake-id based on mac address of network card]
  • --host: host in the generated URLs [default: autodetected local ip address]
  • --host-port: port in the generated URLs [default: -P or 9999]
  • --bind-address: ip address to bind to [default: 0.0.0.0=all]
  • --port: default TCP port to use [default: 9999]
  • --config: specific configuration file to use
  • -F DEFAULT_FORMAT, --default-format DEFAULT_FORMAT: Sets the defualut output format
  • --disable-all-access: disable All Access functionalities
  • --list-devices: list the registered devices
  • --debug: enable debug messages
  • --log: log file
  • --daemon: daemonize the program
  • --disable-version-check: disable check for latest available version
  • --shoutcast-metadata: enable Shoutcast metadata protocol support (disabling IDv3 tags)
  • --disable-playcount-increment: disable the automatic increment of playcounts upon song fetch
  • --keyring-backend: [DEPRECATED] name of the keyring backend to use instead of the default one
  • --list-keyring-backends: [DEPRECATED] list the available keyring backends
  • --keyring-service: [DEPRECATED] keyring service to use, takes precedence over --password if set
  • --keyring-entry: [DEPRECATED] keyring entry to use, required if --keyring-service is used

Config file

All the command-line options can be specified in a configuration file. An example of configuration with the strictly required options could look like this:

email = [email protected]
password = my-secret-password
device-id = 54bbd32a309a34ef

When the proxy is launched, it searches for a file named gmusicproxy.cfg in the XDG-compliant folders like /home/USER/.config/ or /etc/xdg/. It is possible to specify an arbitrary config file on the command-line using the option --config.

Examples of integration

You can copy any M3U list generated by the proxy in the playlists registered inside MPD. MPD usually keeps the playlists inside the folder specified by playlist_directory in its configuration file mpd.conf.

curl -s 'http://localhost:9999/get_by_search?type=album&artist=Queen&title=Greatest%20Hits' > /var/lib/mpd/playlists/queen.m3u
mpc load queen
mpc play

You can also request a fresh list of songs from a station and add them to the current playlist.

mpc clear
curl -s 'http://localhost:9999/get_new_station_by_search?type=artist&artist=Queen&num_tracks=100' | grep -v "^#" | while read url; do mpc add "$url"; done
mpc play

You can add an XSPF playlist to mpd, which provides better metadata:

mpc load "http://localhost:9999/get_top_songs?format=xspf"

You can listen any generated playlist using VLC from command-line.

vlc 'http://localhost:9999/get_by_search?type=album&artist=Rolling%20Stones&title=tattoo&exact=no'

With the addition of XSPF playlists, better metadata is provided:

vlc 'http://localhost:9999/get_top_songs?format=xspf'

You can automatically choose at random one registered station.

curl -s 'http://localhost:9999/get_all_stations?format=text&only_url=yes' | sort -R | head -n1 | vlc -

Official Docker builds are available on Docker Hub. To build and run the Docker container, follow these steps:

docker build -t gmusicproxy:latest .
# Note that OAuth is the preferred login method 
# You may need to run interactively (-it) in order to
# establish your credentials.
# Replace /path/for/oauthcreds with a directory for oauth token storage
docker run -it -p 9999:9999 -v /path/for/oauthcreds:/root/.local/share/gmusicapi gmusicproxy:latest
# Once OAuth is established, run normally:
docker run -v /path/for/oauthcreds:/root/.local/share/gmusicapi -p 9999:9999 gmusicproxy:latest

Other Docker Examples

Running as daemon

docker run -d -p 9999:9999 -v /path/for/oauthcreds:/root/.local/share/gmusicapi gmusicproxy/gmusicproxy:VERSION

Running on port 80 with a different Host/IP in the URLs. Note the required -T argument

docker run -p 80:9999 -v /path/for/oauthcreds:/root/.local/share/gmusicapi gmusicproxy/gmusicproxy:VERSION -T 80

gmusicproxy's People

Contributors

a-irs avatar abusenius avatar arressjay avatar bryant1410 avatar cooloppo avatar jdwoody avatar jgrocho avatar lambdaloop avatar luzifer avatar mario-tux avatar mlmlte avatar nickdepinet avatar poket-jony avatar redlulz 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gmusicproxy's Issues

Add Album information in playlist items

Doing curl -s 'http://localhost:9999/get_by_search?type=album&artist=Madona' | head -10 returns :

#EXTM3U
#EXTINF:308,Madonna - Drowned World/Substitute For Love
http://192.168.77.100:9999/get_song?id=Trjxwcxok7od6k37vvj6p6mjbza
#EXTINF:300,Madonna - Swim
http://192.168.77.100:9999/get_song?id=T5trkvowie77ghuslcaqhs6edhu
#EXTINF:320,Madonna - Ray of Light
http://192.168.77.100:9999/get_song?id=Tbzgbzqjtuwqyywlbqbcnn65ac4
#EXTINF:276,Madonna - Candy Perfume Girl
http://192.168.77.100:9999/get_song?id=Tzzta3bwusnr3bsv6el35x4hwp4

But you can not easily know from which album are those songs.
It would be very nice to have this piece of information available. Would it be technically possible ?

SSL Certificate Verification Error

I only started getting this error in the past few days. I have compiled and run gmusicproxy on a beaglebone with an attached USB audio dongle, with great success, on Debian Wheezy, for several weeks over many boot cycles. Then I started getting error messages about authentication problems.

I hadn't messed with the settings since I got everything working. The beaglebone launches a systemd service on boot that connects to a script launched at the end of boot which begins playing random punk music from a Google All Access station. I'll send a pull request for the systemd feature when the code is cleaner.

If I read the debug output (below) correctly, Google authenticates me and my "device" correctly, but python is throwing a certificate verification error, killing the process.

debian@arm:~/gmusicproxy$ GMusicProxy --email [email protected] --password [redacted] --device-id [redacted] --debug
Google Play Music Proxy 0.9.5 (© Mario Di Raimondo)

configuration used:
{'config': None,
'daemon': False,
'debug': True,
'device_id': '[redacted] ',
'disable_all_access': False,
'disable_version_check': False,
'email': '[email protected]',
'host': 'auto',
'list_devices': False,
'log': None,
'password': '_OMITTED_',
'port': 9999}

ClientLogin()
Traceback (most recent call last):
File "/usr/local/bin/GMusicProxy", line 595, in
api = loginGM(config['email'], config['password'])
File "/usr/local/bin/GMusicProxy", line 504, in loginGM
api.login(email, password)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 39, in login
if not self.session.login(email, password):
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 147, in login
success = super(Mobileclient, self).login(email, password, _args, _kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 107, in login
res = ClientLogin.perform(self, True, email, password)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/protocol/shared.py", line 208, in perform
response = session.send(req_kwargs, cls.required_auth)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 75, in send
res = self._send_without_auth(req_kwargs, new_session)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 42, in _send_without_auth
return rsession.request(
_req_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 456, in request
resp = self.send(prep, *_send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 559, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 382, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

If this is in fact a python problem, what might be the workaround? Is it commenting out the certificate verification part of gmusicproxy (I understand the implications of this)? Is it a different python package/version/etc.? Is it something else entirely, and I going down the wrong path?

Best regards,
Blake

Unable to install dependencies

Hi there. I'm trying to install gmusicproxy on ubuntu(with vagrant) and get this errors:

vagrant@vagrant-ubuntu:~/gmusicproxy$ sudo pip install -r requirements.txt
Obtaining file:///home/vagrant/gmusicproxy (from -r requirements.txt (line 3))
  Running setup.py egg_info for package from file:///home/vagrant/gmusicproxy

Downloading/unpacking gmusicapi>=6.0.0 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package gmusicapi

    warning: no previously-included files matching '_local_*.py' found anywhere in distribution
Downloading/unpacking netifaces>=0.10.4 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package netifaces

Downloading/unpacking pyxdg>=0.25 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package pyxdg

Downloading/unpacking eyed3>=0.7.8 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package eyed3
    warning: no previously-included files matching '*' found under directory 'docs/_build'
Downloading/unpacking python-daemon>=2.0.5 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package python-daemon

    Traceback (most recent call last):
      File "<string>", line 14, in <module>
      File "/home/vagrant/gmusicproxy/build/python-daemon/setup.py", line 97, in <module>
        "Topic :: Software Development :: Libraries :: Python Modules",
      File "/usr/lib/python2.7/distutils/core.py", line 152, in setup
        dist.run_commands()
      File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
        self.run_command(cmd)
      File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
        cmd_obj.run()
      File "version.py", line 500, in run
        self.run_command(command_name)
      File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command
        self.distribution.run_command(command)
      File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
        cmd_obj.run()
      File "version.py", line 538, in run
        version_info = generate_version_info_from_changelog(self.changelog_path)
      File "version.py", line 414, in generate_version_info_from_changelog
        versions_all_json = changelog_to_version_info_collection(infile)
      File "version.py", line 369, in changelog_to_version_info_collection
        import docutils.core
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/core.py", line 20, in <module>
        from docutils import frontend, io, utils, readers, writers
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/frontend.py", line 41, in <module>
        import docutils.utils
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/__init__.py", line 20, in <module>
        import docutils.io
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/io.py", line 18, in <module>
        from docutils.utils.error_reporting import locale_encoding, ErrorString, ErrorOutput
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/error_reporting.py", line 47, in <module>
        locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]
      File "/usr/lib/python2.7/locale.py", line 503, in getdefaultlocale
        return _parse_localename(localename)
      File "/usr/lib/python2.7/locale.py", line 435, in _parse_localename
        raise ValueError, 'unknown locale: %s' % localename
    ValueError: unknown locale: UTF-8
    Complete output from command python setup.py egg_info:
    running egg_info

writing requirements to pip-egg-info/python_daemon.egg-info/requires.txt

writing pip-egg-info/python_daemon.egg-info/PKG-INFO

writing top-level names to pip-egg-info/python_daemon.egg-info/top_level.txt

writing dependency_links to pip-egg-info/python_daemon.egg-info/dependency_links.txt

warning: manifest_maker: standard file '-c' not found



reading manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'

reading manifest template 'MANIFEST.in'

writing manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'

running write_version_info

Traceback (most recent call last):

  File "<string>", line 14, in <module>

  File "/home/vagrant/gmusicproxy/build/python-daemon/setup.py", line 97, in <module>

    "Topic :: Software Development :: Libraries :: Python Modules",

  File "/usr/lib/python2.7/distutils/core.py", line 152, in setup

    dist.run_commands()

  File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands

    self.run_command(cmd)

  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command

    cmd_obj.run()

  File "version.py", line 500, in run

    self.run_command(command_name)

  File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command

    self.distribution.run_command(command)

  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command

    cmd_obj.run()

  File "version.py", line 538, in run

    version_info = generate_version_info_from_changelog(self.changelog_path)

  File "version.py", line 414, in generate_version_info_from_changelog

    versions_all_json = changelog_to_version_info_collection(infile)

  File "version.py", line 369, in changelog_to_version_info_collection

    import docutils.core

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/core.py", line 20, in <module>

    from docutils import frontend, io, utils, readers, writers

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/frontend.py", line 41, in <module>

    import docutils.utils

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/__init__.py", line 20, in <module>

    import docutils.io

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/io.py", line 18, in <module>

    from docutils.utils.error_reporting import locale_encoding, ErrorString, ErrorOutput

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/error_reporting.py", line 47, in <module>

    locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]

  File "/usr/lib/python2.7/locale.py", line 503, in getdefaultlocale

    return _parse_localename(localename)

  File "/usr/lib/python2.7/locale.py", line 435, in _parse_localename

    raise ValueError, 'unknown locale: %s' % localename

ValueError: unknown locale: UTF-8

----------------------------------------
Command python setup.py egg_info failed with error code 1
Storing complete log in /home/vagrant/.pip/pip.log
$ cat /home/vagrant/.pip/pip.log
------------------------------------------------------------
/usr/bin/pip run on Mon Aug  3 11:16:42 2015
Obtaining file:///home/vagrant/gmusicproxy (from -r requirements.txt (line 3))
  Running setup.py egg_info for package from file:///home/vagrant/gmusicproxy
    running egg_info
    writing requirements to gmusicproxy.egg-info/requires.txt
    writing gmusicproxy.egg-info/PKG-INFO
    writing top-level names to gmusicproxy.egg-info/top_level.txt
    writing dependency_links to gmusicproxy.egg-info/dependency_links.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'gmusicproxy.egg-info/SOURCES.txt'
    writing manifest file 'gmusicproxy.egg-info/SOURCES.txt'
Downloading/unpacking gmusicapi>=6.0.0 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package gmusicapi
    running egg_info
    writing requirements to pip-egg-info/gmusicapi.egg-info/requires.txt
    writing pip-egg-info/gmusicapi.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/gmusicapi.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/gmusicapi.egg-info/dependency_links.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'pip-egg-info/gmusicapi.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no previously-included files matching '_local_*.py' found anywhere in distribution
    writing manifest file 'pip-egg-info/gmusicapi.egg-info/SOURCES.txt'
  Source in ./build/gmusicapi has version 6.0.0, which satisfies requirement gmusicapi>=6.0.0 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
Downloading/unpacking netifaces>=0.10.4 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package netifaces
    running egg_info
    writing pip-egg-info/netifaces.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/netifaces.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/netifaces.egg-info/dependency_links.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'pip-egg-info/netifaces.egg-info/SOURCES.txt'
    writing manifest file 'pip-egg-info/netifaces.egg-info/SOURCES.txt'
  Source in ./build/netifaces has version 0.10.4, which satisfies requirement netifaces>=0.10.4 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
Downloading/unpacking pyxdg>=0.25 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package pyxdg
    running egg_info
    writing pip-egg-info/pyxdg.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/pyxdg.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/pyxdg.egg-info/dependency_links.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'pip-egg-info/pyxdg.egg-info/SOURCES.txt'
    writing manifest file 'pip-egg-info/pyxdg.egg-info/SOURCES.txt'
  Source in ./build/pyxdg has version 0.25, which satisfies requirement pyxdg>=0.25 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
Downloading/unpacking eyed3>=0.7.8 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package eyed3
    running egg_info
    writing pip-egg-info/eyeD3.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/eyeD3.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/eyeD3.egg-info/dependency_links.txt
    reading manifest file 'pip-egg-info/eyeD3.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    writing manifest file 'pip-egg-info/eyeD3.egg-info/SOURCES.txt'
  Source in ./build/eyed3 has version 0.7.8, which satisfies requirement eyed3>=0.7.8 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
Downloading/unpacking python-daemon>=2.0.5 (from gmusicproxy==1.0.2->-r requirements.txt (line 3))
  Running setup.py egg_info for package python-daemon
    running egg_info
    writing requirements to pip-egg-info/python_daemon.egg-info/requires.txt
    writing pip-egg-info/python_daemon.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/python_daemon.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/python_daemon.egg-info/dependency_links.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'
    running write_version_info
    Traceback (most recent call last):
      File "<string>", line 14, in <module>
      File "/home/vagrant/gmusicproxy/build/python-daemon/setup.py", line 97, in <module>
        "Topic :: Software Development :: Libraries :: Python Modules",
      File "/usr/lib/python2.7/distutils/core.py", line 152, in setup
        dist.run_commands()
      File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
        self.run_command(cmd)
      File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
        cmd_obj.run()
      File "version.py", line 500, in run
        self.run_command(command_name)
      File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command
        self.distribution.run_command(command)
      File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
        cmd_obj.run()
      File "version.py", line 538, in run
        version_info = generate_version_info_from_changelog(self.changelog_path)
      File "version.py", line 414, in generate_version_info_from_changelog
        versions_all_json = changelog_to_version_info_collection(infile)
      File "version.py", line 369, in changelog_to_version_info_collection
        import docutils.core
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/core.py", line 20, in <module>
        from docutils import frontend, io, utils, readers, writers
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/frontend.py", line 41, in <module>
        import docutils.utils
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/__init__.py", line 20, in <module>
        import docutils.io
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/io.py", line 18, in <module>
        from docutils.utils.error_reporting import locale_encoding, ErrorString, ErrorOutput
      File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/error_reporting.py", line 47, in <module>
        locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]
      File "/usr/lib/python2.7/locale.py", line 503, in getdefaultlocale
        return _parse_localename(localename)
      File "/usr/lib/python2.7/locale.py", line 435, in _parse_localename
        raise ValueError, 'unknown locale: %s' % localename
    ValueError: unknown locale: UTF-8
    Complete output from command python setup.py egg_info:
    running egg_info

writing requirements to pip-egg-info/python_daemon.egg-info/requires.txt

writing pip-egg-info/python_daemon.egg-info/PKG-INFO

writing top-level names to pip-egg-info/python_daemon.egg-info/top_level.txt

writing dependency_links to pip-egg-info/python_daemon.egg-info/dependency_links.txt

warning: manifest_maker: standard file '-c' not found



reading manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'

reading manifest template 'MANIFEST.in'

writing manifest file 'pip-egg-info/python_daemon.egg-info/SOURCES.txt'

running write_version_info

Traceback (most recent call last):

  File "<string>", line 14, in <module>

  File "/home/vagrant/gmusicproxy/build/python-daemon/setup.py", line 97, in <module>

    "Topic :: Software Development :: Libraries :: Python Modules",

  File "/usr/lib/python2.7/distutils/core.py", line 152, in setup

    dist.run_commands()

  File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands

    self.run_command(cmd)

  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command

    cmd_obj.run()

  File "version.py", line 500, in run

    self.run_command(command_name)

  File "/usr/lib/python2.7/distutils/cmd.py", line 326, in run_command

    self.distribution.run_command(command)

  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command

    cmd_obj.run()

  File "version.py", line 538, in run

    version_info = generate_version_info_from_changelog(self.changelog_path)

  File "version.py", line 414, in generate_version_info_from_changelog

    versions_all_json = changelog_to_version_info_collection(infile)

  File "version.py", line 369, in changelog_to_version_info_collection

    import docutils.core

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/core.py", line 20, in <module>

    from docutils import frontend, io, utils, readers, writers

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/frontend.py", line 41, in <module>

    import docutils.utils

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/__init__.py", line 20, in <module>

    import docutils.io

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/io.py", line 18, in <module>

    from docutils.utils.error_reporting import locale_encoding, ErrorString, ErrorOutput

  File "/home/vagrant/gmusicproxy/build/python-daemon/docutils-0.12-py2.7.egg/docutils/utils/error_reporting.py", line 47, in <module>

    locale_encoding = locale.getlocale()[1] or locale.getdefaultlocale()[1]

  File "/usr/lib/python2.7/locale.py", line 503, in getdefaultlocale

    return _parse_localename(localename)

  File "/usr/lib/python2.7/locale.py", line 435, in _parse_localename

    raise ValueError, 'unknown locale: %s' % localename

ValueError: unknown locale: UTF-8

----------------------------------------
Command python setup.py egg_info failed with error code 1
Exception information:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 126, in main
    self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 223, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 980, in prepare_files
    req_to_install.run_egg_info()
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 216, in run_egg_info
    command_desc='python setup.py egg_info')
  File "/usr/lib/python2.7/dist-packages/pip/__init__.py", line 255, in call_subprocess
    % (command_desc, proc.returncode))
InstallationError: Command python setup.py egg_info failed with error code 1

$ uname -a
Linux vagrant-ubuntu 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

reentering password for google account on android devices

I'm using your gmusicproxy in an application to mirror my playlists and used mp3 which works really nice.
Anyway i occasionally need to reenter my password on every android device related to this account. The message states that i have to do this due to a change in account settings.
I just wondered if you have encountered this too?

install error: command GCC failed with exit status 1

On the pip install step I get this error on my wheezy install of raspbian:
will use netlink to read routing table

building 'netifaces' extension

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall
-Wstrict-prototypes -fPIC -DNETIFACES_VERSION=0.10.4
-DHAVE_GETIFADDRS=1 -DHAVE_GETNAMEINFO=1 -DHAVE_NETASH_ASH_H=1
-DHAVE_NETATALK_AT_H=1 -DHAVE_NETAX25_AX25_H=1 -DHAVE_NETECONET_EC_H=1
-DHAVE_NETIPX_IPX_H=1 -DHAVE_NETPACKET_PACKET_H=1
-DHAVE_LINUX_IRDA_H=1 -DHAVE_LINUX_ATM_H=1 -DHAVE_LINUX_LLC_H=1
-DHAVE_LINUX_TIPC_H=1 -DHAVE_LINUX_DN_H=1 -DHAVE_SOCKADDR_AT=1
-DHAVE_SOCKADDR_AX25=1 -DHAVE_SOCKADDR_IN=1 -DHAVE_SOCKADDR_IN6=1
-DHAVE_SOCKADDR_IPX=1 -DHAVE_SOCKADDR_UN=1 -DHAVE_SOCKADDR_ASH=1
-DHAVE_SOCKADDR_EC=1 -DHAVE_SOCKADDR_LL=1 -DHAVE_SOCKADDR_ATMPVC=1
-DHAVE_SOCKADDR_ATMSVC=1 -DHAVE_SOCKADDR_DN=1 -DHAVE_SOCKADDR_IRDA=1
-DHAVE_SOCKADDR_LLC=1 -DHAVE_PF_NETLINK=1 -I/usr/include/python2.7 -c
netifaces.c -o build/temp.linux-armv6l-2.7/netifaces.o

netifaces.c:1:20: fatal error: Python.h: No such file or directory

compilation terminated.

error: command 'gcc' failed with exit status 1


Command /home/pi/.virtualenvs/gmusicproxy/bin/python2 -c "import
setuptools;file='/home/pi/.virtualenvs/gmusicproxy/build/netifaces/setup.py';exec(compile(open(file).read().replace('\r\n',
'\n'), file, 'exec'))" install --single-version-externally-managed
--record /tmp/pip-N80x0Z-record/install-record.txt --install-headers
/home/pi/.virtualenvs/gmusicproxy/include/site/python2.7 failed with
error code 1 in /home/pi/.virtualenvs/gmusicproxy/build/netifaces
Storing complete log in /home/pi/.pip/pip.log

Any ideas on fixing it?

Installation error: "netifaces.c:1:20: fatal error: Python.h: No such file or directory"

Hi. Please forgive me if I am doing this wrong... this is my first GitHub entry.

I was so excited to see your work. Thank you for sharing it. But I am having an issue installing it on my Pi. I am running Raspian and it is pretty much a fresh install. Things were going well for awhile until I hit the following (including as much info as possible for you - see the end for the error).

Please let me know if I can provide any more info or if I should go about this a different way. Noob here but picking things up fast :) Thanks a lot.

(I followed the directions exactly. I also tried the steps under "The right way to use an under-development python project makes use of virtualenv and virtualenvwrapper utilities" but got the same error during setup.)

sudo pip install https://github.com/diraimondo/gmusicproxy/tarball/master

Downloading/unpacking https://github.com/diraimondo/gmusicproxy/tarball/master
Downloading master (unknown size): 25Kb downloaded
Running setup.py egg_info for package from https://github.com/diraimondo/gmusi cproxy/tarball/master

Downloading/unpacking gmusicapi>=4.0.0 (from gmusicproxy==0.9.8)
Downloading gmusicapi-4.0.0.tar.gz (144Kb): 144Kb downloaded
Running setup.py egg_info for package gmusicapi

warning: no previously-included files matching '_local_*.py' found anywhere      in distribution

Downloading/unpacking netifaces (from gmusicproxy==0.9.8)
Downloading netifaces-0.10.4.tar.gz
Running setup.py egg_info for package netifaces

Downloading/unpacking pyxdg (from gmusicproxy==0.9.8)
Downloading pyxdg-0.25.tar.gz (48Kb): 48Kb downloaded
Running setup.py egg_info for package pyxdg

Downloading/unpacking eyed3 (from gmusicproxy==0.9.8)
Downloading eyeD3-0.7.5.tgz (221Kb): 221Kb downloaded
Running setup.py egg_info for package eyed3
warning: no previously-included files matching '*' found under directory 'do cs/_build'
Downloading/unpacking python-daemon (from gmusicproxy==0.9.8)
Downloading python-daemon-1.6.1.tar.gz (47Kb): 47Kb downloaded
Running setup.py egg_info for package python-daemon

Downloading/unpacking validictory>=0.8.0,!=0.9.2 (from gmusicapi>=4.0.0->gmusicp roxy==0.9.8)
Downloading validictory-1.0.0a2.tar.gz
Running setup.py egg_info for package validictory

warning: no files found matching 'CHANGELOG.txt'

Downloading/unpacking decorator>=3.3.1 (from gmusicapi>=4.0.0->gmusicproxy==0.9. 8)
Downloading decorator-3.4.0.tar.gz
Running setup.py egg_info for package decorator

warning: no previously-included files found matching 'Makefile'

Downloading/unpacking mutagen>=1.18 (from gmusicapi>=4.0.0->gmusicproxy==0.9.8)
Downloading mutagen-1.26.tar.gz (868Kb): 868Kb downloaded
Running setup.py egg_info for package mutagen

Downloading/unpacking protobuf>=2.4.1 (from gmusicapi>=4.0.0->gmusicproxy==0.9.8 )
Downloading protobuf-2.6.1.tar.gz (188Kb): 188Kb downloaded
Running setup.py egg_info for package protobuf

Installed /home/pi/build/protobuf/google_apputils-0.4.1-py2.7.egg
Searching for pytz>=2010
Reading http://pypi.python.org/simple/pytz/
Best match: pytz 2014.9
Downloading https://pypi.python.org/packages/2.7/p/pytz/pytz-2014.9-py2.7.eg     g#md5=b8149d1f94d12b402ac6e27a7b12353b
Processing pytz-2014.9-py2.7.egg
Extracting pytz-2014.9-py2.7.egg to /home/pi/build/protobuf

Installed /home/pi/build/protobuf/pytz-2014.9-py2.7.egg
Searching for python-gflags>=1.4
Reading http://pypi.python.org/simple/python-gflags/
Reading http://code.google.com/p/python-gflags
Best match: python-gflags 2.0
Downloading https://pypi.python.org/packages/source/p/python-gflags/python-g     flags-2.0.tar.gz#md5=23c9a793959a54971b1f094b0c6d03b1
Processing python-gflags-2.0.tar.gz
Running python-gflags-2.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install     -r0ozxA/python-gflags-2.0/egg-dist-tmp-QaJaQz
zip_safe flag not set; analyzing archive contents...

Installed /home/pi/build/protobuf/python_gflags-2.0-py2.7.egg
Searching for python-dateutil>=1.4
Reading http://pypi.python.org/simple/python-dateutil/
Reading http://labix.org/python-dateutil
Best match: python-dateutil 2.2
Downloading https://pypi.python.org/packages/source/p/python-dateutil/python     -dateutil-2.2.tar.gz#md5=c1f654d0ff7e33999380a8ba9783fd5c
Processing python-dateutil-2.2.tar.gz
Running python-dateutil-2.2/setup.py -q bdist_egg --dist-dir /tmp/easy_insta     ll-PpFMva/python-dateutil-2.2/egg-dist-tmp-Dkt3K7

Installed /home/pi/build/protobuf/python_dateutil-2.2-py2.7.egg
Searching for six
Reading http://pypi.python.org/simple/six/
Best match: six 1.8.0
Downloading https://pypi.python.org/packages/source/s/six/six-1.8.0.tar.gz#m     d5=1626eb24cc889110c38f7e786ec69885
Processing six-1.8.0.tar.gz
Running six-1.8.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-s1gi79/     six-1.8.0/egg-dist-tmp-m7OUkR
no previously-included directories found matching 'documentation/_build'
zip_safe flag not set; analyzing archive contents...
six: module references __path__

Installed /home/pi/build/protobuf/six-1.8.0-py2.7.egg

Downloading/unpacking requests>=1.1.0,!=1.2.0,!=2.2.1 (from gmusicapi>=4.0.0->gm usicproxy==0.9.8)
Downloading requests-2.4.3.tar.gz (438Kb): 438Kb downloaded
Running setup.py egg_info for package requests

Downloading/unpacking python-dateutil>=1.3,!=2.0 (from gmusicapi>=4.0.0->gmusicp roxy==0.9.8)
Downloading python-dateutil-2.2.tar.gz (259Kb): 259Kb downloaded
Running setup.py egg_info for package python-dateutil

Downloading/unpacking proboscis>=1.2.5.1 (from gmusicapi>=4.0.0->gmusicproxy==0. 9.8)
Downloading proboscis-1.2.6.0.tar.gz
Running setup.py egg_info for package proboscis

Downloading/unpacking oauth2client>=1.1 (from gmusicapi>=4.0.0->gmusicproxy==0.9 .8)
Downloading oauth2client-1.4.1.tar.gz (44Kb): 44Kb downloaded
Running setup.py egg_info for package oauth2client

Downloading/unpacking mock>=0.7.0 (from gmusicapi>=4.0.0->gmusicproxy==0.9.8)
Downloading mock-1.0.1.tar.gz (818Kb): 818Kb downloaded
Running setup.py egg_info for package mock

warning: no files found matching '*.png' under directory 'docs'
warning: no files found matching '*.css' under directory 'docs'
warning: no files found matching '*.html' under directory 'docs'
warning: no files found matching '*.js' under directory 'docs'

Downloading/unpacking appdirs>=1.1.0 (from gmusicapi>=4.0.0->gmusicproxy==0.9.8)
Downloading appdirs-1.4.0.tar.gz
Running setup.py egg_info for package appdirs

Downloading/unpacking python-magic (from eyed3->gmusicproxy==0.9.8)
Downloading python-magic-0.4.6.tar.gz
Running setup.py egg_info for package python-magic

Requirement already satisfied (use --upgrade to upgrade): distribute in /usr/lib /python2.7/dist-packages (from python-daemon->gmusicproxy==0.9.8)
Downloading/unpacking lockfile>=0.9 (from python-daemon->gmusicproxy==0.9.8)
Downloading lockfile-0.10.2.tar.gz
Running setup.py egg_info for package lockfile

Installed /home/pi/build/lockfile/pbr-0.10.0-py2.7.egg
[pbr] Processing SOURCES.txt
warning: LocalManifestMaker: standard file '-c' not found

warning: no previously-included files found matching '.gitignore'
warning: no previously-included files found matching '.gitreview'
warning: no previously-included files matching '*.pyc' found anywhere in dis     tribution

Downloading/unpacking six (from python-dateutil>=1.3,!=2.0->gmusicapi>=4.0.0->gm usicproxy==0.9.8)
Downloading six-1.8.0.tar.gz
Running setup.py egg_info for package six

no previously-included directories found matching 'documentation/_build'

Downloading/unpacking httplib2>=0.8 (from oauth2client>=1.1->gmusicapi>=4.0.0->g musicproxy==0.9.8)
Downloading httplib2-0.9.tar.gz (204Kb): 204Kb downloaded
Running setup.py egg_info for package httplib2

Downloading/unpacking pyasn1==0.1.7 (from oauth2client>=1.1->gmusicapi>=4.0.0->g musicproxy==0.9.8)
Downloading pyasn1-0.1.7.tar.gz (68Kb): 68Kb downloaded
Running setup.py egg_info for package pyasn1

Downloading/unpacking pyasn1-modules==0.0.5 (from oauth2client>=1.1->gmusicapi>= 4.0.0->gmusicproxy==0.9.8)
Downloading pyasn1-modules-0.0.5.tar.gz
Running setup.py egg_info for package pyasn1-modules

Downloading/unpacking rsa==3.1.4 (from oauth2client>=1.1->gmusicapi>=4.0.0->gmus icproxy==0.9.8)
Downloading rsa-3.1.4.tar.gz
Running setup.py egg_info for package rsa

warning: no files found matching 'README'

Installing collected packages: gmusicapi, netifaces, pyxdg, eyed3, python-daemon , gmusicproxy, validictory, decorator, mutagen, protobuf, requests, python-dateu til, proboscis, oauth2client, mock, appdirs, python-magic, lockfile, six, httpli b2, pyasn1, pyasn1-modules, rsa
Running setup.py install for gmusicapi

warning: no previously-included files matching '_local_*.py' found anywhere      in distribution

Running setup.py install for netifaces
checking for getifaddrs...found.
checking for getnameinfo...found.
checking for optional header files...netash/ash.h netatalk/at.h netax25/ax25 .h neteconet/ec.h netipx/ipx.h netpacket/packet.h linux/irda.h linux/atm.h linux /llc.h linux/tipc.h linux/dn.h.
checking whether struct sockaddr has a length field...no.
checking which sockaddr_xxx structs are defined...at ax25 in in6 ipx un ash ec ll atmpvc atmsvc dn irda llc.
checking for routing socket support...no.
checking for sysctl(CTL_NET...) support...no.
checking for netlink support...yes.
will use netlink to read routing table
building 'netifaces' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-pro totypes -fPIC -DNETIFACES_VERSION=0.10.4 -DHAVE_GETIFADDRS=1 -DHAVE_GETNAMEINFO= 1 -DHAVE_NETASH_ASH_H=1 -DHAVE_NETATALK_AT_H=1 -DHAVE_NETAX25_AX25_H=1 -DHAVE_NE TECONET_EC_H=1 -DHAVE_NETIPX_IPX_H=1 -DHAVE_NETPACKET_PACKET_H=1 -DHAVE_LINUX_IR DA_H=1 -DHAVE_LINUX_ATM_H=1 -DHAVE_LINUX_LLC_H=1 -DHAVE_LINUX_TIPC_H=1 -DHAVE_LI NUX_DN_H=1 -DHAVE_SOCKADDR_AT=1 -DHAVE_SOCKADDR_AX25=1 -DHAVE_SOCKADDR_IN=1 -DHA VE_SOCKADDR_IN6=1 -DHAVE_SOCKADDR_IPX=1 -DHAVE_SOCKADDR_UN=1 -DHAVE_SOCKADDR_ASH =1 -DHAVE_SOCKADDR_EC=1 -DHAVE_SOCKADDR_LL=1 -DHAVE_SOCKADDR_ATMPVC=1 -DHAVE_SOC KADDR_ATMSVC=1 -DHAVE_SOCKADDR_DN=1 -DHAVE_SOCKADDR_IRDA=1 -DHAVE_SOCKADDR_LLC=1 -DHAVE_PF_NETLINK=1 -I/usr/include/python2.7 -c netifaces.c -o build/temp.linux -armv6l-2.7/netifaces.o
netifaces.c:1:20: fatal error: Python.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1
Complete output from command /usr/bin/python -c "import setuptools;file= '/home/pi/build/netifaces/setup.py';exec(compile(open(file).read().replace(' \r\n', '\n'), file, 'exec'))" install --single-version-externally-managed -- record /tmp/pip-qjitpo-record/install-record.txt:
running install

running build

running build_ext

checking for getifaddrs...found.

checking for getnameinfo...found.

checking for optional header files...netash/ash.h netatalk/at.h netax25/ax25.h n eteconet/ec.h netipx/ipx.h netpacket/packet.h linux/irda.h linux/atm.h linux/llc .h linux/tipc.h linux/dn.h.

checking whether struct sockaddr has a length field...no.

checking which sockaddr_xxx structs are defined...at ax25 in in6 ipx un ash ec l l atmpvc atmsvc dn irda llc.

checking for routing socket support...no.

checking for sysctl(CTL_NET...) support...no.

checking for netlink support...yes.

will use netlink to read routing table

building 'netifaces' extension

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototy pes -fPIC -DNETIFACES_VERSION=0.10.4 -DHAVE_GETIFADDRS=1 -DHAVE_GETNAMEINFO=1 -D HAVE_NETASH_ASH_H=1 -DHAVE_NETATALK_AT_H=1 -DHAVE_NETAX25_AX25_H=1 -DHAVE_NETECO NET_EC_H=1 -DHAVE_NETIPX_IPX_H=1 -DHAVE_NETPACKET_PACKET_H=1 -DHAVE_LINUX_IRDA_H =1 -DHAVE_LINUX_ATM_H=1 -DHAVE_LINUX_LLC_H=1 -DHAVE_LINUX_TIPC_H=1 -DHAVE_LINUX_ DN_H=1 -DHAVE_SOCKADDR_AT=1 -DHAVE_SOCKADDR_AX25=1 -DHAVE_SOCKADDR_IN=1 -DHAVE_S OCKADDR_IN6=1 -DHAVE_SOCKADDR_IPX=1 -DHAVE_SOCKADDR_UN=1 -DHAVE_SOCKADDR_ASH=1 - DHAVE_SOCKADDR_EC=1 -DHAVE_SOCKADDR_LL=1 -DHAVE_SOCKADDR_ATMPVC=1 -DHAVE_SOCKADD R_ATMSVC=1 -DHAVE_SOCKADDR_DN=1 -DHAVE_SOCKADDR_IRDA=1 -DHAVE_SOCKADDR_LLC=1 -DH AVE_PF_NETLINK=1 -I/usr/include/python2.7 -c netifaces.c -o build/temp.linux-arm v6l-2.7/netifaces.o

netifaces.c:1:20: fatal error: Python.h: No such file or directory

compilation terminated.

error: command 'gcc' failed with exit status 1


Command /usr/bin/python -c "import setuptools;file='/home/pi/build/netifaces /setup.py';exec(compile(open(file).read().replace('\r\n', '\n'), file, ' exec'))" install --single-version-externally-managed --record /tmp/pip-qjitpo-re cord/install-record.txt failed with error code 1 in /home/pi/build/netifaces
Storing complete log in /root/.pip/pip.log

CallFailure: GetStreamUrl: 403 Client Error: Forbidden

Hi there,

Just today I started to get the following error [ID redacted]:

CallFailure: GetStreamUrl: 403 Client Error: Forbidden (requests kwargs: {u'url': u'https://android.clients.google.com/music/mplay', u'headers': {u'X-Device-ID': '000000000000', u'Authorization': u'<omitted>'}, u'allow_redirects': False, u'params': {u'opt': u'hi', u'mjck': 'Tfg43wt6uev6j3kmlbmy6rizfdy', u'pt': u'e', u'slt': '1479341244744', u'sig': 'PDwp98B9e45vFEOT-uAw6CDTvJA', u'net': u'mob'}, u'method': u'GET'}) (response was: '<HTML>\n<HEAD>\n<TITLE>Forbidden</TITLE>\n</HEAD>\n<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n<H1>Forbidden</H1>\n<H2>Error 403</H2>\n</BODY>\n</HTML>\n')

I've done some research and from what I can tell this historically was caused by bad IDs or a change in google's system. I've tried several ID's [all of which were working previously] to no avail. Can anyone confirm if they are also getting this problem now? Is another change required from Simon's gmusicapi?

Any assistance would be appreciated.
Cheers.

EDIT: I thought I would clarify that I have been using my setup for a few weeks now without issue. Tested the device with the ID in use and it, too, is working fine.

list-devices not working

Running GMusicProxy -L or GMusicProxy --list-devices gives me

Google Play Music Proxy 0.9.9.2 (© Mario Di Raimondo)

Please, specify the ID of an Android device registered in your Google account in the config file or on the command-line. Use the option '--list-devices=true' to auto-discover the IDs.

Using --list-devices=true like it indicates gives

GMusicProxy: error: argument -L/--list-devices: ignored explicit argument 'true'

Is there some error in argparse?

Metadata isn't send

Somehow no player can read metadata out of the files. I tried a few things and suggest that something in connection to eyed3 fails. The data gets written into the temporary file but does not seem to be received on the client side. Hope you can help.

Good work yet 👍

403 Client Error: Forbidden

Did a fresh pip install of required modules, started GMusicProxy without error. I can search for my songs, but I can't play any of my tracks. Here's an example

: arp_kiki/pts/28:0.30:~; GMusicProxy --extended-m3u --debug
Google Play Music Proxy 1.0.5 (© Mario Di Raimondo)

configuration used:
{'config': None,
'daemon': False,
'debug': True,
'device_id': 'bf9a6221c0e00dc0',
'disable_all_access': False,
'disable_playcount_increment': False,
'disable_version_check': False,
'email': '[email protected]',
'extended_m3u': True,
'host': 'auto',
'list_devices': False,
'log': None,
'password': '_OMITTED_',
'port': 9999}

authenticated
Fetching lastest version of gmusicproxy...
latest available version: 1.0.4
installed version: 1.0.5
Pre-fetching list of songs in collection
_

When trying to use VLC to stream one of my uploaded songs:

request path: /get_song?id=9b1d1e62-4b83-3ec4-9db8-23a490bac444
Streaming song with id '9b1d1e62-4b83-3ec4-9db8-23a490bac444': Jason Green - god bless the child
{u'album': u'Jason Green',
u'albumArtist': u'',
u'artist': u'Jason Green',
u'beatsPerMinute': 0,
u'clientId': u'qnKrLx74JBqOxMfjSp5/GQ',
u'comment': u'',
u'composer': u'',
u'creationTimestamp': u'1308372096694221',
u'deleted': False,
u'discNumber': 0,
u'durationMillis': u'279000',
u'estimatedSize': u'6773673',
u'genre': u'Blues',
u'id': u'9b1d1e62-4b83-3ec4-9db8-23a490bac444',
u'kind': u'sj#track',
u'lastModifiedTimestamp': u'1434481209008638',
u'playCount': 0,
u'rating': u'0',
u'recentTimestamp': u'1308385312157000',
u'title': u'god bless the child',
u'totalDiscCount': 0,
u'totalTrackCount': 14,
u'trackNumber': 1,
u'year': 2005}

GetStreamUrl(args=['9b1d1e62-4b83-3ec4-9db8-23a490bac444', '13806455504767028672', u'hi'], kwargs={})

Exception happened during processing of request from ('127.0.0.1', 33054)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 649, in init
self.handle()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
self.handle_one_request()
File "/u/arp/gmusicproxy/GMusicProxy", line 471, in handle_one_request
BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
method()
File "/u/arp/gmusicproxy/GMusicProxy", line 39, in do_GET
self._get_song(id=params['id'][0])
File "/u/arp/gmusicproxy/GMusicProxy", line 193, in _get_song
url = self._robust_retry(lambda:api.get_stream_url(song_id=id))
File "", line 2, in _robust_retry
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 390, in retry_wrapper
return f(_args, *_kwargs)
File "/u/arp/gmusicproxy/GMusicProxy", line 467, in _robust_retry
return func()
File "/u/arp/gmusicproxy/GMusicProxy", line 193, in
url = self._robust_retry(lambda:api.get_stream_url(song_id=id))
File "", line 2, in get_stream_url
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 296, in wrapper
return function(_args, *_kw)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 275, in get_stream_url
return self._make_call(mobileclient.GetStreamUrl, song_id, device_id, quality)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/shared.py", line 83, in _make_call
return protocol.perform(self.session, self.validate, _args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/protocol/shared.py", line 227, in perform
raise CallFailure(err_msg, call_name)
CallFailure: GetStreamUrl: 403 Client Error: Forbidden
(requests kwargs: {u'url': u'https://android.clients.google.com/music/mplay', u'headers': {u'X-Device-ID': '13806455504767028672', u'Authorization': u''}, u'allow_redirects': False, u'params': {u'opt': u'hi', u'songid': '9b1d1e62-4b83-3ec4-9db8-23a490bac444', u'pt': u'e', u'slt': '1460091879532', u'sig': 'UTN1cr9kyTda6nqzrjoIXaqKL0A', u'net': u'mob'}, u'method': u'GET'})

(response was: '\n\n<TITLE>Forbidden</TITLE>\n\n\n

Forbidden

\n

Error 403

\n\n\n')

I checked my authorized devices in google play and the host running gmusicapi is listed.

Any pointers for where to start looking?

Sorry, those credentials weren't accepted

Google Play Music Proxy 0.9.8 (© Mario Di Raimondo)

configuration used:
{'config': None,
 'daemon': False,
 'debug': True,
 'device_id': None,
 'disable_all_access': False,
 'disable_version_check': False,
 'email': '***OMITTED***',
 'extended_m3u': False,
 'host': '**auto**',
 'list_devices': True,
 'log': None,
 'password': '***OMITTED***',
 'port': 9999}

ClientLogin(<omitted>)
failed to authenticate
Sorry, those credentials weren't accepted.

I'm typing in my email and password on the command line but getting this error

"year" not in id3 tags

The eyeD3 tool has a -Y option which does:

    if self.args.release_year is not None:
        # empty string means clean, None means not given
        year = self.args.release_year
        printWarning("Setting release year: %s" % year)
        tag.release_date = int(year) if year else None

Can you consider doing in _get_song():

        if 'year' in info: tags.release_date = int(info['year'])

Syntax Error in python-daemon

File "/tmp/pip_build_root/python-daemon/daemon/version/version_info.py", line 20
print 'revision: %(revno)s' % version_info

SyntaxError: invalid syntax

The above error occurs while pip installing from the master branch.

Not really sure, but maybe the setup script needs to be updated to include a version of python-daemon that doesn't break. Anyone else have this issue?

Metadata not showing in most players?

At face value, this seems to be a similar issue to: #41, however, none of the advice there advanced my situation any...

Summary of What I've Done:
-I have installed GMusicProxy according to the instructions here: http://gmusicproxy.net/#gmusicproxy-google-play-music-proxy-setup-installation
-To test, I ran this command from the commandline: vlc 'http://localhost:9999/get_by_search?type=album&artist=Rolling%20Stones&title=tattoo&exact=no'
And, as expected, I got a Rolling Stones playlist playing in VLC complete with metadata...
-But I don't want to use VLC, I want to use Amarok, so I opened Amarok, clicked Playlist -> Add Stream, and pasted in http://localhost:9999/get_by_search?type=album&artist=Rolling%20Stones&title=tattoo&exact=no, which didn't work... Amarok just complained about the media not being recognized.
-Fine, I downloaded the playlist with: wget http://localhost:9999/get_by_search?type=album&artist=Rolling%20Stones&title=tattoo&exact=no -O RollingStones.m3u
Opened THAT in Amarok, and it plays... However, WITHOUT metadata.
-Just for sake of completeness to concept, I tried opening the URL in Audacious (which is the default media player on KXStudio), and it failed to play, reporting an error about "No decoder found..." Open the downloaded playlist and it played, but again, no metadata...

SO, first issue appears to be that Amarok (And other players...) won't recognise anything that doesn't end in *.m3u, but will play the EXACT SAME FILE as long as it's saved to disk first... Maybe we can solve it by adding a .m3u to the end of the URL?


IN trying to solve the metadata issue,
-I tried running GMusicProxy with --extended-m3u, and that gave the same results: The playlist plays, but without any metadata. This is true with both Audacious and Amarok;
-I tried running with --shoutcast-metadata, and that failed everywhere... Amarok, VLC, and Audacious all refused to play anything with that option set.

-Finally, as a means of verifying my baseline, I checked this stream in Amarok: https://www.internet-radio.com/servers/tools/playlistgenerator/?u=http://us1.internet-radio.com:8180/listen.pls&t=.m3u
And I got metadata just fine... SO the problem SEEMS to be in how GMusicProxy is sending the ID3 tags... But I'm not familiar enough with the specs to narrow it down more than that...

Let me know what logs you need and with which combination of options set! Thanks :)

get_all_stations results in Google 500 error

The call to the proxy:

curl -s 'http://192.168.2.15:8081/get_all_stations'

The resulting 500 from Google:

192.168.2.108 - - [25/Nov/2016 06:11:17] "GET /get_all_stations HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('192.168.2.108', 53134)
----------------------------------------
Getting all stations as M3U list...
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/SocketServer.py", line 596, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/local/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/lib/python2.7/SocketServer.py", line 652, in __init__
    self.handle()
  File "/usr/local/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/local/bin/GMusicProxy", line 509, in handle_one_request
    BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
  File "/usr/local/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "/usr/local/bin/GMusicProxy", line 50, in do_GET
    self._get_all_stations(format=params['format'][0] if 'format' in params else 'm3u', separator=params['separator'][0] if 'separator' in params else '|', onlyUrl=params['only_url'][0] if 'only_url' in params else 'no')
  File "/usr/local/bin/GMusicProxy", line 252, in _get_all_stations
    stations = self._robust_retry(lambda:api.get_all_stations())
  File "<decorator-gen-114>", line 2, in _robust_retry
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/utils/utils.py", line 390, in retry_wrapper
    return f(*args, **kwargs)
  File "/usr/local/bin/GMusicProxy", line 505, in _robust_retry
    return func()
  File "/usr/local/bin/GMusicProxy", line 252, in <lambda>
    stations = self._robust_retry(lambda:api.get_all_stations())
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/clients/mobileclient.py", line 760, in get_all_stations
    updated_after=updated_after)
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/clients/mobileclient.py", line 1069, in _get_all_items
    return [s for chunk in generator for s in chunk]
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/clients/mobileclient.py", line 1082, in _get_all_items_incremental
    **kwargs)
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/clients/shared.py", line 83, in _make_call
    return protocol.perform(self.session, self.validate, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/gmusicapi/protocol/shared.py", line 227, in perform
    raise CallFailure(err_msg, call_name)
CallFailure: ListStations: 500 Server Error: Internal Server Error
(requests kwargs: {u'url': u'https://mclients.googleapis.com/sj/v1.11/radio/station', u'headers': {u'Content-Type': u'application/json', u'Authorization': u'<omitted>'}, u'data': '{"max-results": "20000"}', u'method': u'POST', u'params': {u'alt': u'json', u'updated-min': 0, u'include-tracks': u'true'}})
(response was: '{\n "error": {\n  "errors": [\n   {\n    "domain": "global",\n    "reason": "internalError",\n    "message": "Internal Error"\n   }\n  ],\n  "code": 500,\n  "message": "Internal Error"\n }\n}\n')

API is blocking while search is playing one song

As a user of the API I'd expect to be able to use the API while one song is playing through the search API

Actions to reproduce:

  • Issue a search with only one song returning using VLC play from network function.
    (Example: http://10.228.0.1:1201/get_by_search?title=igel%20im%20nebel&type=song)
  • In a terminal try to list playlists.
    (curl 'http://10.228.0.1:1201/get_all_playlists?format=text')

Observed behaviour:

While VLC is buffering the song the curl execution blocks and after the song is fully buffered (near its end) the API responds to the curl and lists the playlists.

Expected behaviour:

VLC continues playing and the curl command returns the playlists immediately (plus the duration required to fetch them from the servers of Google).

Possible fix:

Implement concurrency / threading for HTTP requests

40 seconds to play a song?

Its normal 40s to get the stream of the song in get_song function?
With my old 0.8 version the song is playing in 1 o 2 seconds.

I noticed in debug mode that most of this time is getting the info of the song to add ID3tag of the stream.
Would it be possible to get the song without ID3tag (via option) in the case of the ID3tag is not needed?

(I'm runing GMusicProxy in a raspberry pi)

login() takes exactly 4 arguments, 3 given

When I try to run GMusicProxy, I get this error:

Google Play Music Proxy 0.9.8 (© Mario Di Raimondo)

Traceback (most recent call last):
File "/usr/bin/GMusicProxy", line 636, in
api = loginGM(config['email'], config['password'])
File "/usr/bin/GMusicProxy", line 545, in loginGM
api.login(email, password)
TypeError: login() takes exactly 4 arguments (3 given)

I'm on Arch Linux if it helps.

Exception when Shutting Down proxy

Got this exception while trying to shutdown the proxy server. The media player has closed the connection prior to shutdown.
Trace

^CShutting down the proxy...
----------------------------------------
Exception happened during processing of request from ('192.168.1.102', 54126)
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/Users/anton/gmusicproxy/GMusicProxy", line 472, in handle_one_request
    BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "/Users/anton/gmusicproxy/GMusicProxy", line 43, in do_GET
    self._get_song(id=params['id'][0])
  File "/Users/anton/gmusicproxy/GMusicProxy", line 210, in _get_song
    self.wfile.write(block)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 328, in write
    self.flush()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
  File "/Users/anton/gmusicproxy/GMusicProxy", line 499, in signalHandler
    sys.exit()
SystemExit
----------------------------------------
Traceback (most recent call last):
  File "/usr/local/bin/GMusicProxy", line 8, in <module>
    execfile(__file__)
  File "/Users/anton/gmusicproxy/GMusicProxy", line 671, in <module>
    server.serve_forever()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 236, in serve_forever
    poll_interval)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 155, in _eintr_retry
    return func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 459, in fileno
    return self.socket.fileno()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 174, in _dummy
    raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor

startup issue

Google Play Music Proxy 1.0.5 (© Mario Di Raimondo)

Pre-fetching list of songs in collection
Traceback (most recent call last):
File "GMusicProxy", line 690, in
server.allSongsCache = api.get_all_songs()
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 136, in get_all_songs
tracks = self._get_all_items(mobileclient.ListTracks, incremental, include_deleted)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 1069, in _get_all_items
return [s for chunk in generator for s in chunk]
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 1082, in _get_all_items_incremental
**kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/shared.py", line 83, in _make_call
return protocol.perform(self.session, self.validate, _args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/protocol/shared.py", line 210, in perform
response = session.send(req_kwargs, cls.required_auth)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 90, in send
res = self._send_with_auth(req_kwargs, desired_auth, rsession)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/session.py", line 215, in _send_with_auth
return rsession.request(**req_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 465, in request
resp = self.send(prep, *_send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 573, in send
r = adapter.send(request, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/adapters.py", line 370, in send
timeout=timeout
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 544, in urlopen
body=body, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 344, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
File "/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 314, in _raise_timeout
if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6
TypeError: str returned non-string (type Error)

support gmusicapi > 9.0.0

setup.py only allows for gmusicapi==9.0.0, creating problems for package managers. have versions greater than 9.0.0 been tested yet?

`get_ifl_station` behavior has changed

Originally making get_ifl_station request was identical to pressing "I'm feeling lucky function" in web player - you got new random playlist with random seed each time. Some months ago something has changed in Google Music behavior and now it return random playlist from the same seed each time, to change the seed one has to go to web interface and press the button.

Permission problems with python-daemon 2.1.0

Google Play Music Proxy 1.0.1 (© Mario Di Raimondo)

Traceback (most recent call last):
  File "/usr/bin/GMusicProxy", line 645, in <module>
    with contextDaemon:
  File "/usr/lib/python2.7/site-packages/daemon/daemon.py", line 394, in __enter__
    self.open()
  File "/usr/lib/python2.7/site-packages/daemon/daemon.py", line 370, in open
    change_process_owner(self.uid, self.gid, self.initgroups)
  File "/usr/lib/python2.7/site-packages/daemon/daemon.py", line 642, in change_process_owner
    raise error
daemon.daemon.DaemonOSEnvironmentError: Unable to change process owner ([Errno 1] Operation not permitted)

It runs fine with elevated permissions

Same issue on another project:
ThiefMaster/maildump#17

Is it still working?

after 2 atemps to install on debian and on ubunto, same results. can anyone give some help?

take a look at this log:

192.168.0.113 - - [02/Mar/2015 20:19:06] "GET /get_song?id=T7wmefscihezccr3nosm4ybjeyi HTTP/1.1" 200 -

Exception happened during processing of request from ('192.168.0.113', 33326)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 649, in init
self.handle()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
self.handle_one_request()
File "/usr/local/bin/GMusicProxy", line 449, in handle_one_request
BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
method()
File "/usr/local/bin/GMusicProxy", line 42, in do_GET
self._get_song(id=params['id'][0])
File "/usr/local/bin/GMusicProxy", line 170, in _get_song
info = self._robust_retry(lambda:api.get_track_info(store_track_id=id))
File "", line 2, in _robust_retry
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 382, in retry_wrapper
return f(_args, *_kwargs)
File "/usr/local/bin/GMusicProxy", line 445, in _robust_retry
return func()
File "/usr/local/bin/GMusicProxy", line 170, in
info = self._robust_retry(lambda:api.get_track_info(store_track_id=id))
File "", line 2, in get_track_info
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 288, in wrapper
return function(_args, *_kw)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 1012, in get_track_info
return self._make_call(mobileclient.GetStoreTrack, store_track_id)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/shared.py", line 80, in _make_call
return protocol.perform(self.session, self.validate, _args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/protocol/shared.py", line 225, in perform
raise CallFailure(err_msg, call_name)
CallFailure: GetStoreTrack: 400 Client Error: Bad Request
(requests kwargs: {'url': 'https://www.googleapis.com/sj/v1.5/fetchtrack', 'headers': {'Content-Type': 'application/json', 'Authorization': ''}, 'params': {'alt': 'json', 'nid': 'T7wmefscihezccr3nosm4ybjeyi'}, 'method': 'GET'})
(response was: '{\n "error": {\n "errors": [\n {\n "domain": "global",\n "reason": "badRequest",\n "message": "Bad Request"\n }\n ],\n "code": 400,\n "message": "Bad Request"\n }\n}\n')

ConfigParser.NoSectionError on list devices

I installed gmusicproxy using pip on arch linux (python 2.7). When trying list devices I got the following stack trace:

$ GMusicProxy -e myemail -p mypass -L      
Traceback (most recent call last):
  File "/usr/bin/GMusicProxy", line 532, in <module>
    config = getOptions(configFilename)
  File "/usr/bin/GMusicProxy", line 453, in getOptions
    configValues = dict(config.items('dummy'))
  File "/usr/lib/python2.7/ConfigParser.py", line 642, in items
    raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'dummy'

Gmusicproxy on raspberry: authentication fails

I've installed GMusicProxy on a raspberry pi, from what I've seen I have not encountered any errors in the process. But when I try to get a list of my devices it keeps saying

"Sorry, those credentials weren't accepted."

I've tried googling this problem with various search queries but couldn't find a solution (or a reason for that matter)

Here's my debug output:

$ GMusicProxy -e [email] -p [password] -D --list-devices

Google Play Music Proxy 0.9.8 (© Mario Di Raimondo)

configuration used:
{'config': None,
'daemon': False,
'debug': True,
'device_id': None,
'disable_all_access': False,
'disable_version_check': False,
'email': '_OMITTED',
'extended_m3u': False,
'host': 'auto',
'list_devices': True,
'log': None,
'password': '_OMITTED
',
'port': 9999}

ClientLogin()
failed to authenticate
Sorry, those credentials weren't accepted.

I'm quite sure I'm using the correct username and pw..

What now?

Is "/search_id" not working ?

So , I am trying to used "/search_id" like so

curl -s 'http://localhost:9999/search_id?type=album&title=love'

But no matter what i enter in the title param , i always get empty results , other queries such as

curl -s 'http://localhost:9999/get_album?id=B5sm5kgmtehbpzid7z6v74so6sq'
Are working fine .

Thank you for this wonderfull tool and any help is really appreciated.

Installation on Mac OSX

Hi,

Hope you don't mind but I tried on a OSX and it does not work out from the box (i mean as you described on the website). Here are the different things I tried to install it on OSX 10.9 and the different errors I got :

  • "sudo pip install https://github.com/diraimondo/gmusicproxy/tarball/master"
    --> No distributions matching the version for gmusicapi>=3.1.1-dev (from gmusicproxy==0.9.4)
  • By cloning the repository, happily, it's the same error.
  • By downloading the last TAR, it's a bit more complicated because I get many warning easily fixable, but, at the end I cannot succeed to install ; here are the different problems :
    • A problem with eyed3 dependency (which can be resolved with "sudo pip install . --allow-external eyed3 --allow-unverified eyed3")
      screen shot 2014-03-22 at 15 42 34
    • Then come a problem which seems much more serious with this stack trace : Command /usr/bin/python -c "import setuptools, tokenize;file=u'/private/tmp/pip_build_root/netifaces/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /tmp/pip-5fWkJ5-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /private/tmp/pip_build_root/netifaces
      screen shot 2014-03-22 at 15 50 25
      (EDIT) I went further on that problem and it's caused by netifaces and I got this problem on all its version of it (it's not linked to your soft but prevent it to work). Didn't found any solutions on the Internet, maybe, if you have one, it would be very appreciable ! I'll test on Linux yet !
  • Currently, I'm blocked here and I cannot test your project which sounds to be great but does not work because of dependencies :(

Hope it helps to improve it !

Starting GMusicProxy fails when gmusicproxy.net is offline

At the moment, gmusicproxy.net is offline. Also, GMusicProxy isn't able to start, and fails with the following error:

Google Play Music Proxy 1.0.5 (© Mario Di Raimondo)

Traceback (most recent call last):
  File "/usr/bin/GMusicProxy", line 665, in <module>
    checkLatestVersion()
  File "/usr/bin/GMusicProxy", line 583, in checkLatestVersion
    latestVersion = opener.open(urlLatestVersion).read()
  File "/usr/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1227, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1197, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 111] Connection refused>

Though correlation doesn't imply causation, I do think that the check for the latest version fails because gmusicproxy.net is offline.

Hence, can you make a fail in the version check have no impact on the ability to run GMusicProxy?

/get_by_search : discrepencies between song and album or artist request

/get_by_search returns either an m3u playlist (for album or artist search) or an mp3 (for a song search).
What is a bit strange is that get_by_search also expects a exact parameter. When set to no, one would expect a song search to return several songs and thus a M3U instead of the mp3. As is it now, I do not know how to search for the list of song containing a specific word in their title.

Would it be possible to return a M3U for the song request too (possibly via another parameter if you want to preserv backward compatibility) ?

UnicodeDecodeError

Upon installing, I get an error which prevents the completion of the installation process. I have tried using Python versions 2.7.5 and 2.7.6. The issue has occurred on at least 2 other computers.

The output from the console line goes:

 Exception:
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/commands/install.py", line 274, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/req.py", line 1173, in prepare_files
    self.unpack_url(url, location, self.is_download)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/req.py", line 1320, in unpack_url
    retval = unpack_http_url(link, location, self.download_cache, self.download_dir, self.session)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/download.py", line 587, in unpack_http_url
    unpack_file(temp_location, location, content_type, link)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/util.py", line 625, in unpack_file
    untar_file(filename, location)
  File "/Library/Python/2.7/site-packages/pip-1.5.2-py2.7.egg/pip/util.py", line 556, in untar_file
    path = os.path.join(location, fn)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py", line 80, in join
    path += '/' + b
UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 34: ordinal not in range(128)

Support "Instant Mix" functionality

Currently it is possible to get random thematic playlist by using get_ifl_station command. However Google Music web client allows to create so called "instant mix" for any given song / artist / album, which is pretty much same IFL station but with a given object used as initial seed. This is probably my most loved feature of Google Music and exactly the reason why I am trying to use it as media server backend. Any hints to parts of code to tweak for PR to implement it?

/get_by_search?type=song results in error

Trying to add songs from search results in

error adding Binary file (standard input) matches: Not found

Debug Log:

INFO: authenticated
DEBUG: Fetching lastest version of gmusicproxy...
DEBUG: latest available version: 1.0.1
DEBUG: installed version: 1.0.1
INFO: Listening on port 9999...
DEBUG: request path: /get_by_search?type=song&artist=Geographer&title=Kaleidoscope
INFO: Searching for song with query: Geographer Kaleidoscope
DEBUG: Search(args=[u'Geographer Kaleidoscope', 50], kwargs={})
DEBUG: {u'kind': u'sj#searchresponse', u'clusterOrder': [u'5', u'2', u'3', u'1', u'7', u'6', u'4', u'8'], u'entries': [{u'navigational_result': False, u'score': 165.54998779296875, u'type': u'2', u'best_result': False, u'artist': {u'kind': u'sj#artist', u'artistArtRef': u'http://lh3.googleusercontent.com/ZIgRRfW34Kv2vJ5O1-5GqsmSVSkJBMn9g60hnvc-0UaHLAUWBXbg__pfHE2MG7Wp60fKW-F0bsw', u'name': u'Geographer', u'artistId': u'A4aopp74j4zwlxd4pbvtfnncf3i', u'artist_bio_attribution': {u'kind': u'sj#attribution', u'source_title': u'artist representative'}}}, {u'track': {u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}], u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'], u'composer': u'', u'year': 2012, u'trackAvailableForSubscription': True, u'trackType': u'7', u'album': u'Myth', u'title': u'Kaleidoscope', u'albumArtist': u'Geographer', u'trackNumber': 3, u'discNumber': 1, u'albumAvailableForPurchase': True, u'contentType': u'2', u'trackAvailableForPurchase': True, u'storeId': u'Txwp6zm4g6qrc3zkhihpz67ryza', u'nid': u'Txwp6zm4g6qrc3zkhihpz67ryza', u'estimatedSize': u'11104163', u'albumId': u'Bfvh2badashiwhiwapiolvhd34m', u'genre': u'Alternative/Indie', u'kind': u'sj#track', u'artist': u'Geographer', u'durationMillis': u'277000'}, u'navigational_result': False, u'score': 150.19752502441406, u'type': u'1', u'best_result': False}, {u'track': {u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}], u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'], u'composer': u'', u'year': 2012, u'trackAvailableForSubscription': True, u'trackType': u'7', u'album': u'Myth', u'title': u'Vesij\xe4rvi', u'albumArtist': u'Geographer', u'trackNumber': 9, u'discNumber': 1, u'albumAvailableForPurchase': True, u'contentType': u'2', u'trackAvailableForPurchase': True, u'storeId': u'Tkrxk4atoacsxytnakhoyf52sem', u'nid': u'Tkrxk4atoacsxytnakhoyf52sem', u'estimatedSize': u'10513796', u'albumId': u'Bfvh2badashiwhiwapiolvhd34m', u'genre': u'Alternative/Indie', u'kind': u'sj#track', u'artist': u'Geographer', u'durationMillis': u'262000'}, u'navigational_result': False, u'score': 65.39643096923828, u'type': u'1', u'best_result': False}, {u'navigational_result': False, u'station': {u'kind': u'sj#radioStation', u'seed': {u'kind': u'sj#radioSeed', u'artistId': u'A4aopp74j4zwlxd4pbvtfnncf3i', u'seedType': u'3'}, u'imageUrls': [{u'url': u'http://lh3.googleusercontent.com/ZIgRRfW34Kv2vJ5O1-5GqsmSVSkJBMn9g60hnvc-0UaHLAUWBXbg__pfHE2MG7Wp60fKW-F0bsw'}], u'name': u'Geographer'}, u'type': u'6', u'best_result': False}, {u'navigational_result': False, u'station': {u'kind': u'sj#radioStation', u'seed': {u'trackId': u'Txwp6zm4g6qrc3zkhihpz67ryza', u'kind': u'sj#radioSeed', u'seedType': u'2'}, u'imageUrls': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}], u'name': u'Kaleidoscope'}, u'type': u'6', u'best_result': False}, {u'navigational_result': False, u'station': {u'kind': u'sj#radioStation', u'seed': {u'trackId': u'Tkrxk4atoacsxytnakhoyf52sem', u'kind': u'sj#radioSeed', u'seedType': u'2'}, u'imageUrls': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}], u'name': u'Vesij\xe4rvi'}, u'type': u'6', u'best_result': False}]}
ERROR: the response format for Search was not recognized.

Failed to validate field 'entries' list schema: additional property 'station' not defined by 'properties' are not allowed in list item

First, try the develop branch. If you can recreate this error with the most recent code please create an issue that includes the above ValidationException and the following request/response:
{'url': 'https://mclients.googleapis.com/sj/v1.11/query', 'headers': {'Authorization': ''}, 'params': {'q': u'Geographer Kaleidoscope', 'max-results': 50}, 'method': 'GET'}

'{\n "kind": "sj#searchresponse",\n "entries": [\n {\n "type": "2",\n "artist": {\n "kind": "sj#artist",\n "name": "Geographer",\n "artistArtRef": "http://lh3.googleusercontent.com/ZIgRRfW34Kv2vJ5O1-5GqsmSVSkJBMn9g60hnvc-0UaHLAUWBXbg__pfHE2MG7Wp60fKW-F0bsw",\n "artistId": "A4aopp74j4zwlxd4pbvtfnncf3i",\n "artist_bio_attribution": {\n "kind": "sj#attribution",\n "source_title": "artist representative"\n }\n },\n "score": 165.54998779296875,\n "best_result": false,\n "navigational_result": false\n },\n {\n "type": "1",\n "track": {\n "kind": "sj#track",\n "title": "Kaleidoscope",\n "artist": "Geographer",\n "composer": "",\n "album": "Myth",\n "albumArtist": "Geographer",\n "year": 2012,\n "trackNumber": 3,\n "genre": "Alternative/Indie",\n "durationMillis": "277000",\n "albumArtRef": [\n {\n "url": "http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA"\n }\n ],\n "discNumber": 1,\n "e...'

A traceback follows:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/gmusicapi/protocol/shared.py", line 249, in perform
cls.validate(response, parsed_response)
File "/usr/lib/python2.7/site-packages/gmusicapi/protocol/mobileclient.py", line 262, in validate
return validictory.validate(msg, cls._res_schema)
File "/usr/lib/python2.7/site-packages/validictory/init.py", line 33, in validate
return v.validate(data, schema)
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 569, in validate
self._validate(data, schema)
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 572, in _validate
self.__validate("_data", {"_data": data}, schema)
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 603, in __validate
newschema.get(schemaprop))
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 230, in validate_properties
properties.get(eachProp))
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 603, in __validate
newschema.get(schemaprop))
File "/usr/lib/python2.7/site-packages/validictory/validator.py", line 276, in validate_items
e.value)
ValidationException: Failed to validate field 'entries' list schema: additional property 'station' not defined by 'properties' are not allowed in list item
DEBUG: {'album_hits': [],
'artist_hits': [{u'artist': {u'artistArtRef': u'http://lh3.googleusercontent.com/ZIgRRfW34Kv2vJ5O1-5GqsmSVSkJBMn9g60hnvc-0UaHLAUWBXbg__pfHE2MG7Wp60fKW-F0bsw',
u'artistId': u'A4aopp74j4zwlxd4pbvtfnncf3i',
u'artist_bio_attribution': {u'kind': u'sj#attribution',
u'source_title': u'artist representative'},
u'kind': u'sj#artist',
u'name': u'Geographer'},
u'best_result': False,
u'navigational_result': False,
u'score': 165.54998779296875,
u'type': u'2'}],
'playlist_hits': [],
'song_hits': [{u'best_result': False,
u'navigational_result': False,
u'score': 150.19752502441406,
u'track': {u'album': u'Myth',
u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}],
u'albumArtist': u'Geographer',
u'albumAvailableForPurchase': True,
u'albumId': u'Bfvh2badashiwhiwapiolvhd34m',
u'artist': u'Geographer',
u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'],
u'composer': u'',
u'contentType': u'2',
u'discNumber': 1,
u'durationMillis': u'277000',
u'estimatedSize': u'11104163',
u'genre': u'Alternative/Indie',
u'kind': u'sj#track',
u'nid': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'storeId': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'title': u'Kaleidoscope',
u'trackAvailableForPurchase': True,
u'trackAvailableForSubscription': True,
u'trackNumber': 3,
u'trackType': u'7',
u'year': 2012},
u'type': u'1'},
{u'best_result': False,
u'navigational_result': False,
u'score': 65.39643096923828,
u'track': {u'album': u'Myth',
u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}],
u'albumArtist': u'Geographer',
u'albumAvailableForPurchase': True,
u'albumId': u'Bfvh2badashiwhiwapiolvhd34m',
u'artist': u'Geographer',
u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'],
u'composer': u'',
u'contentType': u'2',
u'discNumber': 1,
u'durationMillis': u'262000',
u'estimatedSize': u'10513796',
u'genre': u'Alternative/Indie',
u'kind': u'sj#track',
u'nid': u'Tkrxk4atoacsxytnakhoyf52sem',
u'storeId': u'Tkrxk4atoacsxytnakhoyf52sem',
u'title': u'Vesij\xe4rvi',
u'trackAvailableForPurchase': True,
u'trackAvailableForSubscription': True,
u'trackNumber': 9,
u'trackType': u'7',
u'year': 2012},
u'type': u'1'}]}
DEBUG: I'm feeling lucky: lets select the first song!
INFO: Selected song: Geographer - Kaleidoscope (Txwp6zm4g6qrc3zkhihpz67ryza)
DEBUG: {u'best_result': False,
u'navigational_result': False,
u'score': 150.19752502441406,
u'track': {u'album': u'Myth',
u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}],
u'albumArtist': u'Geographer',
u'albumAvailableForPurchase': True,
u'albumId': u'Bfvh2badashiwhiwapiolvhd34m',
u'artist': u'Geographer',
u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'],
u'composer': u'',
u'contentType': u'2',
u'discNumber': 1,
u'durationMillis': u'277000',
u'estimatedSize': u'11104163',
u'genre': u'Alternative/Indie',
u'kind': u'sj#track',
u'nid': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'storeId': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'title': u'Kaleidoscope',
u'trackAvailableForPurchase': True,
u'trackAvailableForSubscription': True,
u'trackNumber': 3,
u'trackType': u'7',
u'year': 2012},
u'type': u'1'}
DEBUG: GetStoreTrack(args=[u'Txwp6zm4g6qrc3zkhihpz67ryza'], kwargs={})
DEBUG: {u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}], u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'], u'composer': u'', u'year': 2012, u'trackAvailableForSubscription': True, u'trackType': u'7', u'album': u'Myth', u'title': u'Kaleidoscope', u'albumArtist': u'Geographer', u'trackNumber': 3, u'discNumber': 1, u'albumAvailableForPurchase': False, u'contentType': u'2', u'trackAvailableForPurchase': True, u'storeId': u'Txwp6zm4g6qrc3zkhihpz67ryza', u'nid': u'Txwp6zm4g6qrc3zkhihpz67ryza', u'estimatedSize': u'11104163', u'albumId': u'Bfvh2badashiwhiwapiolvhd34m', u'genre': u'Alternative/Indie', u'kind': u'sj#track', u'artist': u'Geographer', u'durationMillis': u'277000'}
INFO: Streaming song with id 'Txwp6zm4g6qrc3zkhihpz67ryza': Geographer - Kaleidoscope
DEBUG: {u'album': u'Myth',
u'albumArtRef': [{u'url': u'http://lh6.ggpht.com/q2aPx5xQCi3pb-sB8lz_s_oUK_8DowIU_fNBE2VS7dgLoA0b5p_StUX4EoIBCvoTQwkRYuD3OA'}],
u'albumArtist': u'Geographer',
u'albumAvailableForPurchase': False,
u'albumId': u'Bfvh2badashiwhiwapiolvhd34m',
u'artist': u'Geographer',
u'artistId': [u'A4aopp74j4zwlxd4pbvtfnncf3i'],
u'composer': u'',
u'contentType': u'2',
u'discNumber': 1,
u'durationMillis': u'277000',
u'estimatedSize': u'11104163',
u'genre': u'Alternative/Indie',
u'kind': u'sj#track',
u'nid': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'storeId': u'Txwp6zm4g6qrc3zkhihpz67ryza',
u'title': u'Kaleidoscope',
u'trackAvailableForPurchase': True,
u'trackAvailableForSubscription': True,
u'trackNumber': 3,
u'trackType': u'7',
u'year': 2012}
DEBUG: GetStreamUrl(args=[u'Txwp6zm4g6qrc3zkhihpz67ryza', '3709629877331607957', 'hi'], kwargs={})
DEBUG: https://r4---sn-p5qlsns6.c.doc-0-0-sj.sj.googleusercontent.com/videoplayback?id=d618669b6c46a633&itag=25&source=skyjam&begin=0&upn=rwbBSc5pIy8&o=01423689343908048365&ratebypass=yes&ip=71.63.37.143&ipbits=0&expire=1444523777&sparams=expire,id,ip,ipbits,itag,mm,mn,ms,mv,nh,o,pl,ratebypass,source,upn&signature=700892A01BA96D1B36774B943385D6505F38DCAD.7CDAAEB986E079FD3295AB02C0648C31600863A5&key=cms1&mm=31&mn=sn-p5qlsns6&ms=au&mt=1444523632&mv=m&nh=IgpwcjAxLmlhZDI2KgkxMjcuMC4wLjE&pl=17
DEBUG: streaming url: https://r4---sn-p5qlsns6.c.doc-0-0-sj.sj.googleusercontent.com/videoplayback?id=d618669b6c46a633&itag=25&source=skyjam&begin=0&upn=rwbBSc5pIy8&o=01423689343908048365&ratebypass=yes&ip=71.63.37.143&ipbits=0&expire=1444523777&sparams=expire,id,ip,ipbits,itag,mm,mn,ms,mv,nh,o,pl,ratebypass,source,upn&signature=700892A01BA96D1B36774B943385D6505F38DCAD.7CDAAEB986E079FD3295AB02C0648C31600863A5&key=cms1&mm=31&mn=sn-p5qlsns6&ms=au&mt=1444523632&mv=m&nh=IgpwcjAxLmlhZDI2KgkxMjcuMC4wLjE&pl=17
WARNING: Detected connection reset.

get_song - no title, artist and time

When I add songs with "get_song" in my player (example: VLC) i see no title, artist and time, i see only the url.

When i add a playlist with "get_playlist" i see all information, ..... but when a song from playlist is play ("get_song" is used), the time is erased.

I think the proxy will not pass this information, can you improve it? (Because i need the time/songlength.)

Thanks :)

Estimated song size is out by 5 bytes (33>28)

In tests, I'm fining that the estimated song size is out. The current delta in the code is 28, but I'm finding that songs I retrieve are out.

I thought it was fixed at 33, but I've just had a song that's out by 4191.

get_song broken due to google changes

due to recent changes by google, get_song is broken and returns the following:

CallFailure: GetStreamUrl: 403 Client Error: Forbidden
(requests kwargs: {'headers': {'X-Device-ID': '37e6eaa5364d26b6', 'Authorization': '<omitted>'}, 'params': {'opt': 'hi', 'mjck': 'Tnjwqak3bwclrt2bhjhfojp7muy', 'pt': 'e', 'slt': '1393571010139', 'sig': 'IvbVQci-pekjmjNzwmt2_HxJydE', 'net': 'wifi'}, 'url': 'https://android.clients.google.com/music/mplay', 'verify': False, 'allow_redirects': False, 'method': 'GET'})
(response was: '<HTML>\n<HEAD>\n<TITLE>Forbidden</TITLE>\n</HEAD>\n<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n<H1>Forbidden</H1>\n<H2>Error 403</H2>\n</BODY>\n</HTML>\n')

this is reproducible on ubuntu, os x, and debian.
might be related to simon-weber/gmusicapi#221

Proxy not returning answers to requests

Hello, not sure if I am missing some configuration option or if something on my system is blocking it. However, I cannot seem to get any responses from gmusicproxy. wget or curl just hang indefinitely waiting for a response.

gmusicproxy.log

Google Play Music Proxy 1.0.5 (© Mario Di Raimondo)

Pre-fetching list of songs in collection
Listening on port 9999...
Searching for album with query: Queen Greatest Hits
Selected album: Queen - Greatest Hits I, II & III (The Platinum Collection) (Bjw4dr6n3n3mh2k7lzonzhejhm4)
Getting the tracks of the album with id 'Bjw4dr6n3n3mh2k7lzonzhejhm4': Greatest Hits I, II & III (The Platinum Collection) - Queen

The requests

 ✘  ~/.mpd/playlists  curl -s 'http://localhost:9999/get_by_search?type=album&artist=Queen&title=Greatest%20Hits' > queen.m3u
^C
 ✘  ~/.mpd/playlists  

The two lines after "Searching for album..." only appear after I cancel the request (Ctrl+C). The file queen.m3u is empty.

I tried the arch linux aur packages gmusicproxy-git and gmusicproxy-stable and installing manually using python virtualenv.

Any help would be appreciated.

get_song - bad request

I can not listen any music. When I use http://localhost:9999/get_song?id=Txjwctvqcxcin4olnkeurhcndpu
I get

127.0.0.1 - - [21/Jun/2014 17:23:41] "GET /get_song?id=Txjwctvqcxcin4olnkeurhcndpu HTTP/1.1" 200 -

Exception happened during processing of request from ('127.0.0.1', 60587)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 649, in init
self.handle()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
self.handle_one_request()
File "/usr/local/bin/GMusicProxy", line 410, in handle_one_request
BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
method()
File "/usr/local/bin/GMusicProxy", line 39, in do_GET
self._get_song(id=params['id'][0])
File "/usr/local/bin/GMusicProxy", line 165, in _get_song
info = self._robust_retry(lambda:api.get_track_info(store_track_id=id))
File "", line 2, in _robust_retry
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 382, in retry_wrapper
return f(_args, *_kwargs)
File "/usr/local/bin/GMusicProxy", line 406, in _robust_retry
return func()
File "/usr/local/bin/GMusicProxy", line 165, in
info = self._robust_retry(lambda:api.get_track_info(store_track_id=id))
File "", line 2, in get_track_info
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 288, in wrapper
return function(_args, *_kw)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/mobileclient.py", line 1012, in get_track_info
return self._make_call(mobileclient.GetStoreTrack, store_track_id)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/clients/shared.py", line 80, in _make_call
return protocol.perform(self.session, self.validate, _args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/protocol/shared.py", line 225, in perform
raise CallFailure(err_msg, call_name)
CallFailure: GetStoreTrack: 400 Client Error: Bad Request
(requests kwargs: {'url': 'https://www.googleapis.com/sj/v1.5/fetchtrack', 'headers': {'Content-Type': 'application/json', 'Authorization': ''}, 'params': {'alt': 'json', 'nid': 'Txjwctvqcxcin4olnkeurhcndpu'}, 'method': 'GET'})
(response was: '{\n "error": {\n "errors": [\n {\n "domain": "global",\n "reason": "badRequest",\n "message": "Bad Request"\n }\n ],\n "code": 400,\n "message": "Bad Request"\n }\n}\n')

ImportError: cannot import name InsecureRequestWarning

Hello,

i have my system (Raspberry Pi 2) reinstalled (Raspian Jessie / Debian 8 Jessie) and install the gmusicproxy like:

Traceback (most recent call last):
File "/usr/local/bin/GMusicProxy", line 6, in
exec(compile(open(file).read(), file, 'exec'))
File "/home/pi/gmusicproxy/GMusicProxy", line 29, in
from requests.packages.urllib3.exceptions import InsecureRequestWarning
ImportError: cannot import name InsecureRequestWarning

What can i do or can you fix it? Thanks

I have seen, that gmusicapi 7.0.0 and gmusicproxy 1.0.2 is installed. I have in between attempts by the manual installation of gmusicproxy 1.0.1 and gmusicapi 6.0.0 to circumvent the problem, but unfortunately it has not helped.
Here you can see all current package: http://pastebin.com/5y3USSk9

The 'gmusicapi>=5.0.0-dev0' distribution was not found and is required by gmusicproxy

Hi guys,

A few days ago, I had the 'Sorry, those credentials weren't accepted' issue (just like bhanderson here: #27), so I figured I should upgrade to the latest version of gmusicproxy.

I'm running it on Windows using Cygwin.

$ pip install --allow-external eyed3 --allow-unverified eyed3 -r requirements.txt --upgrade
[...]
Successfully installed gmusicapi-4.0.0 gmusicproxy-0.9.8

But now, whenever I try to start gmusicproxy, I get the following error:

$ gmusicproxy
Traceback (most recent call last):
  File "/usr/bin/gmusicproxy", line 4, in <module>
    __import__('pkg_resources').require('gmusicproxy==0.9.8')
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 3074, in <module>
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 3060, in _call_aside
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 3087, in _initialize_master_working_set
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 647, in _build_master
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 660, in _build_from_requirements
  File "build/bdist.cygwin-2.0.2-x86_64/egg/pkg_resources/__init__.py", line 833, in resolve
pkg_resources.DistributionNotFound: The 'gmusicapi>=5.0.0-dev0' distribution was not found and is required by gmusicproxy

How do you guys manage to make it work?

EDIT: I'm able to start gmusicproxy if I remove 'gmusicapi>=5.0.0-dev0' from install_requires, but then I get this error:

$ gmusicproxy -e ****@gmail.com -p **** -d ****
Google Play Music Proxy 0.9.8 (© Mario Di Raimondo)

Traceback (most recent call last):
  File "/usr/bin/gmusicproxy", line 6, in <module>
    exec(compile(open(__file__).read(), __file__, 'exec'))
  File "/home/*****/gmusicproxy/GMusicProxy", line 636, in <module>
    api = loginGM(config['email'], config['password'])
  File "/home/*****/gmusicproxy/GMusicProxy", line 545, in loginGM
    api.login(email, password, config['device_id'])
TypeError: login() takes exactly 3 arguments (4 given)

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.