Giter Site home page Giter Site logo

vvdleun / audiostreamerscrobbler Goto Github PK

View Code? Open in Web Editor NEW
14.0 0.0 1.0 423 KB

Scrobbles or sends meta-data of streamed music on Bluesound/BluOS, Yamaha MusicCast and/or Denon HEOS players to Last FM, ListenBrainz, Libre FM and/or GNU FM. Built for Raspberry pi-alike devices.

License: MIT License

Golo 72.84% Java 27.16%
bluesound bluos musiccast heos last-fm libre-fm gnu-fm listenbrainz lastfm librefm

audiostreamerscrobbler's Introduction

AudioStreamerScrobbler

AudioStreamerScrobbler is an application that monitors hardware audiostreamers and scrobbles played tracks to one or more of the personal audio tracking ("scrobbler") services.

The program is intended to be used 24/7 on Raspberry pi-alike devices. I have personally compiled and have been running it on a Raspberry pi 1 Model B for some time now.

AudioStreamerScrobbler was written in Eclipse Golo, a lesser known dynamic language that runs on the Java Virtual Machine (JVM). It was a design goal to write as much code in Golo as possible and not to use additional Java dependencies, unless very unpractical. We'll see how that wil turn out on the longer run. I had to write some code in Java to work around omissions in the Golo run-time library, but luckily Gradle takes care of those complexities when building the project. Although I'm personally not the biggest fan of dynamic languages, I really started to like Golo while I was developing this program. In my opinion it's a nice, small and clean language, with a surprisingly powerful run-time library.

Supported hardware and scrobbler/music tracking services

Supported hardware audiostreamer platforms:

  • Bluesound / BluOS-based players
  • Yamaha MusicCast
  • Denon HEOS (EXPERIMENTAL)

The following music tracking services are supported:

Requirements

AudioStreamerScrobbler is a project powered by the Java Virtual Machine (JVM). To run it, the Java Runtime Environment (JRE) version 8 is required. Golo is currently not compatible with Java 9 and higher, and seems to have issues when running on a JVM higher than 8. It remains to be seen whether Golo will be made compatible with newer Java versions. If not, a port to a different programming language is not ruled out.

