marverenic / Jockey

A music player for Android focused on simplicity, performance, and design
Apache License 2.0
355 stars 122 forks source link

[Question] how do i call this please help ? #252

Closed Dirkstaal closed 7 years ago

Dirkstaal commented 7 years ago

Hi i have a simple question how would i call this

** EqualizedExoPlayer.java

public Equalizer mEqualizer;

** Now i have another class Test.java

I want to call mEqualizer

Tried doing this :

public EqualizedExoPlayer mPlayer; mPlayer.mEqualizer.(anything here)

But it keeps crashing can you please help me not close this ?

marverenic commented 7 years ago

I'm guessing you're getting a NullPointerException, right? By default EqualizedExoPlayer binds to the system equalizer. The custom equalizer is only setup when you call equalizedExoPlayer.setEqualizerSettings(enabled, settings) with the enabled boolean set to true and valid equalizer settings are provided. Whenever the custom equalizer is turned off and the system equalizer gains control of the audio session, the mEqualizer field will be null.

Dirkstaal commented 7 years ago

But how would i be able to resolve the NPE so that i can use mPlayer.mEqualizer in my test.class

Dirkstaal commented 7 years ago

Its just for testing because i want to make a feature in the now playing to switch from artwork to music Visualization Basically Equalizer and Visualizer is the same but i need to call visualizer in another class

Dirkstaal commented 7 years ago

I already made methods in the EqualizedExoPlayer.java Ill upload the class now so that you can take a look if i did it correctly please ?

EqualizedExoPlayer.txt

marverenic commented 7 years ago

I don't really know how the Visualizer class works, so I'm not sure if you're on the right track or not. For the actual NPE, if you're trying to access the custom equalizer, make sure you call equalizedExoPlayer.setEqualizerSettings(true, equalizerSettings) in your test code before you try to access the equalizer object.

Dirkstaal commented 7 years ago

The Visualizer code i implemented is right but if call this in the SurfaceView..

mPlayer.mVisualizer.(something) i get the NPE saying :

Unable to access field "audioFx.Visualizer" on a null object reference On 24 Mar 2017 21:23, "Andrew Bailey" notifications@github.com wrote:

I don't really know how the Visualizer class works, so I'm not sure if you're on the right track or not. For the actual NPE, if you're trying to access the custom equalizer, make sure you call equalizedExoPlayer.setEqualizerSettings(true, equalizerSettings) in your test code before you try to access the equalizer object.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289120717, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlvwSS3yzOuzDUujEhHZoytdGqv2LHks5rpBghgaJpZM4Mnyp7 .

Dirkstaal commented 7 years ago

In the EqualizedExoPlayer.java i Called this :

public EqualizedExoPlayer(Context context, SimpleExoPlayer delegate) {
    mContext = context;
    mExoPlayer = delegate;
    mExoPlayer.setAudioDebugListener(new EqualizerEventListener());
    if (ContextCompat.checkSelfPermission(context,

"android.permission.RECORD_AUDIO") == 0) { setupVisualizer(); } }

This would not cause problems ?

In the SurfaceView i need to call

mPlayer.mVisualizer.getFft(bytesFFT);

I need to use the same Visualizer of EqualizedExoPlayer.java On 24 Mar 2017 22:10, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

The Visualizer code i implemented is right but if call this in the SurfaceView..

mPlayer.mVisualizer.(something) i get the NPE saying :

Unable to access field "audioFx.Visualizer" on a null object reference On 24 Mar 2017 21:23, "Andrew Bailey" notifications@github.com wrote:

I don't really know how the Visualizer class works, so I'm not sure if you're on the right track or not. For the actual NPE, if you're trying to access the custom equalizer, make sure you call equalizedExoPlayer.setEqualizerSettings(true, equalizerSettings) in your test code before you try to access the equalizer object.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289120717, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlvwSS3yzOuzDUujEhHZoytdGqv2LHks5rpBghgaJpZM4Mnyp7 .

Dirkstaal commented 7 years ago

The error

java.lang.RuntimeException: Unable to resume activity {com.marverenic.music.debug/com.marverenic.music.activity.NowPlayingActivity}: java.lang.NullPointerException: Attempt to read from field 'android.media.audiofx.Visualizer com.marverenic.music.player.EqualizedExoPlayer.mVisualizer' on a null object reference

at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4035)

at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4100)

at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3271)

at android.app.ActivityThread.access$1000(ActivityThread.java:218)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1734)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:145)

at android.app.ActivityThread.main(ActivityThread.java:6934)

at java.lang.reflect.Method.invoke(Native Method)

at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)

Caused by: java.lang.NullPointerException: Attempt to read from field 'android.media.audiofx.Visualizer com.marverenic.music.player.EqualizedExoPlayer.mVisualizer' on a null object reference

