Glitch9Inc / Glitch9-Support

GNU General Public License v3.0
0 stars 0 forks source link

[NativeMediaPlayer] [BUG] Errors in data chunk when playing single item #24

Closed Manurocker95 closed 19 hours ago

Manurocker95 commented 2 days ago

Playing a playlist with a single item throws this error:

AndroidJavaException: java.lang.OutOfMemoryError: Failed to allocate a 104 byte allocation with 1958456 free bytes and 1912KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC. java.lang.OutOfMemoryError: Failed to allocate a 104 byte allocation with 1958456 free bytes and 1912KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC. com.google.gson.reflect.TypeToken.(TypeToken.java:72) com.google.gson.reflect.TypeToken.get(TypeToken.java:303) com.google.gson.Gson.(Gson.java:114) com.glitch9.media2.playlist.Playlist.(Playlist.java:41) com.glitch9.media2.Media2.processData(Media2.java:137) com.glitch9.media2.Media2.$r8$lambda$2ciMAVAim7f76ihqAWdchtbEwgA(Unknown Source:0) com.glitch9.media2.Media2$$ExternalSyntheticLambda1.accept(Unknown Source:4) com.glitch9.media2.utils.DataReceiver.receiveDataChunk(DataReceiver.java:40) com.glitch9.media2.Media2.receiveDataChunk(Media2.java:117) com.unity3d.player.UnityPlayer.nativeRender(Native Method) com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(Unknown Source:0) com.unity3d.player.UnityPlayer$F$a.handleMessage(Unknown Source:122) android.os.Handler.dispatchMessage(Handler.java:102) android.os.Looper.loopOnce(Looper.java:210) android.os.Looper.loop(Looper.java:299) com.unity3d.player.UnityPlayer$F.run(Unknown Source:24) UnityEngine.AndroidJNISafe.CheckException () (at <00000000000000000000000000000000>:0) UnityEngine.AndroidJavaObject._Call (System.IntPtr methodID, System.Object[] args) (at <00000000000000000000000000000000>:0) Glitch9.NativePlugins.NativeMediaPlayer.MediaPlayer.HandleInitialization (System.Boolean playWhenReady, System.Int32 startMediaItemIndex, System.Single startPosition) (at <00000000000000000000000000000000>:0) Glitch9.NativePlugins.NativeMediaPlayer.MediaPlayer.Initialize (Glitch9.NativePlugins.NativeMediaPlayer.Playlist playlist, System.Nullable1[T] playWhenReady, System.Nullable1[T] startMediaItemIndex, System.Single startPosition) (at <00000000000000000000000000000000>:0)

Manurocker95 commented 2 days ago

Additionally, this warning:

AndroidJNIHelper.GetSignature: using Byte parameters is obsolete, use SByte parameters instead UnityEngine.AndroidJavaObject:_Call(String, Object[]) Glitch9.NativePlugins.NativeMediaPlayer.MediaPlayer:HandleInitialization(Boolean, Int32, Single) Glitch9.NativePlugins.NativeMediaPlayer.MediaPlayer:Initialize(Playlist, Nullable1, Nullable1, Single)

Glitch9Inc commented 2 days ago

2024-07-04 update

will work on iOS if this works on Manurocker95's end.

Manurocker95 commented 1 day ago

2024-07-04 update

  • changed the logic to send each media item + compression
  • added artwork size limit (2mb)
  • test successful on Pixel 6 (8gb ram), Galaxy note 8 (6gb ram)

will work on iOS if this works on Manurocker95's end.

Not working: That version is triggering this:

image

Manurocker95 commented 1 day ago

Crashing on Retroid Pocket 4, Redmi Note 9 and Anbernic 405

Manurocker95 commented 1 day ago

What trigger the error is:

 // java: public void receiveMediaItem(int mediaItemIndex, String json) 
 foreach ((int index, string json) mediaItemData in DataTransferUtil.SendMediaItems(CurrentPlaylist))
 {
     _plugin.Call(RECEIVE_MEDIA_ITEM, mediaItemData.index, mediaItemData.json);
 }
