quodlibet / quodlibet

Music player and music library manager for Linux, Windows, and macOS
https://quodlibet.readthedocs.io
GNU General Public License v2.0
1.43k stars 223 forks source link

Consecutive songs are silent when "Disable Gapless Playback" is off #4159

Open Derpitron opened 2 years ago

Derpitron commented 2 years ago

Steps to reproduce

  1. Have a local playlist with a collection of mp3 song files
  2. Have "Disable Gapless Playback" option be turned off
  3. Play one song in the playlist and wait for it to end
  4. When the next song plays, the progress bar appears, and the song starts for a very brief moment, but then cuts out completely.
  5. Changing or pressing the progress bar in anyway causes the audio to return.

Expected Output

Audio should play one after the other seamlessly without cutting out, when using Gapless Playback.

Actual Output

Subsequent song is silent when playing in a sequence.

Output when running

quodlibet-cmd.exe --debug

Debug Log

    D: 25.768: player.gstbe.player.__message: Recalculate latency
    D: 25.892: player.gstbe.player.__message: Recalculate latency
    D: 26.028: player.gstbe.player.__message: Recalculate latency
    D: 26.151: player.gstbe.player.__message: Recalculate latency
    D: 26.285: player.gstbe.player.__message: Recalculate latency
    D: 26.412: player.gstbe.player.__message: Recalculate latency
    D: 26.546: player.gstbe.player.__message: Recalculate latency
    D: 29.470: player.gstbe.player.__message: Recalculate latency
    D: 38.114: player.gstbe.player.__message: Recalculate latency
    D: 46.759: player.gstbe.player.__message: Recalculate latency
    D: 48.651: player.gstbe.player.__about_to_finish: About to finish (async)
    D: 48.653: player.gstbe.player.__about_to_finish_sync: About to finish (sync)
    D: 48.655: player.gstbe.player.__about_to_finish_sync: Select next song in mainloop..
    D: 48.659: PlaylistModel.next_ended: Using <In Order>.next_implicit() to get next song
    D: 48.662: player.gstbe.player.__about_to_finish_sync: ..done.
    D: 48.664: player.gstbe.player.__about_to_finish: About to finish (async): setting uri
    D: 48.666: player.gstbe.player.__about_to_finish: About to finish (async): done
    D: 49.697: player.gstbe.player.__message: Stream changed
    D: 49.698: GStreamerPlayer._end: End song
    D: 49.705: util.cover.manager.run: Found local cover from EmbeddedCover: <tempfile._TemporaryFileWrapper object at 0x000001c4d3b8c460>
    D: 49.710: player.gstbe.player.__message: Recalculate latency
    D: 49.859: SongFileLibrary._changed: Emitting changed for 2 item(s) (e.g. 'd:\\users\\priya\\music\\yuksek - 15. tonight (gameloft edit).mp3'...) from <SongFileLibrary @ 0x1c4d0431dc0>
    D: 49.871: qltk.completion.__update_song: Updated tag model for 2 songs
    D: 49.874: qltk.tracker.__changed: Current song changed, updating current file

Print Pipeline

|-GstPlayBin (playbin2)
\
 |-GstURIDecodeBin (uridecodebin5)
 \
  |-GstFileSrc (source)
  |-GstDecodeBin (decodebin5)
  \
   |-GstTypeFindElement (typefind)
   |-GstID3Demux (id3demux6)
   |-GstMpegAudioParse (mpegaudioparse6)
   | audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)1, layer=(int)3, rate=(int)44100, channels=(int)2, parsed=(boolean)true
   |-avdec_mp3 (avdec_mp3-6)
 | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
 |-GstInputSelector (inputselector6)
 | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
 |-GstPlaySink (playsink)
 \
  | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
  |-GstTee (audiotee)
  | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
  |-GstStreamSynchronizer (streamsynchronizer2)
  | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
  |-Bin (abin)
  \
   | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
   |-GstQueue (aqueue)
   | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
   |-GstPlaySinkAudioConvert (aconv)
   \
    |-GstIdentity (identity)
    | audio/x-raw, format=(string)S16LE, layout=(string)non-interleaved, rate=(int)44100, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
    |-GstAudioConvert (conv)
    | audio/x-raw, rate=(int)44100, format=(string)F32LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstAudioResample (resample)
   | audio/x-raw, rate=(int)44100, format=(string)F32LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
   |-Bin (bin4)
   \
    | audio/x-raw, rate=(int)44100, format=(string)F32LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstPitch (pitch)
    | audio/x-raw, rate=(int)44100, format=(string)F32LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstAudioConvert (audioconvert2)
    | audio/x-raw, rate=(int)44100, format=(string)S16LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstAudioResample (audioresample2)
    | audio/x-raw, rate=(int)44100, format=(string)S16LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstVolume (volume2)
    | audio/x-raw, rate=(int)44100, format=(string)S16LE, channels=(int)2, layout=(string)interleaved, channel-mask=(bitmask)0x0000000000000003
    |-GstDirectSoundSink (player)

Test System

Which version of Quod Libet?

4.5.0, at commit 7e82d050c765a1d6f3ee84009461aa07acd64b58

Which operating system

Windows 10 21H2

If it's audio-related, what back-end?

Unsure how to check the back-end

afontenot commented 2 years ago

Do you see this problem when playing songs from the songlist (e.g. in the paned browser), or only when using a playlist? Do you have any files other than mp3 (flac, m4a, ogg, wav, etc) that you could test this with?

Derpitron commented 2 years ago

Do you see this problem when playing songs from the songlist (e.g. in the paned browser), or only when using a playlist?

This problem is observed all of the views which have the Track List panel.

Do you have any files other than mp3 (flac, m4a, ogg, wav, etc) that you could test this with?

I don't have any files other than mp3 to test with.

afontenot commented 2 years ago

I couldn't reproduce this with a fresh download of 4.5.0 portable.

Windows 10 Enterprise LTSC Version: 1809 Build 17763.3469

Stuff you could try, if no one else has any suggestions:

Derpitron commented 2 years ago
  1. "Disable gapless playback" has fixed the issue.
  2. Where is the section "Print Pipeline"? image
afontenot commented 2 years ago

2. Where is the section "Print Pipeline"?

I believe you have to have started it with the "--debug" option I mentioned for that to appear.

afontenot commented 2 years ago

I see you've updated the original post with the logs. Those Recalculate latency lines look suspicious to me. Your buffer duration (in screenshot) looks low, I wonder if putting it on 2 or 3 seconds would improve things? The small buffer might be breaking GStreamer in gapless playback mode.

Viktini commented 1 year ago

If it's a recalculate latency issue, this might be an upstream bug with Gstreamer. I've been having issues where I can't seek FLAC files without it causing a delay lasting seconds before it kicks back in. I've tried uninstalling gst-libav, switching between PipeWire and PulseAudio, disabling gapless, increasing the output buffer, still nothing.

I also tried Gmusicbrowser, which also uses Gstreamer as a backend, and still the same problem. This also occurs in Dolphin's (KDE) preview pane when Gstreamer is used as Phonon's backend. I'm running Arch Linux, with gstreamer 1.20.3-2

EDIT: Fixed by downgrading Gstreamer and its libraries to 1.20.2. I've reported my issue to upstream and referenced this one just in case.

afontenot commented 1 year ago

@Viktini nice find. I think this is probably a different issue because the version in use is 4.5.0, on Windows. At the time of the release, the latest msys2 package for gstreamer was 1.20.1, so they are most likely using that.

afontenot commented 1 year ago

@hydino2085143 incidentally, the mp3 format doesn't natively support gapless playback, it's basically hacked in and only works if you have a supported encoder / decoder combination. So if the suggestions I made above don't help, there's some chance the problem could be specific to your mp3 files. Maybe you could provide samples or at least say where they're from / how they're encoded? I don't have any I can test except stuff in my own collection, which is encoded with the latest version of LAME.

Edit: to confirm that mp3 is at fault here, you could also download this public domain album in FLAC.