navidrome / navidrome

🎧☁️ Modern Music Server and Streamer compatible with Subsonic/Airsonic
https://www.navidrome.org
GNU General Public License v3.0
11.24k stars 839 forks source link

[Bug]: Streamed songs do not trigger the album to be listed in "Recently played" #2347

Closed GioF71 closed 1 year ago

GioF71 commented 1 year ago

I confirm that:

Version

0.49.3

Current Behavior

The files are streamed correctly, see the logs:

time="2023-05-10T09:25:23Z" level=info msg="Streaming file" artist=Jestofunk bitRate=866 cached=false format=raw originalBitRate=866 originalFormat=flac requestId=navidrome-app/wjbQk0H3M6-000892 title="The Ghetto (featuring CeCe Rogers and Fred Wesley)" transcoding=false user=giovanni username=giovanni time="2023-05-10T09:32:10Z" level=info msg="Streaming file" artist="Freedom Or Not" bitRate=993 cached=false format=raw originalBitRate=993 originalFormat=flac requestId=navidrome-app/wjbQk0H3M6-000913 title="Feel It (Jazzy Mix)" transcoding=false user=giovanni username=giovanni

Expected Behavior

The album which contains the streamed songs should appear in the "Recently played" view.

Steps To Reproduce

There are many ways, but I am using the subsonic plugin for upmpdcli, see the discussion so the steps reduce to these:

1 - Just stream some tracks 2 - Check the gui on the "Recently Played" page to see if the album is presented

Environment

- OS: Linux/Docker
- Browser: Chromium
- Client: Upmpdcli with SubSonic Plugin

How Navidrome is installed?

Docker

Configuration

---
version: "3"

networks:
  traefik:
    external: true
  openssh-server:
    external: true

services:
  navidrome-app:
    image: deluan/navidrome:latest
    container_name: navidrome-app
    hostname: navidrome-app
    networks:
      - traefik
      - openssh-server
    environment:
      #- ND_ENABLETRANSCODINGCONFIG="true"
      #- ND_SCANSCHEDULE=12h
      #- ND_LOGLEVEL=info  
      #- ND_BASEURL=""
      - ND_SCANNER_EXTRACTOR=ffmpeg
      - ND_SCANSCHEDULE=0
      #- ND_ENABLETRANSCODINGCONFIG=true
      - ND_SPOTIFY_ID=${ND_SPOTIFY_ID}
      - ND_SPOTIFY_SECRET=${ND_SPOTIFY_SECRET}
      - ND_LASTFM_APIKEY=${ND_LASTFM_APIKEY}
      - ND_LASTFM_SECRET=${ND_LASTFM_SECRET}
      - ND_LOGLEVEL=debug
    volumes:
      - ./data:/data
      - /mnt/local/s8tb02/music/exported:/music:ro
    ports:
      - 4533:4533
    labels:
      - com.centurylinklabs.watchtower.enable=false
    restart: unless-stopped

Relevant log output

