Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YouTube Music -> Last.FM scrobbling same songs multiple times #156

Closed
roos-robert opened this issue Jun 11, 2024 · 27 comments
Closed

YouTube Music -> Last.FM scrobbling same songs multiple times #156

roos-robert opened this issue Jun 11, 2024 · 27 comments
Labels
bug Something isn't working

Comments

@roos-robert
Copy link

roos-robert commented Jun 11, 2024

Describe the bug
Hi and thank you for your work on this great scrobbler!
I'm running into an issue using YouTube Music and scrobbling to Last.FM. It seems to be fetching the played history over and over, scrobbling the same songs to Last.FM, for example:

image

I played this song once, and it keeps being scrobbled over and over (same with other songs).

As an example:
image

Songs found here (just turned the listening history on) should be maybe 20% of that amount.

To Reproduce
Steps to reproduce the behavior:

  1. Install locally (nodejs)
  2. Setup YouTube Music with local file
  3. Setup Last.FM with local file
  4. Play music from iOS device

Expected behavior
To only scrobble a song once, not fetch the play history over and over and scrobble songs multiple times.

Logs
A piece of the logs, all of the songs saying they are being scrobbled to Last.FM here was listened to an hour ago.

[2024-06-11 10:29:05.586 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:29:05.585 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:29:05.365 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:55.353 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:55.352 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:55.162 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:45.151 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:45.149 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:44.946 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:34.934 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:34.933 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:34.746 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:24.735 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:24.734 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:24.519 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:14.504 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:14.503 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:14.302 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:28:04.288 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:28:04.288 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:28:04.086 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:27:54.078 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:27:54.077 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:27:53.879 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:27:45.267 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:45.266 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) Artemas - i like the way you kiss me @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:44.115 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 776ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:44.091 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:44.090 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) Dua Lipa - Training Season @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:43.868 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Last activity was at 2024-06-11T10:27:00+02:00 | Next check interval: 10.00s
[2024-06-11 10:27:43.867 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] No new tracks discovered
[2024-06-11 10:27:43.684 +0200] DEBUG  : [App] [Sources] [Ytmusic - MyYTMusic] Refreshing recently played
[2024-06-11 10:27:42.889 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 700ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:42.858 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:42.857 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) Elley Duhé - MIDDLE OF THE NIGHT @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:41.588 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 840ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:41.569 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:41.568 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) (G)I-DLE - Fate (나는 아픈 건 딱 질색이니까) @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:40.428 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 737ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:40.401 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:40.400 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) CHUNG HA - I’m Ready (I’m Ready) @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:39.164 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 579ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:39.134 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:39.133 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) KISS OF LIFE - Midas Touch (Midas Touch) @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:37.743 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 839ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:37.724 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:37.724 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) Aden Foyer - The Ballet Girl @ 2024-06-11T10:27:00+02:00 (S)
[2024-06-11 10:27:36.581 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Waiting 840ms to scrobble so time passed since previous scrobble is at least 1000ms
[2024-06-11 10:27:36.567 +0200] DEBUG  : [App] [Scrobblers] [Lastfm - myLastFm] Raw Payload: 
[2024-06-11 10:27:36.566 +0200] INFO   : [App] [Scrobblers] [Lastfm - myLastFm] Scrobbled (New)     => (YTMusic) Ed Sheeran - Shivers @ 2024-06-11T10:27:00+02:00 (S)

Versions (please complete the following information):
Provide version information for any related sources/clients.

  • multi-scrobbler: [e.g. 0.7.1 node, locally]
  • YouTube Music
  • Last.FM

Additional context
Running latest release (cloned master of this repo)

@SomeAspy
Copy link

SomeAspy commented Jun 11, 2024

I had this issue too, but it was difficult for me to reliably replicate, seemingly happening at random, so without any reliable data I didn't bother opening an issue. I've just been watching the entire repo.

@roos-robert
Copy link
Author

roos-robert commented Jun 11, 2024

I had this issue too, but it was difficult for me to reliably replicate, seemingly happening at random, so without any reliable data I didn't bother opening an issue. I've just been watching the entire repo.

Haha you know what? You're the reason I found this repo! Googled for a YouTube Music scrobbler and found your blog. 😁

Hopefully the dev have some insight to what might be going on.

So I'm guessing then (reading your blog) that the dev branch didn't solve this issue either?

@SomeAspy
Copy link

At the time of writing the dev branch didn't make a difference.
I think the only difference here is I used the docker images (I tried stable, develop, and develop-debian)
but yeah, I had the exact same issue. Since I've been watching the commit history, I haven't noticed anything that might be related to this.

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 12, 2024

Thanks for the writeup.

There haven't been any changes to the YT Music code in MS because I don't personally use YT Music so if something breaks I depend on any users who use it to report an issue.

I can't currently reproduce your issue but I'm fairly confident it's due to how YTM "organizes" your listens in its recent history -- it does not surface any actual "listened at" datetime info. Instead:

  • it buckets plays into "playlists" of relative time, then large buckets for month/year
  • MS assumes that the order of the plays within a bucket are in reverse chronological order (most recent played first) -- this is anecdotally what I saw when developing/testing YTM but there is no guarantee

EX:

  • Today (4 tracks)
  • Yesterday (2 tracks)
  • Last Week (20 tracks)
  • May 2024 (150 tracks)

You can see more in the PR I made to try to compensate for this in the underying YTM library MS uses.

MS tries to be clever about how it determines if YTM has returned a new track. When it first starts up (polling) it stores all tracks returned from YTM history in a flat list. Then it polls that history API regularly and if it finds a track at the beginning of the list (assumed most recent) that does not match the last-seen first track it determines that is a new track and scrobbles it.

Likely what is happening with the duplicate scrobbles is that YTM is either not returning tracks in reverse chronological order or it is not returning the playlists in reverse chronological order. Or maybe something else entirely...its pretty opaque.

MS also can't do duplicate checking, which it does for all other music sources, because there are no datetimes so it just has to assume the list is in the correct order. 🤷


Having said all that, I've added some code to help surface information about those playlists to a feature branch in MS. Please use the ytMusicDebug branch if running locally or foxxmd/multi-scrobbler:ytdebug docker image.

You'll find on the dashboard the YTM card has a new link, See Recent from Source API. Navigating to this link will open a page that lists the tracks returned from YTM without modification. This is the exact order YTM returns them to MS. You'll also see the "playlist bucket" YTM puts these tracks in at the end of each track.

image

If everything is working normally this list should be essentially the same order as Tracks Discovered page for your YTM source.

If you see duplicate scrobbles occurring please:

  • include the list from Recent
  • include the list from Discovered
  • include any relevant logs

This will help me isolate if its a list order issue or if I need to dig further into this. thanks

@FoxxMD FoxxMD added the bug Something isn't working label Jun 12, 2024
@roos-robert
Copy link
Author

@FoxxMD thank you for the explanation and insights into why scrobbling from YouTube Music is such a pain, to be honest if it wasn't for multi-scrobbler I would stick with Spotify. Your work is much appreciated!

To give a brief update since it's been almost a day since your reply, these are the steps I've taken to test this out:

  • Running the ytMusicDebug branch locally (using pm2 on a Ubuntu server)
  • Running YouTube Music for about 2 hours from my iPhone app
  • Running YouTube Music for about 6 hours from web browser on PC/Mac

So far everything has been scrobbling perfectly correct! The only change from when I ran the release version of 0.7.1 is:

  • Not using separate [service/client].json files, instead running the all-in-one config.json

I'll leave this issue open and get back to you once I've tested things out some more, hopefully @SomeAspy have time to try it out as well.

Thanks again for all your work!

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 14, 2024

Off topic but I read your blog post @SomeAspy (thanks for the kind words!) and wanted to let you know you do not need CF Access.

The next problem I ran into is the fact that (in my case) this is a publicly accessible URL. I couldn't just close it, because Last.FM needs to callback URL to authenticate with Multi Scrobbler.

Last.fm uses a slightly modified authorization code flow but the relevant part is that its redirect behavior is the same as the normal oauth2.0 spec -- the redirect URI is is where the authorization service redirects the users browser after its side of the authorization flow is complete. This means the URI used only needs to be accessible from the users browser, not that is needs to be publicly accessible:

  • You setup a redirect URI for your application like http://localhost:9078/lastfm/callback
  • Click authenticate in MS -> MS generates auth URL like http://www.last.fm/api/auth/?api_key=1234 and tells your browser to redirect there
  • You see your created LFM application on last.fm and click allow access to your account
  • last.fm servers authorize access and return the redirect uri to your browser but now it includes auth code like http://localhost:9078/lastfm/callback?token=67890
    • Your browser is told to redirect to that new URL, it navigates to MS (which is only accessible on your machine through localhost!)
  • MS parses token out of the URL and does a final exchange, server-to-server, where it sends the token to LFM and receives a sessionKey it can use to make api requests

LFM's servers never initiate a connection with your MS instance so your instance does not need to be public in order to complete the auth flow. This is usually true for any oauth2.0 compliant authorization flow and auth code flows in general.

@SomeAspy
Copy link

I love to see people reading it! I was surprised to see the author found this from my silly blog. I have updated the post to add what you just said.
I will be giving your YTM branch a try soon, right now I don't listen to a lot of music from mobile.

I also can't help but comment on your swiftness of responding to any and all issues on this repository, so kudos!

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 24, 2024

@roos-robert @SomeAspy have either of ya'll had a chance to test this? Any results?

@SomeAspy
Copy link

I'm actually gonna begin tomorrow, the circumstances where I scrobble a lot from mobile have started today.

@SomeAspy
Copy link

Something I've almost immediately noticed within the first few hours of using is my YouTube music cookie seems to get invalidated more than it previously was.
I originally set this up last night, and pulled a cookie using the post request before going to sleep.
Later, today in the afternoon, the cookie has been invalidated. I chock it up to whatever, and pull it again.
I listen to music for about an hour, and things work fine. I take a nap for 2 hours and come back to find my cookie invalidated again. @roos-robert have you been having similar issues?
image

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 25, 2024

@SomeAspy can you try enabling the option mentioned here? This should be included in the latest commits on the ytdebug docker image.

@SomeAspy
Copy link

Ah yes I missed that. I haven't actually tested this exactly yet but it seems to drop on restart. I can test it when I get home.

@SomeAspy
Copy link

Another smaller detail I've noticed: if you play a song several times over only one play will be detected. I assume this is because of the way you make sure not to scrobble multiple times and am not sure if this is avoidable.

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 25, 2024

As long as there is a different track played between the two it should be detecting them just fine (assuming MS was running and monitoring the entire time). I'll try to use YTM today and see if I can get api dumps to use for testing.

@SomeAspy
Copy link

SomeAspy commented Jun 25, 2024

There was no track between, and I just noticed that the YouTube history itself only shows once.
I've been using https://github.com/th-ch/youtube-music (the difference being it's a client and can actively watch what you are doing to scrobble so) on desktop and it will scrobble plays if you play it over several times. I guess not much can be done about this if YouTube music itself doesn't list it as played multiple times. image