at com.marverenic.music.FullScreenVisualizers.VisualizerSurfaceView.enable(VisualizerSurfaceView.java:134)

at com.marverenic.music.activity.NowPlayingActivity.onResume(NowPlayingActivity.java:564)

at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1285)

at android.app.Activity.performResume(Activity.java:6730)

at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4024)

at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4100)

at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3271)

at android.app.ActivityThread.access$1000(ActivityThread.java:218)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1734)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:145)

at android.app.ActivityThread.main(ActivityThread.java:6934)

at java.lang.reflect.Method.invoke(Native Method)

at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)

In the EqualizedExoPlayer.java i Called this :

public EqualizedExoPlayer(Context context, SimpleExoPlayer delegate) {
    mContext = context;
    mExoPlayer = delegate;
    mExoPlayer.setAudioDebugListener(new EqualizerEventListener());
    if (ContextCompat.checkSelfPermission(context,

"android.permission.RECORD_AUDIO") == 0) { setupVisualizer(); } }

This would not cause problems ?

In the SurfaceView i need to call

mPlayer.mVisualizer.getFft(bytesFFT);

I need to use the same Visualizer of EqualizedExoPlayer.java On 24 Mar 2017 22:10, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

The Visualizer code i implemented is right but if call this in the SurfaceView..

mPlayer.mVisualizer.(something) i get the NPE saying :

Unable to access field "audioFx.Visualizer" on a null object reference On 24 Mar 2017 21:23, "Andrew Bailey" notifications@github.com wrote:

I don't really know how the Visualizer class works, so I'm not sure if you're on the right track or not. For the actual NPE, if you're trying to access the custom equalizer, make sure you call equalizedExoPlayer.setEqualizerSettings(true, equalizerSettings) in your test code before you try to access the equalizer object.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289120717, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlvwSS3yzOuzDUujEhHZoytdGqv2LHks5rpBghgaJpZM4Mnyp7 .

marverenic commented 7 years ago

It's kind of hard to say without seeing the code that's trying to access the Visualizer.

I'm guessing from your stacktrace that one of your Activities is trying to get a Visualizer object you set up in the service, right? If that's the case, then it probably won't be possible with the current implementation of the player service. As of right now, Jockey has a separate process for the player service and the rest of its UI. Because these processes don't share any memory (unlike threads), you won't be able to access an Object you create in the service on the UI without some form of Inter-Process Communication (e.g. AIDL or broadcasting an Intent), and even if you do send the object through IPC, you would need to keep it up-to-date whenever you create a new instance of it.

Instead of putting the Visualizer in the EqualizedExoPlayer class, you may find it easier to send the AudioSessionId from the service to the UI and have the UI create the Visualizer instance.

Dirkstaal commented 7 years ago

How will i send the AudioSessionId ? Example please

In previous Jockey i just called PlayerController.getAudioSessionId(); On 25 Mar 2017 04:49, "Andrew Bailey" notifications@github.com wrote:

It's kind of hard to say without seeing the code that's trying to access the Visualizer.

I'm guessing from your stacktrace that one of your Activities is trying to get a Visualizer object you set up in the service, right? If that's the case, then it probably won't be possible with the current implementation of the player service. As of right now, Jockey has a separate process for the player service and the rest of its UI. Because these processes don't share any memory (unlike threads), you won't be able to access an Object you create in the service on the UI without some form of Inter-Process Communication (e.g. AIDL or broadcasting an Intent), and even if you do send the object through IPC, you would need to keep it up-to-date whenever you create a new instance of it.

Instead of putting the Visualizer in the EqualizedExoPlayer class, you may find it easier to send the AudioSessionId from the service to the UI and have the UI create the Visualizer instance.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289183474, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlv2Dg0I9fMvvn9AcEOjrFWIE62_g4ks5rpICcgaJpZM4Mnyp7 .

Dirkstaal commented 7 years ago

It will help me alot because then all my Visualization code can be in one class :)

I will really appreciate your help

Also will add the project on my github account On 25 Mar 2017 12:00, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

How will i send the AudioSessionId ? Example please

In previous Jockey i just called PlayerController.getAudioSessionId(); On 25 Mar 2017 04:49, "Andrew Bailey" notifications@github.com wrote:

It's kind of hard to say without seeing the code that's trying to access the Visualizer.

I'm guessing from your stacktrace that one of your Activities is trying to get a Visualizer object you set up in the service, right? If that's the case, then it probably won't be possible with the current implementation of the player service. As of right now, Jockey has a separate process for the player service and the rest of its UI. Because these processes don't share any memory (unlike threads), you won't be able to access an Object you create in the service on the UI without some form of Inter-Process Communication (e.g. AIDL or broadcasting an Intent), and even if you do send the object through IPC, you would need to keep it up-to-date whenever you create a new instance of it.