navidrome-app    | time="2023-05-10T09:39:37Z" level=info msg="Finished initializing cache" cache=Image elapsedTime=8.81s maxSize=100MB
navidrome-app    | time="2023-05-10T09:39:46Z" level=debug msg="API: New request /rest/stream" client=upmpdcli requestId=navidrome-app/oVRzZRr9qt-000021 username=giovanni version=1.16.1
navidrome-app    | time="2023-05-10T09:39:46Z" level=debug msg="Found matching player" client=upmpdcli id=62941726-dc83-4916-8df7-53c024604448 requestId=navidrome-app/oVRzZRr9qt-000021 type="Music Player Daemon 0.23.12" username=giovanni
navidrome-app    | time="2023-05-10T09:39:46Z" level=debug msg="Streaming RAW file" id=c10b1fc2af908fcc81b50493a2f53301 originalBitrate=828 originalFormat=flac path="/music/Music03/2023.Library.Add/2023-04/2023-04-21/Qobuz Downloads/Various Artists - Café Noir Musique Pour Bistrots - Acid Jazz, Vol. 1 (2009) [16B-44.1kHz]/03. Nublado Mesclado.flac" requestBitrate=0 requestFormat=flac requestId=navidrome-app/oVRzZRr9qt-000021 selectedBitrate=828 selectedFormat=raw username=giovanni
navidrome-app    | time="2023-05-10T09:39:46Z" level=info msg="Streaming file" artist="Jerome van Rossum" bitRate=828 cached=false format=raw originalBitRate=828 originalFormat=flac requestId=navidrome-app/oVRzZRr9qt-000021 title="Nublado Mesclado" transcoding=false user=giovanni username=giovanni
navidrome-app    | time="2023-05-10T09:39:46Z" level=debug msg="API: New request /rest/getCoverArt" client=upmpdcli requestId=navidrome-app/oVRzZRr9qt-000022 username=giovanni version=1.16.1
navidrome-app    | time="2023-05-10T09:39:46Z" level=debug msg="HTTP: GET http://192.168.1.174:4533/rest/getCoverArt?id=c10ccaa400fb0a2369adb9e89ba3ae3d&u=giovanni&s=[REDACTED]&t=[REDACTED]&c=upmpdcli&v=1.16.1" elapsedTime=6.1ms httpStatus=200 remoteAddr="192.168.1.8:60074" requestId=navidrome-app/oVRzZRr9qt-000022 responseSize=84660 userAgent=Mozilla/5.0
navidrome-app    | time="2023-05-10T09:39:50Z" level=debug msg="HTTP: GET http://192.168.1.174:4533/rest/stream?id=c10b1fc2af908fcc81b50493a2f53301&format=flac&u=giovanni&s=[REDACTED]&t=[REDACTED]&c=upmpdcli&v=1.16.1" elapsedTime=4.11s httpStatus=200 remoteAddr="192.168.1.41:38280" requestId=navidrome-app/oVRzZRr9qt-000021 responseSize=50471705 userAgent="Music Player Daemon 0.23.12"

Anything else?

I have read this ticket and specifically this post. I don't know exactly if this makes my request impossibile to solve.

An alternative might be to receive back from mpd/upmpdcli something that tells the plugin that a song has played, but then what could I do? I could "scrobble" but this is a different thing and on my side, it is already handled at the mpd level with yams (yet another mpd scrobbler), I see no other api in subsonic that correspondes to "mark the album as played".

Thanks!

Code of Conduct

dweymouth commented 1 year ago

This isn't a Navidrome bug - it's a bug in the subsonic plugin for upmpdcli. The client is supposed to call the scrobble endpoint when it wants to register a play count increase.

Edit: I see you're the developer of that plugin :) You just need to call scrobble to let Navidrome know that a track has been played and it should update the play count info.

GioF71 commented 1 year ago

Hello, thank you for your answer. It seems to me that scrobbling is not the same as just playing. A track is 'played' regardless of the fact that the track is 'scrobbled' or not. OTOH, even assuming that scrobbling could be the solution, upmpdcli and this upmpdcli plugin is only the bridge to mpd, it does not get notified of the fact that a track has been played: the plugin just provides the urls (/rest/stream ...) to mpd. So the only moment when I could possibly call the scrobble API is when the tracks are listed, but that happens when one is browsing the library, and not specifically when one actually decides to enqueue some tracks and play them. Again, about scrobbling to last.fm, in my setup, this is done by yams which is connected to mpd.

Please correct me if I am wrong.

Thank you

Edit: if I am calling this a Bug while it might be possibly a feature request, or my mistake, I apologize in advance.

dweymouth commented 1 year ago

"Scrobbling" to the subsonic server isn't the same as scrobbling to last.fm, though many servers including Navidrome can be configured to do so. There's a good reason why an access to the play URL doesn't automatically trigger a play count increase though - clients can access the URL in order to cache music offline that hasn't yet been played by the user. Or the user can skip a song as soon as it begins playing, in which case it doesn't make sense to count it as played. Also if a client has a local copy already, and the user plays it twice, the client can increment the play count on the server appropriately.

