memen45 / SubMusic

Sync music and podcasts to your Garmin watch from your own SubSonic or Ampache server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Media Error Occured on fetching playlist

tarioch opened this issue · comments

I just installed the app today and when I'm trying to sync I'm getting the error "Media Error Occured" when it's trying to fetch the playlist.

My setup is

server address: http://myhost.com:44
username: myuser
api key: mypassword

I'm running airsonic which works very well with all other subsonic clients: https://airsonic.github.io/

One thing that I found a bit weird is that on the config page, it shows "alpha 0.0.1" but as I installed today I think it should be 0.0.3 .

I'm using a vivoactive 4

Thank you for trying the app and providing feedback!

As far as I know, it is not possible to use other ports than the default http and https ports. The "Media Error Occured" throws due to the ":"in the URL. If you can make your server available over http or https, it should start working. I have only tested with HTTPS (port 443) though, and I have seen issues with others trying to connect using HTTP, so let me know if http works too.

With regards to your second remark: you are completely right! I fixed it locally, but didn't push an update for it yet.

Thanks for your quick feedback. I now tried with http://my.host.com (I only need the one with port when I'm outside my wlan and as the sync happens only in the wlan anyway it's good enough) and I'm still getting the media error.

Is there any way to add some more logging/debugging to it to figure out what's failing?
Also have you thought about wheter you want to keep the app closed source or making it open source?

Are you able to get a response if you use "http://my.host.com/rest/ping" in the browser? The browser should show some XML response if the URL is working (right click -> view source).
If that does work, "http://my.host.com" as URL should work as well and not throw an error,

If the error remains, there should be something wrong in the code. If you are willing to help debug, there should be a file called CIQ_LOG.YAML in /GARMIN/APPS/LOGS on the device. It should provide a cause of error and a stack trace that could help me solve it.

ping request works, log has exception in it


---
Error: Unhandled Exception
Time: 2020-06-10T11:07:19Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 2
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x100018df
---
Error: Unhandled Exception
Time: 2020-06-10T11:07:19Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 2
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x100018df

Response for the ping rest call (after adding required params), so it was

http://my.host.com/rest/ping?u=myuser&p=mypassword&c=foo&v=1.15

<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.15.0"/>

Hmm, unfortunately the stack trace is not too comprehensive. The URL seems fine though. I do see however that I missed the required parameters "c" and "v", as Nextcloud does not require them.
If you leave the c and v parameters, do you get a subsonic-response - status="failed"?

I am not planning on keeping the app closed source at all. I wanted to clean up one part of the code before publishing as it is only functional, but not good code (still too much based on some example code). As soon as I have time to rewrite it, I will publish the code in this repository.

I think that's it, it fails if c or v are missing. According to this http://www.subsonic.org/pages/api.jsp they are mandatory.

Thanks again for this app and your very fast responses.

Thanks a lot for your feedback and help. Just now I uploaded version 0.0.4 to the app store. I hope this solves the issues and allows you to connect to your server.

Please let me know if it does, as I can then update the description and notify some other users about this.

Thanks, I got further with this. Now I see my playlists. But unfortunately when I try to sync it, it fails again with the media error.

---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T13:17:43Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 3
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a0a
---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T13:17:43Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 3
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a0a
---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T13:18:07Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 3
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a0a
---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T13:18:07Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 3
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a0a

Great! That was the hardest part. I think I figured out the subsequent problem. I fixed it and pushed it to the store (version 0.0.5).

  • I added checks for the responses to have status => "ok", but downloading only returns binary data, so that check failed.

Thanks a lot!

Unfortunately still fails with 0.0.6


---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T14:34:51Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 5
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a3b
---
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T14:34:51Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 5
Filename: A6A85331
Appname: SubMusic
Stack: 
  - pc: 0x10001a3b

Sorry, I am unable to reproduce the error.

  • What type of songs do you have stored? The watch supports ADTS, MP3, M4A and WAV.
  • Would it be possible to provide me (privately) with some temporary account, so I can evaluate the requests in more detail?

