devgianlu / librespot-android Goto Github PK
View Code? Open in Web Editor NEWA demo app that runs librespot-java on Android
A demo app that runs librespot-java on Android
Hey @devgianlu, I have the feeling it would make sense to archive this repo as it does not seem likely we will be able to do much without librespot-java being under active development.
Clicking on the play button rapidly for 4-5 times instantly crashes the player, with this stack trace :
2022-01-08 16:19:02.149 7076-7555/xyz.gianlu.librespot.android E/AndroidRuntime: FATAL EXCEPTION: player-queue-132206105
Process: xyz.gianlu.librespot.android, PID: 7076
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at xyz.gianlu.librespot.player.StateWrapper.getCurrentTrack(StateWrapper.java:843)
at xyz.gianlu.librespot.player.StateWrapper.metadataFor(StateWrapper.java:655)
at xyz.gianlu.librespot.player.Player$3.metadataFor(Player.java:471)
at xyz.gianlu.librespot.player.playback.PlayerSession.metadataFor(PlayerSession.java:200)
at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:132)
at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:276)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-01-08 16:19:02.165 7076-7555/xyz.gianlu.librespot.android I/Process: Sending signal. PID: 7076 SIG: 9
This can be considered a bug in librespot-java (the 'Player' does not accept multiple load requests in a short time) or a bug in librespot-android (if it is not a bug in librespot-java, then we should implement a way of not sending the request if the player is already processing requests).
Anyway, i'd like to hear what should be done on this, so that i know if I should implement a request queue and wait for player readyness or if this should be done directly into librespot-java in a next release.
Right now, for example java.util.Base64 is available on Android 8+, otherwise there will be an exception like this:
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: xyz.gianlu.librespot.android, PID: 15947
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;
at xyz.gianlu.librespot.common.Utils.toBase64(Utils.java:314)
at xyz.gianlu.librespot.core.Session.authenticatePartial(Session.java:435)
at xyz.gianlu.librespot.core.Session.authenticate(Session.java:333)
at xyz.gianlu.librespot.core.Session.access$600(Session.java:75)
at xyz.gianlu.librespot.core.Session$Builder.create(Session.java:1021)
at xyz.gianlu.librespot.android.LoginActivity$LoginThread.run(LoginActivity.java:96)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.util.Base64" on path: DexPathList[[zip file "/data/app/xyz.gianlu.librespot.android-1/base.apk"],nativeLibraryDirectories=[/data/app/xyz.gianlu.librespot.android-1/lib/arm, /data/app/xyz.gianlu.librespot.android-1/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
We might need to find a workaround if we want to support older Android-versions.
https://stackoverflow.com/questions/47431337/base64-support-for-different-api-levels
It seems that the player gets stuck here:
Internally librespot-java uses a CompletableFuture
which may not be supported on Android 6, even with desugaring.
If i start playing a song on librespot-android, and then go to my spotify app to change the source of the song, librespot-android crashes :
2022-01-06 23:23:07.091 20210-20258/xyz.gianlu.librespot.android E/AndroidRuntime: FATAL EXCEPTION: player-audio-sink
Process: xyz.gianlu.librespot.android, PID: 20210
java.lang.IllegalStateException: Unable to retrieve AudioTrack pointer for stop()
at android.media.AudioTrack.native_stop(Native Method)
at android.media.AudioTrack.stop(AudioTrack.java:2881)
at xyz.gianlu.librespot.android.sink.AndroidSinkOutput.stop(AndroidSinkOutput.java:99)
at xyz.gianlu.librespot.player.mixing.AudioSink.run(AudioSink.java:160)
at java.lang.Thread.run(Thread.java:920)
This is caused by the line :
if (track != null) track.stop();
(AndroidSinkOutput.java:99)
I tried to fix the issue, and i have a bizarre behavior ; this code :
if (track != null)
{
System.out.println("STATE:" + track.getPlayState());
track.stop();
}
does not crash the player. Maybe i was lucky, or maybe getPlayState() actualizes something inside the AudioTrack ?
Anyway, the state here prints '1' in this case, i.e. AudioTrack.PLAYSTATE_STOPPED
; so a correct fix should be :
if (track != null && track.getPlayState() != AudioTrack.PLAYSTATE_STOPPED)
track.stop();
I'm not sure if it is the "good way" though...
Hi! Is a nyone still using this app? The setup seemed easy and everything looks well, I see my device but when connecting to it, it gets stuck on "Connecting to device" until it times out. Has anyone faced this issue or knows about another solution to it? Thanks a lot.
"Snapshot" is causing the build to fail. I removed them and it worked perfectly.
As ".close()" in the SinkOutput API is expecting to pause the playback, ".start()" should actually resume the playback in case a track has been paused before. Throw a SinkException if the track can't be resumed.
Let me begin with a question. The sink API defines a method ".setVolume()". Should this method be implented in such a way that it:
I think the third option makes sense. @devgianlu what do you think?
How to display pictures in metadata on android,Android imageview does not support direct display of this data
below code right?
`
for (Metadata.Image image : track.getAlbum().getCoverList()) {
if (image.hasFileId() && image.hasSize()) {
byte[] imageBytes = image.toByteArray();
imageView.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
break;
}
}
`
FATAL EXCEPTION: player-queue-152537130
Process: com.djbot, PID: 19945 java.util.concurrent.RejectedExecutionException: Task xyz.gianlu.librespot.audio.cdn.CdnManager$Streamer$InternalStream$$ExternalSyntheticLambda0@53a3dbb rejected from java.util.concurrent
hello,
can you please post an APK for this? Or at least some instructions how to build this in docker (if this is possible at all).
I am using spotify official app as a spotify connect device and its driving me nuts because it constantly dissapears from the device list.
thank you!
If this app is here to showcase how librespot can be included in an Android app, i think it would be good to show the minimal proguard rules that should be added so that you can enable 'minify' for release configurations.
I went trough the hassle of testing that for my app, here are the rules i could come up with :
# The spotify librespot player needs an 'output class'
# for it's audio output ; we need to keep that
-keep class xyz.gianlu.librespot.android.sink.AndroidSinkOutput
# librespot needs reflexion to work internally
# Here we keep the classes it needs
-keep class xyz.gianlu.librespot.mercury.MercuryRequests$GenericJson
{
<init>(com.google.gson.JsonObject); # method <init> i.e. constructor
}
-keep class xyz.gianlu.librespot.mercury.MercuryRequests$ResolvedContextWrapper
{
<init>(com.google.gson.JsonObject); # method <init> i.e. constructor
}
-keep class com.spotify.** {*;}
-keep class xyz.gianlu.librespot.audio.decoders.** {*;}
(from https://github.com/vhaudiquet/BladePlayer/blob/master/app/proguard-rules.pro)
I did not check what was needed for the Android Native decoder or the Tremolo decoder as i don't use them in my app for now.
It appears to be working keeping only those classes, and it cuts in half my app size.
I hope it can be useful to other people, this is why i'm sharing this here (and i think it should be included in the project, either in the proguard rules file or in the readme/documentation)
first off: thank you for this amazing piece of software, I cant wait to use my old xiaomi mi a2 (Android 10) productively angain.
however I cant seem to get it to work. The "Librespot Connect" device does show up on my iPhone, but once I select it, it just says "Connecting..." and keeps playing through my iPhone speakers.
Does anyone have an idea what I could do to make it work?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.