GioF71 commented 1 year ago

Alright, understood what Scrobbling means here. But again, I can't know when a track plays, the plugin only shows the library in a number of different ways and serves URLs to mpd. I cannot consider a track that appears on a selection list as an 'access' to the play url. This would trigger an incorrect number of play increments that would not represent the reality. In order to be able to intercept when playback happens, the plugin should behave differently, more like a proxy I believe. What do you think?

dweymouth commented 1 year ago

Either that, or be able to poll or subscribe to status updates from mpd and track what's being played that way.

GioF71 commented 1 year ago

Yes, but there is another aspect that I wasn't considering when I wrote the previous comment. Upmpdcli, when working as a media server, can be used by any (well maybe almost any) upnp/dlna renderer. For example I can use a ChromeCast Audio, create a DLNA/OpenHome renderer with BubbleUpnpServer, and that ChromeCast would then be eligible as a player for Upmpdcli (and of course the subsonic plugin). I have done that an it works perfectly fine. So MPD is not necessarily involved: any solution that relies on checking mpd status updates would only cover mpd as the final player. Also, that solution should be deployed to all the mpd players and that would be quite inconvenient.

GioF71 commented 1 year ago

Another thing I don't understand.

If I stream a media file, Navidrome is serving the file instead of playing it directly from its GUI. But it could detect the "play" event. Can't the scrobble be triggered automatically?

Also, from the Subsonic API, for the "scrobble" verb the description is:

Registers the local playback of one or more media files. Typically used when playing media that is cached on the client. This operation includes the following:

- "Scrobbles" the media files on last.fm if the user has configured his/her last.fm credentials on the Subsonic server (Settings > Personal).

- Updates the play count and last played timestamp for the media files. (Since [1.11.0](http://www.subsonic.org/pages/api.jsp#versions))

- Makes the media files appear in the "Now playing" page in the web app, and appear in the list of songs returned by getNowPlaying (Since [1.11.0](http://www.subsonic.org/pages/api.jsp#versions))

So it seems to me that 'scrobble' should be used when a media has been downloaded (does not count as a play) then played locally in a different moment, like you mentioned a few comments before. In this case, it makes perfect sense that the client calls the scrobble api.

GioF71 commented 1 year ago

ah btw I see you are the developer of SuperSonic! :-)

dweymouth commented 1 year ago

There was a discussion around this in the OpenSubsonic org, and there was no clear consensus so far. Apparently original Subsonic and its direct forks recorded play count increases when stream was called. There are still some problems I see with this though, that Deluan agrees with, is that 1) the stream endpoint is also used if a client wants to cache or pre-download transcoded media, since the download endpoint doesn't allow transcoding; and 2) it's a good user experience that if you skip a song shortly after it starts playing that it should not count as a play. There's no way to detect this if an access to the stream endpoint automatically registers a play. Also, clients that play gaplessly have to call stream to start pre-downloading the next track before it begins, and if the user may switch to playing something else entirely before that track ever starts.

GioF71 commented 1 year ago

Ok, understood. Fair points. So I am building a simple mpd scrobbler for subsonic in python, it already works for me. It's so nice to see the tracks appear in the Navidrome gui, and, consequently, in the "Recently played" view of the media server. The only problem is that this scrobbler is something more that one needs to install with every instance of mpd. A minor inconvenience anyway.

GioF71 commented 1 year ago

Of course, thank you for the support and explanations!

GioF71 commented 1 year ago

Hello, I have built an initial version of the scrobbler for mpd. Here is the repository. Please share your thoughts if you have a moment to take a look at it. It solves the issue only when the final player is MPD. The best solution would be if the scrobble could be done within the subsonic plugin, for this I need to see if there is something we can do with the author of upmpdcli.

I believe we can close this, thanks @dweymouth for the great support.

github-actions[bot] commented 12 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.