In this case it was house of cards for about 7 replays.

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 25, 2024

Yeah, unfortunately MS can't do any thing about that since YTM doesn't report any kind of player status or listening statistics. All it reports is the history, in order (hopefully), without any timestamps. It's the least data-rich platform MS supports.

@SomeAspy
Copy link

SomeAspy commented Jun 25, 2024

Yet again I feel like I shot myself in the foot using YouTube Music. Since this is the best we can get regarding mobile scrobbling on iOS, I've been trying to think of the best way to keep using my desktop scrobbler without interfering with multi-scrobbler, which will be running in the background.

In short, I want to use MS for mobile, and the desktop client for desktop. I have a feeling these will naturally interfere with each other. I haven't really tried it yet though.

In better news, scrobbling via mobile seems to be going great, to the best it can given the limitations of YTM. I will list the problems I have with it just for record, but I cannot think of a way to actually fix these.

  • Skipped songs seem to still scrobble (YTM shows in history, so not much to be done)
  • Back to back replays only scrobble once (Once again, YTM history limitation)

Cross examining YTM history with last.fm scrobbles seems to be more reliable (???) but there are still some oddities and duplications.

image

Duplicates are often scrobbled in bunches, for what it is worth, with exact same times (which would not be possible since each song is at least 3 minutes)
image