Manurocker95 commented 1 day ago

Before crashing the following events are triggered:

ON_PLAYLIST_UPDATED ON_INIT_CHANGED_TRUE ON_IS_PLAYING_CHANGED_FALSE

Glitch9Inc commented 1 day ago

image This line is a big hint. I believe you are using PersistentDataPath but it's loading audio from StreamingAssets

Glitch9Inc commented 1 day ago

Yeah that was crucial. The new playlist factory was not passing the correct uriType. I'll send you the updated version with this fix.

Manurocker95 commented 1 day ago

Yeah that was crucial. The new playlist factory was not passing the correct uriType. I'll send you the updated version with this fix.

Noice! I sent you by mail an example that crashes so you can check if that also works :)

Manurocker95 commented 22 hours ago

Playlist.AddMediaitem(mediaItem) overrides the mediaItem datapath in "prepareMediaItem" within "playlist DownloadDirectory":

    private MediaItem PrepareMediaItem(MediaItem item)
    {
        item.PlaylistIndex = Index;
        item.Index = index;
        item.PersistentDataPath = DownloadDirectory;

        if (item.UriType != UriType.Unknown && item.UriType != UriType)
        {
            Debug.LogWarning($"MediaItem#{item.Index} UriType is not equal to the Playlist's UriType. Setting it to the Playlist's UriType.");
        }

        item.UriType = UriType;
        return item;
    }
Manurocker95 commented 22 hours ago

In addition, mediaitem constructor should set PersistentDataPath value to URL in constructor when uritype is PersistentDatapath

Manurocker95 commented 22 hours ago

In addition, you now need to set the whole persistentdatapath value instead of the relative value so AFTER doing playlist.AddItem, u need to do

            playlist.MediaItems[playlist.MediaItems.Count-1].PersistentDataPath = Application.persistentDataPath + "/" + filePath

            or modify the value in the prepare
Manurocker95 commented 22 hours ago

MediaItem constructor should be something like:

    public MediaItem(UriType uriType, string url, MediaMetadata metadata = null)
    {
        this.uriType = uriType;
        this.url = url;
        this.metadata = metadata;

        if (uriType == UriType.PersistentDataPath)
        {
            this.persistentDataPath = Application.persistentDataPath + "/" + url;
        }
    }

and prepare item in Playlist:

    private MediaItem PrepareMediaItem(MediaItem item)
    {
        item.PlaylistIndex = Index;
        item.Index = index;
        if (string.IsNullOrEmpty(item.PersistentDataPath)
             item.PersistentDataPath = DownloadDirectory;

        if (item.UriType != UriType.Unknown && item.UriType != UriType)
        {
            Debug.LogWarning($"MediaItem#{item.Index} UriType is not equal to the Playlist's UriType. Setting it to the Playlist's UriType.");
        }

        item.UriType = UriType;
        return item;
    }
Manurocker95 commented 22 hours ago

That makes it work on Editor but now on android is triggering:

Unity has received an error from Native: Error: 1, -2147483648

Manurocker95 commented 22 hours ago

That makes it work on Editor but now on android is triggering:

Unity has received an error from Native: Error: 1, -2147483648

And I'm using the same exact audios which are .mp3. All of them worked before the data chunk rework.

Manurocker95 commented 20 hours ago

Okay, it seems the URL is skipped when "downloading":

2024/07/05 13:39:03.507 28847 28847 Warn System.err [NativeMediaPlayer] getPersistentDataPathAsset: /Audio/Albums/MySong.mp3

2024/07/05 13:39:03.508 28847 28847 Warn System.err [NativeMediaPlayer] File does not exist at /storage/emulated/0/Android/data/com.Manurocker95.MyProject/files/MySong.mp3. Downloading...

As you can see "Audio/Albums/" is completely skipped

Manurocker95 commented 19 hours ago

With latest update and manually sending Application.persistentDatapath + relativepath in persistentdatapath and URL, the audios play again.