Sure, sent you a message over the garmin iq page.

Thanks! I get an SECURE_CONNECTION_REQUIRED response. In the simulator I can disable HTTPS requirements, which allows it to work. However, I do not think that this is possible on the device.

I will improve the error reporting in the following version (0.0.7). However, the problem resides with Connect IQ and the choice to only support HTTPS connections, unfortunately. This would require setting up a Let's Encrypt service on your machine (which is free and quite simple fortunately).

Thanks a lot, a bit weird that the other requests work on http. Anyway I switched to https and unfortunately still the same problem, sent you a mail with credentials.

Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2020-06-10T17:40:34Z
Part-Number: 006-B3225-00
Firmware-Version: '4.70'
Language-Code: eng
ConnectIQ-Version: 3.1.8
Store-Id: 600bd75f-6ccf-4ca5-bc7a-0a4fcfdcf794
Store-Version: 6
Filename: 8ED2EFC8
Appname: SubMusic
Stack: 
  - pc: 0x10001a6a

Testing against your server I get a

NETWORK_RESPONSE_TOO_LARGE = -402 | Serialized response was too large.

I have checked the Subsonic API, but I cannot find a way to limit the number of results per request. On sync, it tries to retrieve the playlist in a single request. So the response will be an array of all songs including all metadata. I do not know the exact maximum size of a response.

Do you know if Subsonic supports paged responses?

Unfortunately still fails with 0.0.6

Was the fetching playlists working with this version already?

Fetching of the list of playlists works fine (I see my playlists and can select the right one, but it fails when I then try so sync one of the playlists).

I now created a simpler playlist with just one song in it, but the same problem happens.

According to this: http://www.subsonic.org/pages/api.jsp several of the apis support pagination, but I don't think the playlist one does.

sorry, not sure what happened the last time, now it works with synchronizing the single entry playlist

This is remarkable. I thought I could reproduce the last error, and it still does not work for me:

INVALID_HTTP_BODY_IN_NETWORK_RESPONSE = -400

When I load the download URL in the browser:
On your server:

  • response header Content-Type: application/x-download
  • browser starts to download the file
  • Connect IQ reports conflicting body (since request is done for mp3 encoding)

Whereas on my server (Nextcloud + music app):

  • response header Content-Type: audio/mpeg; charset=utf-8
  • plays the song in the browser
  • Connect IQ downloads as expected

I am not sure how to proceed, since this seems a server side implementation difference. Does the Subsonic API even specify this response Content-Type?

I don't think it's specified. What I noticed is that /download gives Content-Type: application/x-download but if you use /stream it gives Content-Type: audio/mpeg

I think stream might be the better one anyway as this avoids having to deal with unsupported audio formats.

Yes I just discovered that too. I assumed stream method was for retrieving parts of songs, but it isnt. I will test with the /stream method and update if it works correctly!

Will be version 0.0.8. Hoping that this finally solves it!

Saw that you pushed 0.0.8, now I'm getting a 402 even on only selecting a 1 entry list

Uninstalled app and reinstalled. A couple more interesting points

  • first time I'm able to fetch the test playlist (with one song)
  • another dummy playlist (with also one song) failed with -1005, according to dev doc that's UNABLE_TO_PROCESS_MEDIA probably the media was not converted
  • afterwards even trying to resync the test playlist (which worked before), will fail with a -402

Haha, you found the exact reason I did not publish the code yet. The keeping track of playlists requires a rewrite to make it more robust.

I have fixed the former bug, allowing to remove playlists even when they are not yet completely synced. However, the UNABLE_TO_PROCESS_MEDIA is weird. The song element "suffix" is used to determine the media encoding, so if that element is not one of the four supported suffixes, it might throw such an error. Did you verify the suffix is one of ADTS, MP3, M4A or WAV.

I might have an idea what's going on. The file has m4a, but as you're accessing it with the stream api, it's actually converted to mp3.