Strangely, these duplications and order errors don't seem to appear in the MS debug
image

@FoxxMD
Copy link
Owner

FoxxMD commented Jun 25, 2024

Thank you for the detailed writeup and track matching, this is very helpful!

Skipped songs seem to still scrobble (YTM shows in history, so not much to be done)

Yes, unfortunately YTM records a song to the history playlist if it even loads in the player. It has no threshold for "this has been played for X seconds" before adding it.

Duplicates are often scrobbled...with the exact same times (which would not be possible since each song is at least 3 minutes)

This is a limitation of how MS tries to detect plays in "real-time" in the way I described in the earlier comment. It should be polling fast enough that when the history updates there is only one new track -- IE polling every 60 seconds, tracks are played for longer than 60 seconds so only one shows up between each poll -- BUT the code does not enforce this assumption: if multiple tracks show up between two polls it'll scrobble all the newly seen tracks with the same timestamp. It's erring on the side of caution in the event polling temporarily fails or YTM doesn't update history for an extended period.

Strangely, these duplications and order errors don't seem to appear in the MS debug

This is good to see, I think. It at least tells us that the data scraped by yt-music-api library is the same as what you actually see in YTM, at least in a spontaneous context.


During this window do you know if MS restarted polling or had any errors? Even temporary ones like it failed to contact api but restarted successfully before polling was stopped -- or had a reauthentication event for YTM? Any logs at all might be insightful.