Since this is a alpha pre-release, the program must be compiled before it can be used. To compile the program, both the Java Developers Kit (JDK) version 8 and the Gradle build tool (https://gradle.org) are required. Gradle will download the required dependencies, compile the project and build a stand-alone JAR file that can be used to run the program. To compile, issue the following command in the project's root directory (the directory containing the build.gradle file):

gradle clean build

In the build/libs subdirectory, you'll find a audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar file that you can run with the java -jar audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar command. Be advised that you'll need to do some manual configuration first. This will be explained in the next section.

Installation

After compiling the project, copy the builds/libs/audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar file to a directory that is convenient for you. In the same directory, create a config.json file that looks like this:

{
    "players" {
        "bluos": {
            "enabled": true,
            "players": ["Living Room C368"]
        }
        "musiccast": {
            "enabled": true,
            "players": ["Bedroom ISX-18D", "Kitchen WX-010"]
        },
        "heos": {
            "enabled": true,
            "players": ["Portable HEOS 1"]
        }
    },
    "scrobblers": {
        "lastfm": {
            "enabled": true,
            "apiKey": "",
            "apiSecret": "",
            "sessionKey": ""
        },
        "listenbrainz" {
            "enabled": true,
            "userToken": ""
        },
        "librefm": {
            "enabled": true,
            "sessionKey": ""
        },
        "gnufm": {
            "enabled": true,
            "nixtapeUrl": "192.168.178.109/nixtape",
            "sessionKey": ""
        },
        "listenbrainz-server": {
            "enabled": true,
            "websiteUrl": "",
            "apiUrl": "",
            "userToken": ""
        }
    },
    "settings": {
        "network": {
            "networkInterface": "",
            "networkInterfaceAddress": ""
        },
        "errorHandling": {
            "maxSongs": 100,
            "retryIntervalMinutes": 30
        }
    }
}

This format may change once support for other player standards, new group functionality and/or other features are added to the program. I'll make sure this README.md file will always contain an up-to-date example.

Setting up the players

The program should be able to monitor all Bluesound, Yamaha MusicCast and Denon HEOS players that are available in your network.

Do not forget to disable the audiostreamer standards that you do not want to use at this time (by setting the enabled setting to value false). Otherwise, a lot of unnecessary traffic will be generated on your network.

Setting up Bluesound / BluOS-based players

First, make sure that the bluos entry of the players section in your config.json file is enabled, as displayed below. Also, enter all the names of your players in the players list. If you have two players, that are called Living Room C368 and Kitchen Pulse Flex, your BluOS players configuration should look like this:

    ...
    "players": {
        "bluos": {
            "enabled": "true",
            "players": ["Living Room C368", "Kitchen Pulse Mini 2i"]
        }
    },
    ...

The player name must match your BluOS device name exactly. Note that the name is CaSe SeNsItIvE.

The program should be compatible with all current and legacy Bluesound speakers and players. It has been tested on a NAD BlueOS 2 MDC upgrade module in a NAD C368 amplifier and a Bluesound Pulse Mini 2i speaker. The program should also be compatible with the new third party BluOS powered devices that have appeared on the market (like available from Dali), but this has not been tested yet.

Setting up Yamaha MusicCast players

At this stage, the program can only monitor the Net/USB input of MusicCast players. Also, despite some players having support for multiple zones, only the Main zone is supported for now. I hope to improve this one day.

First, make sure that the musiccast entry of the players section of your config.json file is enabled, as displayed below. Also, enter all the name of your players in the players list. For example if you have two players that are called Living Room WX-010 and Bedroom ISX-18D, your MusicCast players configuration will look like this:

    ...
    "players": {
        "musiccast": {
            "enabled": "true",
            "players": ["Living Room WX-010", "Bedroom ISX-18D"]
        }
    },
    ...

Note that the player name is case sensitive.

I have seen that when playing local songs from my NAS, that the MusicCast player does not recognize the length of songs and therefore cannot scrobble those songs. Yamaha UK support team confirmed to me that this is a known current limitation of the MusicCast platform. I'd like to investigate and try to come up with a workaround one day.

MusicCast compatibility has been tested with a Yamaha Restio ISX-18d and WX-010 MusicCast speakers only, but should be compatible with the full range of Yamaha MusicCast speakers, home theaters, amplifiers, CD players, turntable, etc.

Setting up Denon HEOS players

This support is considered experimental. As always, open an issue if you encounter problems.

HEOS support is implemented differently than the other standards. Instead of the program connecting to all players individually, it connects to the first player that it finds. Since all HEOS devices communicate with each other, this device is then used to detect and monitor all HEOS devices on the network.

Make sure that the heos entry is enabled in the main players section, as displayed below. Also, enter all the name of your players in the players list:

    ...
    "players": {
        "heos": {
            "enabled": "true",
            "players": ["Living Room HEOS 3", "Bathroom HEOS 1"]
        }
    },
    ...

Compatibility has been briefly tested with a HEOS 1 HS2 device only. It should be compatible with the full range of HEOS compatible devices released by Denon.

Setting up scrobbler services

For each scrobbler service, set the enabled field to true for the scrobbler services that you want to use. Make sure you'll set the others to false, otherwise the application will probably crash.

Coming up are instructions to authorize the application with each scrobbler service.

Last FM

Last FM is the scrobbler service that started it all. In my opinion, its recommendation engine is still unbeatable.

To use this program with Last FM, first get yourself an API key and API secret at https://www.last.fm/api/account/create You can keep the Callback URL empty, as it is not used by this desktop app. Note that Last FM's account page has been broken for a long time, you won't be able to retrieve the API key/secret in your account screen, so if you lose your keys, you'll have to request a new pair.

Put the API key and secret in the correct fields in the config.json file, then run the following command on a machine that has a desktop GUI browser:

java -jar audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar --authorize lastfm

This will start a browser. If you are not logged in to Last FM, you are asked to log in. After logging in, Last FM will ask you whether you want to authorize the application. If this is what you want, click Yes. Then open the console window and press Enter, to let the application know that you have authorized the application. It will then continue the authorization process. Finally, it will show the value for the session key. Copy and paste it and place it in the sessionKey value in the config.json file's lastfm entry.

ListenBrainz and ListenBrainz Server

ListenBrainz is a new service, operated by the MetaBrainz Foundation. At the time of writing this service was still in beta. A big different with all others is that ListenBrainz will give away all collected data for free. Everybody can download a complete data dumps from their database on their website. A recommondation system is said to be in development.

To use this program with ListenBrainz, first get yourself an account. In your user profile, you'll find your unique user token. Copy and paste this and place this in the userToken field of the listenbrainz entry in the config.json file. Don't forget to set the enabled field to the true value.

Local installation

You can also choose to download the ListenBrainz Server yourself and run a server instance locally, but this is recommended for advanced users only. If you choose to go this route and have it running in your network, you must fill the listenbrainz-server entry in the config.json file, set its enabled field to true and fill the websiteUrl (the URL where you can access your local instance) and the apiUrl (this is the same URL that you entered in ListenBrainz Server's listenbrainz/config.py file's API URL field). You can keep it empty if you chose the same URL for the API as the website. You'll still need to find the User Token in your server's user profile page.

Libre FM

Libre FM is a free alternative for Last FM. It is basically a rebranded GNU FM (see below), with a nicer UI theme, run as a cloud service by the developers of GNU FM. It was started in 2009, but it still does not offer a recommendation engine. Therefore Libre FM is, at least for now, most useful if you primarily want to archive your listening habits. The maintainers of Libre FM promise not to sell your user data, very much unlike Last FM.

If you want to use AudioStreamerScrobbler with Libre FM, make sure that the librefm entry in the config.json file has the enabled key set to value true. Then run the following command on a terminal that has access to a GUI desktop browser:

java -jar audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar --authorize librefm

See the Last FM entry for more detailed instructions on the authorization process, the process is very much the same with Libre FM. Note that at the time of writing, AudioStreamerScrobbler client is not known by Libe FM, so it will show as an unknown client/API keys for the time being. After authorizing, just copy and paste it and place the returned session key in the sessionKey value in the config.json file's librefm entry.

GNU FM

GNU FM is not a cloud service. It's a web application that can be downloaded and deployed on any server, even on a local machine in your network. It is very similar to Libre FM, but they differ quite a bit in the user-interface department.

The beauty of GNU FM is that it is open-source. You can take it and adjust it fully to your needs (some PHP, HTML, JavaScript and database knowledge will be needed). If you make changes that you'll contribute back to the GNU FM project, you will help the Libre FM project as well, as they are based on the same codebase. Unfortunately there does not seem to be an active community to both, but that is another story...

If you are concerned that cloud services like Last FM, Libre FM and ListenBrainz will disappear without warning one day, it could be worthwhile to run and maintain a GNU FM instance yourself. Of course the social aspect of scrobbling is lost then, unless you share your GNU FM instance with other people. It should be noted, though, that Libre FM can be linked to GNU FM instances that can be reached on the web.

If you want to use AudioStreamerScrobbler with GNU FM, make sure that the gnufm entry in the config.json file has the enabled key set to value true.

Also, you'll need to enter the URL to GNU FM. At this time, GNU FM consists of two submodules: "NixTape" (this module consists of the user interface and the AudioScrobbler 2.0 API protocol implementation) and "Gnukebox" (this module implements the older AudioScrobbler 1.x API protocol, which AudioStreamerScrobbler does not use at all). in the nixtapeUrl entry in the config.json file, you should enter the URL that you'll use to access your GNU FM application from your browser. On my machine, I've installed GNU FM on a virtual machine and entered the following URL: 192.168.178.109/nixtape (your IP address wil most likely be different).

After all this, run the following command on a terminal that has access to a GUI desktop internet browser:

java -jar audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar --authorize gnufm

See the Last FM entry for more detailed instructions on the authorization process, the process is very much the same with GNU FM. Note that at the time of writing, AudioStreamerScrobbler client is not known by GNU FM, so it will show as an unknown client/API keys for the time being. After authorizing, just copy and paste it and place the returned session key in the sessionKey value in the config.json file's gnufm entry.

Configuring scrobble errors parameters

As this program was created for Raspberry pi-alike devices, it currently can only register songs that could not be scrobbled in volatile memory (storing them on the filesystem would damage the pi's SD cards on the long run). This means that the program will not persist them and when quitting the application before it had a chance to scrobble the songs, those scrobbles will be lost forever.

You can choose how many songs it can store per scrobbler by setting the desired amount in the maxSongs entry. You can also configure the interval on which it will try to scrobble those songs by setting the retryIntervalMinutes entry in the confgiuration file. This interval is always specified in minutes.

For Last FM, songs that could not be scrobbled for 14 days in a row are silently dropped, as required by Last FM. For the other services this limit has been set to 30 days.

Configuring network interface parameters

Normally the program uses the network card that the Java's network library of the Java platform selects as its default. While developing, I have seen rare cases where the wrong network card was selected and the program could not communicate with any player on the network.

If this happens to you, you can overrule the network interface that is used when opening I/O sockets (at this time HTTP requests are not affected by this, open a GitHub issue if this causes problems for you).

To list the network interfaces that are available on your computer, run the following command:

java -jar audiostreamerscrobbler-0.1.0-SNAPSHOT-all.jar --networkinterfaces

This will list the currently available and enabled network interfaces and their addresses. Sample output of my Windows desktop PC:

Alias    : "wlan3"
Name     : "Dell Wireless 1705 802.11b/g/n (2.4GHZ)"
Addresses: "192.168.178.107"  "xxxx:x:x:x:xxxx:xxxx:xxxx:xxxx%wlan3"

Alias    : "eth6"
Name     : "VirtualBox Host-Only Ethernet Adapter"
Addresses: "192.168.99.1"  "xxxx:x:x:x:xxxx:xxxx:xxxx:xxxx%eth6"

In the config.json configuration file, find or add the network section under settings:

...
"settings": {
    ....
    "network": {
        "networkInterface": "wlan3",
        "networkInterfaceAddress": ""
    },
    ....
}
...

In the networkInterface field, you can fill the output of the Alias or Name fields, that were listed when using the --networkinterfaces parameter. Normally that would be enough, the program will then try to bind to the first IP address of that network interface. If you want the program to bind to a specific IP address of a network interface, you can also fill the networkInterfaceAddress field. For example, on my system I could fill networkInterfaceAddress with the 192.168.178.107 address.

Plans

I'd like to add an optional GUI mode, so setting up the program would become much more user-friendly. Also, I'd like to add an option to reduce the generated network traffic (the trade-off being that it may take awhile to detect a playing device)

On the longer term I'd like to add more advanced grouping possibilities, so that multiple groups of players can be monitored at the same time and support different accounts on different scrobbler/music tracking services.

Right now I mostly concentrate on features that I'll use myself, but if there's demand I'd love to switch priorities.

About the author

I am Vincent van der Leun. I'm a Dutch Java developer and currently employed by a modern cloud-based software company in Holland.

If you like scrobbling as much as I do, feel free to visit one of my accounts (and add me as a friend if the service supports that):

Also, please open GitHub issues if you need support, have questions, concerns, suggestions, etc. about this program.

audiostreamerscrobbler's People

Contributors

vvdleun avatar

Stargazers

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

Forkers

tml3nr

audiostreamerscrobbler's Issues

Deadlocks occur, at least in the SSDP handler threads

While the program can run smoothly for months, from time to time the program seems to hang.

Some early investigation points to the SSDP handler as the cause. It has a clunky way to determine whether it should run or stay paused and it probably fails to detect that it needs to run from time to time. In certain situation it is never checked again whether its threads will need to run, so it can remain idle and never detect new devices on the network.

My current idea is to get rid of the Workers on the SSDP handler and just let the threads always run periodically. Since it knows which devices it has to detect, it can choose to do nothing each time it runs.

Exception launched when starting script with Node already playing

script running on a Pi 4 / raspberry OS Buster. Streaming from Node 2i

Everything works fine when starting script, then streaming: scrobbling perfectly.

If I start playing a song and then run the script, the following error occurs :

Starting 'BluOS' detector...
Starting LSDP discovery thread...
Detected player 'BluOS/Node2' is managed by the 'Player Group' group.
All players of type 'BluOS' in group 'Player Group' have been found. Stop looking for other players of this type.
Starting monitor for player 'Node2 (Standard: BluOS, model: N125, version 3.16.1, IP address: 192.168.1.46, MAC address: 90:56:82:41:73:c4)'...
Starting player polling thread for player 'Node2 (Standard: BluOS, model: N125, version 3.16.1, IP address: 192.168.1.46, MAC address: 90:56:82:41:73:c4)...
Stopping 'BluOS' detector...
Error occurred while polling PlayerProxy{impl=BluOsPlayerImpl{playerType=union PlayerTypes.BluOs, name=Node2, bluOsImpl=struct BluOsPlayerImpl{name=Node2, port=11000, model=N125, version=3.16.1, macAddress=90:56:82:41:73:c4, ipAddress=192.168.1.46, LSDPVersionSupposedly=1, host=192.168.1.46}}, playerTypeId=BluOS, id=BluOS/Node2}: java.lang.IllegalArgumentException: Comparison method violates its general contract!
Exception in thread "PollBasedMonitorHelper" java.lang.IllegalArgumentException: Comparison method violates its general contract!
        at java.base/java.util.TimSort.mergeLo(TimSort.java:781)
        at java.base/java.util.TimSort.mergeAt(TimSort.java:518)
        at java.base/java.util.TimSort.mergeForceCollapse(TimSort.java:461)
        at java.base/java.util.TimSort.sort(TimSort.java:254)
        at java.base/java.util.Arrays.sort(Arrays.java:1515)
        at java.base/java.util.ArrayList.sort(ArrayList.java:1750)
        at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:392)
        at java.base/java.util.stream.DistinctOps$1$2.end(DistinctOps.java:168)
        at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:210)
        at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
        at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
        at java.base/java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:720)
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
        at org.eclipse.golo.runtime.RegularMethodFinder.find(RegularMethodFinder.java:40)
        at org.eclipse.golo.runtime.MethodInvocationSupport.findTarget(MethodInvocationSupport.java:349)
        at org.eclipse.golo.runtime.MethodInvocationSupport.lookupTarget(MethodInvocationSupport.java:225)
        at org.eclipse.golo.runtime.MethodInvocationSupport.fallback(MethodInvocationSupport.java:250)
        at audiostreamerscrobbler.utils.RequestUtils.doHttpGetRequest(RequestUtils:11)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.FunctionCallSupport.fallback(FunctionCallSupport.java:210)
        at audiostreamerscrobbler.factories.RequestFactory.__$$_golo$compiler$sugar_closure_8(RequestFactory:54)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at gololang.FunctionReference.invoke(FunctionReference.java:157)
        at gololang.DynamicObject.dispatchCall(DynamicObject.java:171)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.MethodInvocationSupport.fallback(MethodInvocationSupport.java:280)
        at audiostreamerscrobbler.players.bluos.BluOsMonitor.requestPlayerState(BluOsMonitor:61)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.FunctionCallSupport.fallback(FunctionCallSupport.java:210)
        at audiostreamerscrobbler.players.bluos.BluOsMonitor.pollBluOsStatus(BluOsMonitor:42)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.FunctionCallSupport.fallback(FunctionCallSupport.java:210)
        at audiostreamerscrobbler.players.bluos.BluOsMonitor.__$$_golo$compiler$sugar_closure_1(BluOsMonitor:34)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at gololang.FunctionReference.invoke(FunctionReference.java:157)
        at gololang.DynamicObject.dispatchGetterStyle(DynamicObject.java:201)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.MethodInvocationSupport.fallback(MethodInvocationSupport.java:280)
        at audiostreamerscrobbler.players.helpers.PollBasedMonitorHelper.pollPlayerAnCallCallback(PollBasedMonitorHelper:103)
        at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
        at org.eclipse.golo.runtime.FunctionCallSupport.fallback(FunctionCallSupport.java:210)
        at audiostreamerscrobbler.players.helpers.PollBasedMonitorHelper.__$$_golo$compiler$sugar_closure_5(PollBasedMonitorHelper:41)
        at java.base/java.lang.invoke.MethodHandleProxies$1.invoke(MethodHandleProxies.java:195)
        at jdk.proxy1/com.sun.proxy.jdk.proxy1.$Proxy3.run(Unknown Source)
        at java.base/java.lang.Thread.run(Thread.java:829)
Stopping LSDP discovery thread...

MusicCast support is not working on Linux computers

On my Raspberry pi 1 (Model B) AudiostreamerScrobbler is detecting MusicCast players on the network. It sends HTTP requests, but fails to receive UDP responses.

On my Windows development machine, this seems to be working fine.

Add Gradle wrapper to project

Since the Golo compiler Gradle plugin does not seem to compatible with the newest Gradle versions, add the Gradle wrapper to this project, so that the user is not required to install a specific (outdated) Gradle version to compile this project.

Investigation: should program be ported to different language than Golo?

Personally I'm quite happy with the Golo language. It's a fun language, it has a small run-time library with useful (and, again, fun) features. The JVM needs a small dynamic language like this in my view.

Also, while no work seems to be actively done to migrate Golo to newer Java versions, that's not really a concern to me at this time. For this particular project I plan to stay on Java 8 for the time being. The reason is that I want this program to keep running on my aging and very slow Raspberry pi 1, Model B device, which would otherwise become obsolete to me. It has been running fine for quite some time, monitoring about 3 to 5 players, of various types, each day (I keep not all my players on the network all the time).

Of course, the fact that nobody seems to be actively working on Golo is of some concern, so in the end I may choose to port this program to Groovy, Kotlin, or a different JVM language on the longer run.