Instead of putting the Visualizer in the EqualizedExoPlayer class, you may find it easier to send the AudioSessionId from the service to the UI and have the UI create the Visualizer instance.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289183474, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlv2Dg0I9fMvvn9AcEOjrFWIE62_g4ks5rpICcgaJpZM4Mnyp7 .

Dirkstaal commented 7 years ago

Ill send you all the code later what im using its not that much

It will help me alot because then all my Visualization code can be in one class :)

I will really appreciate your help

Also will add the project on my github account On 25 Mar 2017 12:00, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

How will i send the AudioSessionId ? Example please

In previous Jockey i just called PlayerController.getAudioSessionId(); On 25 Mar 2017 04:49, "Andrew Bailey" notifications@github.com wrote:

It's kind of hard to say without seeing the code that's trying to access the Visualizer.

I'm guessing from your stacktrace that one of your Activities is trying to get a Visualizer object you set up in the service, right? If that's the case, then it probably won't be possible with the current implementation of the player service. As of right now, Jockey has a separate process for the player service and the rest of its UI. Because these processes don't share any memory (unlike threads), you won't be able to access an Object you create in the service on the UI without some form of Inter-Process Communication (e.g. AIDL or broadcasting an Intent), and even if you do send the object through IPC, you would need to keep it up-to-date whenever you create a new instance of it.

Instead of putting the Visualizer in the EqualizedExoPlayer class, you may find it easier to send the AudioSessionId from the service to the UI and have the UI create the Visualizer instance.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289183474, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlv2Dg0I9fMvvn9AcEOjrFWIE62_g4ks5rpICcgaJpZM4Mnyp7 .

Dirkstaal commented 7 years ago

Did you get the files ? On 25 Mar 2017 12:09, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

Ill send you all the code later what im using its not that much

It will help me alot because then all my Visualization code can be in one class :)

I will really appreciate your help

Also will add the project on my github account On 25 Mar 2017 12:00, "Dirkie Oosthuizen" dirkstaaldullen@gmail.com wrote:

How will i send the AudioSessionId ? Example please

In previous Jockey i just called PlayerController.getAudioSessionId(); On 25 Mar 2017 04:49, "Andrew Bailey" notifications@github.com wrote:

It's kind of hard to say without seeing the code that's trying to access the Visualizer.

I'm guessing from your stacktrace that one of your Activities is trying to get a Visualizer object you set up in the service, right? If that's the case, then it probably won't be possible with the current implementation of the player service. As of right now, Jockey has a separate process for the player service and the rest of its UI. Because these processes don't share any memory (unlike threads), you won't be able to access an Object you create in the service on the UI without some form of Inter-Process Communication (e.g. AIDL or broadcasting an Intent), and even if you do send the object through IPC, you would need to keep it up-to-date whenever you create a new instance of it.

Instead of putting the Visualizer in the EqualizedExoPlayer class, you may find it easier to send the AudioSessionId from the service to the UI and have the UI create the Visualizer instance.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marverenic/Jockey/issues/252#issuecomment-289183474, or mute the thread https://github.com/notifications/unsubscribe-auth/ARrlv2Dg0I9fMvvn9AcEOjrFWIE62_g4ks5rpICcgaJpZM4Mnyp7 .

marverenic commented 7 years ago

I'm not sure that you're approaching this problem correctly. EqualizedExoPlayer is basically a layer built on top of ExoPlayer that's responsible for binding and unbinding Equalizers, and ExoPlayer is responsible for all media playback. You've added an EqualizedExoPlayer field to your VisualizerSurfaceView class, but I don't think it's ever initialized, and I don't know that you would be able to ever initialize it properly.

Jockey will have one instance of EqualizedExoPlayer (which in turn has one instance of ExoPlayer). This instance is going to be in the player service – and this service lives in a separate process from the Activities. Because they're in separate processes, an Object that's in the service can't exist in an Activity. A copy of the Object can exist, but because EqualizedExoPlayer changes states very frequently it's not reasonable to try to keep the instance of the EqualizedExoPlayer alive in both the service and in your Activity (since any changes to one instance would not become visible to the other instance without making another copy of it).

Your Visualizer code will only be able to reference code in the PlayerController interface and its descendants. All other classes in the player package are only used by the service, and you cannot get these instances directly to the UI. You will have to modify PlayerController and ServicePlayerController to allow accessing the AudioSessionID in the UI, and then create your Visualizer similar to how you did before (in the oldCode.txt attachment). As a warning, though, this is not trivial. ExoPlayer changes its AudioSessionID all the time (sometimes in the middle of a song), and keeping this up-to-date may not be possible without introducing latency from IPC.

I'm going to close this issue because it is outside the scope of the project currently. If you still want to make this change, then I would recommend you study the code in ServicePlayerController carefully and become familiar with RxJava and AIDL. Feel free to ask questions about how Jockey is structured, but development questions should be taken to a forum like StackOverflow.