Based on what you've presented so far though it seems like either

  • MS is restarting polling when it shouldn't and is incorrectly using a "stale" history list
  • YTM history order is not temporally consistent IE it adds tracks in the middle of existing history or switches the order of tracks "later"

I'll see about improving the history checking code and storing previous state so i can detect if/when this consistency occurs so it can drop the "stale" list or try to recover somehow.

@SomeAspy
Copy link

I should have included logs, you are right.
It looks like the web UI logs have rolled over, so I have attached the log file.
Skimming over it, I don't see anything erroneous.
scrobble-2024-06-25.1.log
image

FoxxMD added a commit that referenced this issue Jun 25, 2024
* Use superdiff to diff PlayObject lists and detect changes as well as append/prepend scenarios
* Replace YTM recently played logic with list diffing, only accept prepend-validated lists
  * On non-prepend scenarios replace existing recently played and log human readable diff
@FoxxMD
Copy link
Owner

FoxxMD commented Jun 25, 2024

@SomeAspy @roos-robert I've pushed changes to the ytdebug image and associated branch that overhauls how MS checks YTM history. It now validates the sort order against the previous list and only scrobbles new plays if they are only new (aka prepended to returned history) and there are no other changes to the list. In the event of a non-prepend scenario it'll now log to WARN with a list of changes and replace the in-memory list its validating against.

Please try these changes and let me know if you get any logs about non-prepend events.

FoxxMD added a commit that referenced this issue Jun 26, 2024
* Use superdiff to diff PlayObject lists and detect changes as well as append/prepend scenarios
* Replace YTM recently played logic with list diffing, only accept prepend-validated lists
  * On non-prepend scenarios replace existing recently played and log human readable diff
@SomeAspy
Copy link

I should link this in here as well. #158 (comment) Perhaps it might make more sense to merge these issues into one issue, as the difference between the 2 problems is starting to blur.

FoxxMD added a commit that referenced this issue Jun 26, 2024
…lays #156

Rather than generating our own just use the known "good" history we just compared against to see if this improves consistency.
@FoxxMD
Copy link
Owner

FoxxMD commented Jun 26, 2024

Both issues are related to YTM but I don't think they are casual in nature, at least not yet. I'd prefer to keep them separate for now.

RE your comment in 158:

That's pretty eye-popping! There may be an issue with MS still but there are definitely inconsistencies in there that can't be accounted for by the way MS handles the history. I've added a few more changes. Please try testing with foxxmd/multi-scrobbler:pr-163.

@SomeAspy
Copy link

