Closed ne0rrmatrix closed 1 week ago
Here is an example implementation. It is in sample app under views. MediaElement page. https://github.com/CommunityToolkit/Maui/pull/2076
Stacktrace:
at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20830
at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 75
at AndroidX.Media3.Common.IPlayerListener.OnPositionDiscontinuityDeprecated(Int32 reason) in D:\a\_work\1\s\generated\androidx.media3.media3-common\obj\Release\net8.0-android\generated\src\AndroidX.Media3.Common.IPlayer.cs:line 1716
at AndroidX.Media3.Common.IPlayerListener.n_OnPositionDiscontinuityDeprecated_I(IntPtr jnienv, IntPtr native__this, Int32 reason) in D:\a\_work\1\s\generated\androidx.media3.media3-common\obj\Release\net8.0-android\generated\src\AndroidX.Media3.Common.IPlayer.cs:line 1703
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPI_V(_JniMarshal_PPI_V callback, IntPtr jnienv, IntPtr klazz, Int32 p0) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 55
--- End of managed Java.Lang.AbstractMethodError stack trace ---
java.lang.AbstractMethodError: abstract method "void androidx.media3.common.Player$Listener.onPositionDiscontinuity(int)"
at crc64ceb75e76f4b66147.MediaManager.n_onPositionDiscontinuity(Native Method)
at crc64ceb75e76f4b66147.MediaManager.onPositionDiscontinuity(MediaManager.java:260)
at androidx.media3.exoplayer.ExoPlayerImpl.lambda$updatePlaybackInfo$13(ExoPlayerImpl.java:1946)
at androidx.media3.exoplayer.ExoPlayerImpl$$ExternalSyntheticLambda18.invoke(Unknown Source:8)
at androidx.media3.common.util.ListenerSet$ListenerHolder.invoke(ListenerSet.java:332)
at androidx.media3.common.util.ListenerSet.lambda$queueEvent$0(ListenerSet.java:216)
at androidx.media3.common.util.ListenerSet$$ExternalSyntheticLambda1.run(Unknown Source:6)
at androidx.media3.common.util.ListenerSet.flushEvents(ListenerSet.java:238)
at androidx.media3.exoplayer.ExoPlayerImpl.updatePlaybackInfo(ExoPlayerImpl.java:2028)
at androidx.media3.exoplayer.ExoPlayerImpl.setMediaSourcesInternal(ExoPlayerImpl.java:2244)
at androidx.media3.exoplayer.ExoPlayerImpl.setMediaSources(ExoPlayerImpl.java:608)
at androidx.media3.exoplayer.ExoPlayerImpl.setMediaItems(ExoPlayerImpl.java:571)
at androidx.media3.common.BasePlayer.setMediaItems(BasePlayer.java:56)
at androidx.media3.common.BasePlayer.setMediaItem(BasePlayer.java:41)
at androidx.appcompat.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.n_onClick(Native Method)
at androidx.appcompat.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.onClick(AlertDialog_IDialogInterfaceOnClickListenerImplementor.java:31)
at androidx.appcompat.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1068)
at android.widget.AdapterView.performItemClick(AdapterView.java:330)
at android.widget.AbsListView.performItemClick(AbsListView.java:1265)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3278)
at android.widget.AbsListView.onTouchUp(AbsListView.java:4256)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3997)
at android.view.View.dispatchTouchEvent(View.java:15655)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3114)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2787)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:490)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1904)
at android.app.Dialog.dispatchTouchEvent(Dialog.java:910)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:448)
at android.view.View.dispatchPointerEvent(View.java:15919)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:7021)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6815)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6229)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6286)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6252)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:6417)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6260)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:6474)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6233)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6286)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6252)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6260)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6233)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:9211)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:9162)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:9131)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:9337)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:267)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loopOnce(Looper.java:162)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
This appears to be an issue with an incompatible class library. The common library is throwing errors on IPlayerIlistener
Added minimal reproduction. Unzip folder. Load top level project in Visual Studio or VS Code. Launch in Android emulator or create apk and put on device. Run program and click either stop or scrub timeline by using any control.
Hey @moljac! Thanks for doing the Media3 bindings! Any chance you could help us resolve this?
My guess is that we're missing a binding in the new Media3 libraries.
We're blocked from porting CommunityToolkit.Maui.MediaElement
to Media3
until we can get this resolved or find a workaround.
Do you need the #region IPlayer.IListener implementation method stubs
section in MediaManager.android.cs
? The interface methods have default implementations so I don't think you need to provide additional empty implementations.
The issue may be you are providing:
public void OnPositionDiscontinuity (int reason) { }
while the IPlayerListener
method is called something else:
void OnPositionDiscontinuityDeprecated (int reason) { ... }
Yes we need the iPlayer listener. It is critical. We use it extensively and will continue to need it while we support legacy APIs and for monitoring many things currently.
I'm not suggesting you remove IPlayerListener
, just that you remove the "method stubs" that aren't currently doing anything. If this is just a simple sample and you need them in your real project I would suggest trying it with the correct method name.
Yes I would be happy to do that! Sorry I was confused there. It is the Maui Community toolkit. I did not add the stubs. They have been there since I started helping out last year. I will go through them and remove the ones we are not using. The sample I provided was just a ripped sample that I made up in an afternoon as I did not want to link a huge sample app with many other things listed. I am currently working on migrating the Dotnet Maui Community toolkit to use media 3.
Do you need the
#region IPlayer.IListener implementation method stubs
section inMediaManager.android.cs
? The interface methods have default implementations so I don't think you need to provide additional empty implementations.The issue may be you are providing:
public void OnPositionDiscontinuity (int reason) { }
while the
IPlayerListener
method is called something else:void OnPositionDiscontinuityDeprecated (int reason) { ... }
The implementation stubs are required or the app will crash. Even when empty they do something. BTW I have tried other media 3 nugets which with very minor changes to the code I have do work 100 percent of the time. I have tested https://www.nuget.org/packages/Anjo.Android.Media3.ExoPlayer and it works out of the box with little to no modifications. I can't use that as it would not be allowed at all. The source is unavailable and not on GitHub in a public repo. But if it is indeed media 3 and the same as what you have done I have to think that this is a binding issue and not an issue with my code.
Do you need the
#region IPlayer.IListener implementation method stubs
section inMediaManager.android.cs
? The interface methods have default implementations so I don't think you need to provide additional empty implementations. The issue may be you are providing:public void OnPositionDiscontinuity (int reason) { }
while the
IPlayerListener
method is called something else:void OnPositionDiscontinuityDeprecated (int reason) { ... }
The implementation stubs are required or the app will crash. Even when empty they do something. BTW I have tried other media 3 nugets which with very minor changes to the code I have do work 100 percent of the time. I have tested https://www.nuget.org/packages/Anjo.Android.Media3.ExoPlayer and it works out of the box with little to no modifications. I can't use that as it would not be allowed at all. The source is unavailable and not on GitHub in a public repo. But if it is indeed media 3 and the same as what you have done I have to think that this is a binding issue and not an issue with my code.
It's not an issue with your implementation, it's because Anjo's and the others are mostly copies of the work I've done here: https://github.com/Baseflow/ExoPlayerXamarin/pull/166
I think I had this issue too all the way back when Media3 was still ExoPlayer, I ended up removing the deprecated methods (https://github.com/ArchangelWTF/ExoPlayerXamarin/blob/22591a98b8448f1b716c1cb74d2c700164c54361/Media3.Common/Transforms/Metadata.xml#L11) as well as setting the entire listener class to abstract(https://github.com/ArchangelWTF/ExoPlayerXamarin/blob/22591a98b8448f1b716c1cb74d2c700164c54361/Media3.Common/Transforms/Metadata.xml#L17) to force them to be fully implemented by people trying to use the Listener (because otherwise the app would crash anyway)
There was a reason I removed the deprecated methods over renaming but I cant remember what it was, it might be related to the crash.
Maybe that gives some pointers for the AndroidX maintainers to fix the issue.
This needs to be implemented https://github.com/xamarin/AndroidX/blob/d126bba06db14db94517403df0f3c7dd31d863d7/source/androidx.media3/media3-exoplayer/Transforms/Metadata.xml#L153 and https://github.com/xamarin/AndroidX/blob/d126bba06db14db94517403df0f3c7dd31d863d7/source/androidx.media3/media3-exoplayer/Transforms/Metadata.xml#L135 The second one is not used and if removed causes app to crash while seeking. It still needs to be there as a stub. The first one is used by our app to provide video dimensions to developers.
Android application type
Not applicable
Affected platform version
VS 2022, Dotnet Maui 8.0.21, Dotnet 8.x
Description
When enabling
PlayerListener
interface I am having issues with**Java.Lang.AbstractMethodError:** 'abstract method "void androidx.media3.common.Player$Listener.onPositionDiscontinuity(int)"'
on adding a media item or seeking. If I never add the listener exoplayer has no issues. This worked previously with version 2 and I have updated it to support version 3. Adding any media item using any available method and then attempting to change it crashes the app. Seeking using timeline or by implementing seek method has same result.Note: The log output below contains the crash info for when you scrub the timeline.
Steps to Reproduce
IPlayerListener
Did you find any workaround?
Do not implement the listener or do not enable it when changing media or scrubbing the timeline. Either will solve issue.
Relevant log output