Unable to install - Failed to apply plugin [id 'org.golo-lang.golo']

Using Windows 10 because getting old java is a pain on Linux, after installing both JRE and JDK 8, and Gradle 6.0.1 (latest) and Gradle 5.4 (was released around the time of the master push) I get the following error.

An exception occurred applying plugin request [id: 'org.golo-lang.golo', version: '0.6']

Failed to apply plugin [id 'org.golo-lang.golo'] >

No signature of method: org.gradle.api.plugins.JavaBasePlugin.configureForSourceSet() is applicable for argument types: (org.gradle.api.internal.tasks.DefaultSourceSet_Decorated, org.gololang.gradle.GoloCompile_Decorated) values: [source set 'main', task ':compileGolo']

More details and full Gradle build scan available at https://scans.gradle.com/s/zuxelnoqjmiqy

java.lang.IllegalArgumentException while running

Thanks for building this cool piece of software! Looking forward to start scrobbling, but ran into following error message when running audiostreamscrobbler (configured with lastfm):

Starting 'BluOS' detector...
Starting LSDP discovery thread...
Detected player 'BluOS/NODE 2i' is managed by the 'Player Group' group.
All players of type 'BluOS' in group 'Player Group' have been found. Stop looking for other players of this type.
Starting monitor for player 'NODE 2i (Standard: BluOS, model: N125, version 3.6.12, IP address: 192.168.1.59, MAC address: XX:XX:XX:XX:XX:XX)'...
Starting player polling thread for player 'NODE 2i (Standard: BluOS, model: N125, version 3.6.12, IP address: 192.168.1.59, MAC address: XX:XX:XX:XX:XX:XX)...
Stopping 'BluOS' detector...
New song detected: '"Ancient Skin" (Jack Penate, "After You"), played 206 seconds of 232 seconds'
Could not update Playing Now for service 'lastfm': java.lang.IllegalArgumentException: Comparison method violates its general contract!
Stopping LSDP discovery thread...
New song detected: '"Swept to the Sky" (Jack Penate, "After You"), played 0 seconds of 282 seconds'
Could not update Playing Now for service 'lastfm': java.lang.IllegalArgumentException: Comparison method violates its general contract!

Some information on my environment:

java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (Zulu8.42.0.195-CA-linux_aarch32hf) (build 1.8.0_232-b195)
OpenJDK Client VM (Zulu8.42.0.195-CA-linux_aarch32hf) (build 25.232-b195, mixed mode, Evaluation)
gradle --version

------------------------------------------------------------
Gradle 4.10.3
------------------------------------------------------------

Build time:   2018-12-05 00:50:54 UTC
Revision:     e76905e3a1034e6f724566aeb985621347ff43bc

Kotlin DSL:   1.0-rc-6
Kotlin:       1.2.61
Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM:          1.8.0_232 (Azul Systems, Inc. 25.232-b195)
OS:           Linux 4.19.66-v7+ arm

I am running a Raspberry Pi 3 Model B. Any idea what could be causing the issue?

p.s. I did retrieve the sessionKey from lastfm and added it to the config.json file

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.