devgianlu / librespot-android

A demo app that runs librespot-java on Android
33 stars 13 forks source link

Use `MediaCodec` as decoder #9

Closed devgianlu closed 3 years ago

devgianlu commented 3 years ago
devgianlu commented 3 years ago

@funtax @mitschwimmer It's working! Feel free to make changes if needed.

To force it to use the native decoder change this line: https://github.com/devgianlu/librespot-android/blob/168e9e39428ccad829c65de4e4c4527b3ea6b7ea/app/build.gradle#L25

mitschwimmer commented 3 years ago

@devgianlu great to hear that this worked out! Sadly it does not on my test device. The extractor is not finding a track in my case. Do you have an idea why?

2021-05-03 20:32:04.325 13829-13934/xyz.gianlu.librespot.android E/x.g.l.a.d.Decoders: Failed initializing Codec instance for VORBIS
    java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at xyz.gianlu.librespot.audio.decoders.Decoders.initDecoder(Decoders.java:54)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:140)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271)
        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)
     Caused by: xyz.gianlu.librespot.player.decoders.Decoder$CodecException: No tracks found.
        at xyz.gianlu.librespot.player.decoders.AndroidNativeDecoder.<init>(AndroidNativeDecoder.java:51)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at xyz.gianlu.librespot.audio.decoders.Decoders.initDecoder(Decoders.java:54) 
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:140) 
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271) 
        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) 
2021-05-03 20:32:04.325 13829-13934/xyz.gianlu.librespot.android E/x.g.l.p.Player: Failed loading track.
    java.io.UnsupportedEncodingException: VORBIS
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:142)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271)
        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)
2021-05-03 20:32:04.325 13829-13866/xyz.gianlu.librespot.android D/AudioTrack: stop(73): called with 0 frames delivered
devgianlu commented 3 years ago

@mitschwimmer What are you trying to play?

mitschwimmer commented 3 years ago

Rick as given in the app module.

devgianlu commented 3 years ago

Is there anything more in the logs coming directly from the extractor? Also, could you try playing something else?

mitschwimmer commented 3 years ago

Played some different URI's but same result. I went through the debugger but only found that there is indeed no track found by the extractor. I am attaching a log file. I can't seem to relate a message to the extractor but filtering for "audio" shows some messages that might reveal something. I need to leave now but tomorrow I could try to compare the logs between tremolo and mediacodec to see which messages actually differ. librespot android log 3-5-21.txt

devgianlu commented 3 years ago

I see some

2021-05-03 21:36:34.910 1156-1903/? E/Utils: did not find mime type

But not entirely sure. Will have a closer look when possible. FYI, I tested on Android 6 (Samsung device).

funtax commented 3 years ago

FYI, I tested on Android 6 (Samsung device).

Yearh you got it down to Android 6? When I tested librespot-java on Android last year, Android 8+ was required because of Java-Streams or so, happy to see it's working now on a lower version!

With the predefined track it's working on my Android 10-device. Hope I can find some time tomorrow to check again with other songs.

mitschwimmer commented 3 years ago

It seems to me the issue is somehow related to Android 11. @devgianlu, my suggestion would be to open an issue that this needs fixing. I do not think this should keep you from merging as Android 11 is kind of niche, still.

devgianlu commented 3 years ago

I can try it on Android 11 as my main device runs that.

On merging, I wanted to make an MP3 decoder too since it should be supported already.

funtax commented 3 years ago

On Android 7, after patching the Base64-stuff, I get this Exception:

E/x.g.l.a.d.Decoders: Failed initializing Codec instance for VORBIS
    java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
        at xyz.gianlu.librespot.audio.decoders.Decoders.initDecoder(Decoders.java:54)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:140)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
     Caused by: xyz.gianlu.librespot.player.decoders.Decoder$CodecException: No tracks found.
        at xyz.gianlu.librespot.player.decoders.AndroidNativeDecoder.<init>(AndroidNativeDecoder.java:51)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430) 
        at xyz.gianlu.librespot.audio.decoders.Decoders.initDecoder(Decoders.java:54) 
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:140) 
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
        at java.lang.Thread.run(Thread.java:761) 
E/x.g.l.p.Player: Failed loading track.
    java.io.UnsupportedEncodingException: VORBIS
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.load(PlayerQueueEntry.java:142)
        at xyz.gianlu.librespot.player.playback.PlayerQueueEntry.run(PlayerQueueEntry.java:271)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)

With libtremolo it seems to work fine.

devgianlu commented 3 years ago

Mhh, guess this is quite common. I'll make some changes so that if a decoder doesn't manage to initialize, it'll try the next one.

devgianlu commented 3 years ago

@funtax @mitschwimmer Should work everywhere now.

mitschwimmer commented 3 years ago

Hm, could you add logging? Right now it is hard to see which decoder is in use. Under which circumstances would it be the Android Native vorbis decoder?

devgianlu commented 3 years ago

They are "evaluated" in this order:

I have also added the decoder name to the logs.