I think I also found another issue, it has problems with file names with special characters (e.g. &). I think now that you use the stream api, it would make more sense to not use the original filename (which I'm guessing you're doing right now) and instead use maybe the id and add .mp3. That way it's save from special characters and should solve the encoding issue as well. If needed you could even set the parameter format=mp3 on the stream call to be more explicit.

The app is accessing by id in either case, so titles should not be the issue. If stream always returns an mp3, then I have to adapt the code indeed, however I will have to test this on Nextcloud as well, as otherwise it may break.

Makes sense, was just guessing here as I see issues with files that have a path (not title) like
Klaus Badelt &amp; Hans Zimmer/Pirates of the Caribbean_ Soundtrack Treasures Collection/1-01 Klaus Badelt - Fog Bound.mp3

But if always the id (which is numeric) is used, then this shouldn't be an issue.

I am just testing with Nextcloud and it returns Content-Type: audio/mp4, I can reproduce your -1005 error. Also in the browser this does not work ("No video with supported format and MIME type found"). The format=mp3 parameter does give the same Content-Type. The best I can do here is just skip over a song if downloading fails. That way the rest of the sync will still work, instead of cancelling as it is now.

Does adding the format=mp3 return a Content-Type: audio/mpeg for you? If so, I might add that parameter to ensure mp3 is tried if the transcoding is supported by the server.

On my server if I use the stream url (independent of if I aadd the format=mp3 param or not) I'm getting Content-Type: audio/mpeg and the file is converted. If I use download, I get a different file than if I use stream, the stream gives me an mp3 converted file.

After another couple of reinstalls and avoiding different playlists and files which are problematic (as you said, path does actually not make any troubles, I guess that was just caused by earlier issues). I was now able to sync a playlist with 27 songs in it :) Adding one more makes it fail. Are your playlists so short or does the nextcloud impl add less metadata?

Anyway, I think this is great progress (from not able to connect, to able to sync 27 songs in a playlist). Thank you again very much.

Do you see any way to work around the issue with the response size of the getPlaylist?

Indeed I only tested with ~10 songs per playlist. Unfortunately the response limit is very low, somewhere around 16kB or 32kB. There is no simple way around this currently.

I have made an update again:

  • default format=mp3 is requested
  • if stream failed, the song will be skipped (for all subsequent syncs) and continues to next song
  • removing a playlist that was not yet synced, will remove it from to_sync (so accidentally adding a too large playlist does no longer require reinstall)

Will upload it shortly (Version 0.0.9).

Sound's great (do you never sleep? ;)). Is there a way to "stream" the response? As there isn't too much info needed from that response if there would be a way to work on the response stream, that might solve the issue.

Started a thread on the forum to see if anyone has an idea, if we could stream it, I think it would be possible to handle it
https://forums.garmin.com/developer/connect-iq/f/discussion/229268/way-to-receive-web-request-response-as-a-stream

I don't think that is possible. Also other options like bluetooth etc are not possible due to the same memory limitation.

The most feasible option would be to add support for Ampache API. Looks much better and allows paged requests on almost all methods. Will look into this when I have more time.

Thanks a lot for the efforts on investigating! I will close this issue as the initial problem is fixed.

Can you tell me the necessary stuff that you need on that getPlaylist call? I'm thinking about creating a small proxy that will do the real request and then strip out all the unnecessary stuff, that way it should reduce the response quite a bit, so I can also sync larger playlists.

The metadata should be delivered on downloading the song itself. Up to now, only the playlist name is shown to the user. Therefore for the getPlaylist request, the only thing required of each of the songs are the "id" elements. If you strip all the other elements from the song objects, I think it will take a while before you hit the limit again!

If anyone is interested, I started creating it https://github.com/tarioch/subsonic-api-proxy still testing a bit more, I also want to something to have all the files as mp3, as in my setup the stream api will always return mp3 independent of the filename or metadata of the file, because of the on the fly conversion.