Alright, I just started it up (with the debug env variable) and your new PR. I guess I'll let you know how it goes sometime soon (most likely tomorrow)

@SomeAspy
Copy link

hey @roos-robert a bit off topic, but I thought I'd mention I commissioned a Youtube Music app tweak for iOS, It seems to work great! https://github.com/marioparaschiv/lastfm-yt-music

FoxxMD added a commit that referenced this issue Aug 21, 2024
…lays #156

Rather than generating our own just use the known "good" history we just compared against to see if this improves consistency.
@nalsai
Copy link

nalsai commented Aug 27, 2024

The change to validate the sort order against the previous list and only scrobble new plays if they are prepended to returned history works well in not creating any wrong scrobbles, however it causes songs that should be scrobbled to not be scrobbled quite often for me.

For example: I ran into an issue when I played a song briefly but then skipped it. MS scrobbled the song but when I skipped it, YouTube removed it from the history (replacing it with the next song I played) causing MS to reset its history and not scrobble the song I played directly after. (The skipped song was scrobbled but the one I actually listened to wasn't)

Another reset I don't quite understand why it happened was this:
It seems like the song at position 2 was replaced?? and a new song was added.

Changes from last seen list:
1. SOUND HOLIC / Nana Takahashi - DESTRUCTION A to Z ) (feat. Nana Takahashi/DJ Command) @ N/A => Added
2. A-One - ゼンマイ恋時計(T.E.B Summer Mix) - Zenmai Koi Dokei(T.E.B Summer Mix) @ N/A => Moved -  Originally at 1
3. Shinra-Bansho - 幸福を享受せよ - Embrace Happiness @ N/A => Added
4. Mamemi - Space Cowgirl @ N/A => Moved -  Originally at 3
...

Another issue I ran into is that it won't scrobble songs I have already played somewhat recently. (not sure if it's related)

@FoxxMD
Copy link
Owner

FoxxMD commented Aug 27, 2024

Thanks for reporting your issue.

In order for MS to accurately determine if a song has been scrobbled it needs a source of truth. Whether that is information about the current state of the player (subsonic, spotify) like playing/"position within the track" or an actual list of played songs (lastfm, listenbrainz) the information MS receives needs to be consistent and predictable.

Unfortunately there is no documentation for how YTM history behavior works and the observed behavior for information for that "source of truth" (list of played tracks) is problematic:

  • no consistency to what it keeps or not keeps (when you skip a song, does it show up in history or not? Is there a timeout period?)
  • it seemingly replaces tracks with others based on skip, seek behavior, sometimes...
  • the order of the tracks within history is not consistent with no clear trigger for re-ordering

The lack of consistency is what was causing the duplicate scrobbles for this issue in the first place. In order to partially compensate for this MS is now extremely "strict" about watching the order of tracks in YTM's history. Changes to the list that are valid for recording a scrobble should only fall under these two conditions:

  • it expects that unseen tracks should only appear (be added) at the beginning of the list AND
  • that tracks it has already seen should not change order or disappear from the list.

If either of those two conditions is violated it "resets" its source of truth to the "new" list and waits for changes that match the above conditions.


The issues you are running in to, MS not scrobbling, are due to it resetting the source of truth after those conditions are violated. You can see that from the Changes from last seen list: logging it is outputting for visibility. This is, unfortunately, the trade-off that has to be made in order to get some kind of stability from YTM as a Source. I wish it could be better but MS can only be as good as the information it is receiving and YTM is honestly garbage for this.

If you want better scrobbling your best bet would be to use a scrobbling app (on your phone, web browser, computer) that scrobble to last.fm and then relay that with MS to LZ or Maloja or w/e.

@FoxxMD
Copy link
Owner

FoxxMD commented Aug 28, 2024

All of the changes to prevent duplicate scrobbles and the logging these things are now included in v0.8.3 along with FAQ entries and doc mentions about the above issues with missing scrobbles. The original issue is "resolved" and there's not much more that can be done about the inconsistent upstream data from YTM so I'm closing this for now.

If google decides to release an official API for YTM in the future or another way of access this data is discovered I'll be happy to revisit this.

@FoxxMD FoxxMD closed this as completed Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants