Quodlibet: How to add a pause between tracks?

Created on 10 Oct 2019  路  6Comments  路  Source: quodlibet/quodlibet

I鈥檓 looking for a way to add (5-30s) pauses between two tracks in a playlist. The actual use case is to play music at a dance event. Usually people need some time to change partners, so having one track immediately followed by the next one is a no go.

If there is currently no way to achieve this:

  • What kind of plugin would this be?

All 6 comments

There isn't any I think. A hacky way would be to use silence songs in between. Use "Audacity": Main Menu > Generate > Silence > Set Duration, Main Menu > File > Export as MP3.

Although it's worth looking at the Random Album plugin, this does a very similar thing (configurable)...

Although it's worth looking at the Random Album plugin, this does a very similar thing (configurable)...

Maybe we could move that logic into its own plugin? And add support for pausing between songs too.

@torotil

Here's another hacky solution via a plugin that freezes the whole player after a song was played:

try:
    from quodlibet import _, config
except ImportError:
    def _(i):
        return i

from quodlibet.qltk import Icons
from quodlibet.plugins.events import EventPlugin
import time


SLEEP_SECONDS = 10

class SleepAfterSongEndedPlugin(EventPlugin):
    PLUGIN_ID = "SleepAfterSongEndedPlugin"
    PLUGIN_NAME = _("Sleep After Song")
    PLUGIN_DESC = _("Freeze the player after song ended.")
    PLUGIN_ICON = Icons.MEDIA_PLAYBACK_PAUSE

    def plugin_on_song_ended(self, song, skipped):
        if not skipped:
            time.sleep(SLEEP_SECONDS)

It seemed to work fine in my short test, but might break something else.

@CreamyCookie

That didn't work for me (on Linux), the app UI became unresponsive but the next song continued playing. Pausing it does work for me though:

from quodlibet import _
from quodlibet import app
from quodlibet.plugins.events import EventPlugin
from quodlibet.qltk import Icons
import threading
import time

SLEEP_SECONDS = 2

class SleepAfterSongEndedPlugin(EventPlugin):
    PLUGIN_ID = "PauseBetweenSongs"
    PLUGIN_NAME = _("Pause Between Songs")
    PLUGIN_DESC = _("Pauses for a few seconds after a song ends.")
    PLUGIN_ICON = Icons.MEDIA_PLAYBACK_PAUSE

    def plugin_on_song_ended(self, song, skipped):
        if not skipped:
            thread = threading.Thread(target=self.pause_for_x_seconds, args=())
            thread.daemon = True
            thread.start()

    def pause_for_x_seconds(self):
        app.player.paused = True
        time.sleep(SLEEP_SECONDS)
        app.player.paused = False

Edit: I tried adding a preferences section to let the user enter a custom value but couldn't figure out how to get anything to show up. I tried copying the track_repeat plugin's preference setup but no dice...

@chickendude

That's definitely a far better solution!

I tried adding a preferences section to let the user enter a custom value but couldn't figure out how to get anything to show up

I just tried the same, and maybe you made the same mistake I just did: forgetting to extend from PluginConfigMixin. Now it works:

from gi.repository import Gtk

from quodlibet import _
from quodlibet import app
from quodlibet.plugins import PluginConfigMixin
from quodlibet.plugins.events import EventPlugin
from quodlibet.qltk import Icons

import threading
import time


class SleepAfterSongEndedPlugin(EventPlugin, PluginConfigMixin):
    PLUGIN_ID = "PauseBetweenSongs"
    PLUGIN_NAME = _("Pause Between Songs")
    PLUGIN_DESC = _("Pauses for a few seconds after a song ends.")
    PLUGIN_ICON = Icons.MEDIA_PLAYBACK_PAUSE

    DEFAULT_PAUSE = 2
    CONFIG_KEY_FOR_PAUSE = "pause_in_seconds"

    @classmethod
    def PluginPreferences(cls, parent):
        def pause_changed(spin):
            cls.config_set(cls.CONFIG_KEY_FOR_PAUSE, int(spin.get_value()))

        vb = Gtk.VBox(spacing=10)
        vb.set_border_width(10)
        hbox = Gtk.HBox(spacing=6)
        lbl = Gtk.Label(label=_("Pause in seconds:"))
        hbox.pack_start(lbl, False, True, 0)
        val = cls.config_get(cls.CONFIG_KEY_FOR_PAUSE, cls.DEFAULT_PAUSE)
        spin = Gtk.SpinButton(
            adjustment=Gtk.Adjustment.new(float(val), 2, 20, 1, 10, 0))
        spin.connect("value-changed", pause_changed)
        hbox.pack_start(spin, False, True, 0)
        vb.pack_start(hbox, True, True, 0)
        vb.show_all()
        return vb

    def plugin_on_song_ended(self, song, skipped):
        key = self.CONFIG_KEY_FOR_PAUSE
        pause_in_seconds = int(self.config_get(key, self.DEFAULT_PAUSE))

        if not skipped:
            thread = threading.Thread(target=self.pause_for_x_seconds, 
                                      args=(pause_in_seconds,))
            thread.daemon = True
            thread.start()

    def pause_for_x_seconds(self, pause_in_seconds):
        app.player.paused = True
        time.sleep(pause_in_seconds)
        app.player.paused = False

If you want, you can create a pull request to add this as a plugin. It seems general purpose enough. If you do, please name it Closes #3268: Added a plugin to pause between tracks or similar, so that this issue will be closed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lazka picture lazka  路  6Comments

lazka picture lazka  路  6Comments

lazka picture lazka  路  6Comments

jeronimojoe picture jeronimojoe  路  5Comments

smammy picture smammy  路  3Comments