1

I created a bash script for Audacious that pauses playback in X minutes (and that gradually reduces volume over the last 10 minutes). This script met my needs well while using Audacious. However, now I am switching to DeaDBeeF.

I have two options: modify my existing script to work with DeaDBeeF, or create a generic approach that will work with almost any Linux or KDE audio player. I am seeking help with either approach.

However, I have not been able to locate documentation for DeaDBeeF that allows me to proceed in the way I was able to with Audacious. If I could find the documentation (and if DeaDBeeF offers equivalent commands) I could easily modify my existing script. Alternatively, and possibly with more help, I could implement a generic script.

I am not a developer, so my preferred implementation is a simple bash script (although I am open to other equally simple implementation options).

As mentioned, I am seeking help to modify my bash script to either work with DeaDBeeF or to work in a generic manner. Here's my script:

#!/bin/bash

function_pid=0

function musicsleep(){
    countdown=$(($1*60-1))
    datestop=$((`date +%s` + $countdown));
    echo "pausing music in $1 minutes..."

    #begin reducing sound volume 10 minutes (600 sec) from end
    voldown=$(($datestop - 600))

    while [ "$datestop" -ge `date +%s` ]; do
        datestr=$(printf "%s" $(date -u --date @$(($datestop + 1 - `date +%s`)) +%H:%M:%S))
        echo -ne "$datestr\r";
        kdialog --passivepopup "music will pause in: $datestr" 14
        if [ `date +%s` -ge "$voldown" ]; then
            currvol=$(audtool get-volume)
            #reduce volume in 40 steps of 2 = 80% reduction (starting at 100) over 10 min
            newvol=$(($currvol - 2))
            audtool set-volume $newvol
            echo -ne "\t\tvolume = $newvol\r"
            kdialog --passivepopup "volume = $newvol" 14
        fi
        sleep 15
    done
    audtool playback-pause
    echo "music paused at $(date)"
    audtool set-volume 100
}

while true; do

    choice=$(kdialog --combobox "Music Sleep Time:" "cancel" "stop" "5" "10" "15" "20" "25" "30" "35" "45" "45" "50" "60" "90" "120" "180" "360" "480" --default "25");
    retval="$?"
    if [ "$retval" -eq 0 ]; then
            if [ $function_pid -ne 0 ]; then
                kill $function_pid
                function_pid=0
                echo "countdown process terminated..."
            fi

            if [ "$choice" == cancel ]; then
                echo "countdown canceled by user at $(date)"
                kdialog --passivepopup "countdown canceled" 10
            elif [ "$choice" == stop ]; then
                audtool playback-stop
                echo "music playback stopped at $(date)"
                kdialog --passivepopup "music playback stopped" 10
            else
                echo "countdown (re)set by user at $(date)"
                kdialog --passivepopup "countdown started" 5
                audresult=$(audtool playlist-shuffle-status)
                if [ "$audresult" == "on" ]; then audtool playlist-shuffle-toggle; fi
                audtool playback-playing
                isplaying=$?
                audtool playback-paused
                ispaused=$?
                audtool playback-stopped
                isstopped=$?
                echo "isplaying=$isplaying, ispaused=$ispaused, isstopped=$isstopped"
                if [[ "$isstopped" -eq 0 || "$ispaused" -eq 0 ]]; then audtool playback-play; echo "playback started"; fi
                musicsleep "$choice" &
                function_pid=$!
                echo "function_pid=$function_pid"
            fi
            audtool set-volume 100

    elif [ "$retval" -eq 1 ]; then
            echo "exiting musicsleep"
            #audtool set-volume 100
            break
    else
            kdialog --error "ERROR";
    fi;

done

The essential features implemented in this script are:

  • Pick a sleep countdown timer value from a GUI
  • Disable random (shuffle) playback when countdown timer starts
  • Pause audio playback in X minutes
  • Show time remaining in GUI (or via desktop notifications)
  • Show current volume level in GUI
  • Gradually reduce volume over the last 10 minutes
  • After playback is paused, reset volume level to the initial value
  • Allow countdown timer to be reset to a new value without disrupting playback
  • Allow countdown timer to be canceled without disrupting playback
  • Stop playback manually from the countdown timer GUI

Some questions are:

Does DeaDBeeF have equivalent commands?

If yes, where is the documentation for the equivalent DeaDBeeF commands?

For anyone who is already familiar with DeaDBeeF, can I expect to simply substitute the DeaDBeeF commands for my existing Audacious commands in my script? Or are the differences great enough to require a complete rewrite of the script?

If a generic countdown timer with the above functionality will be relatively simply to implement, does anyone want to guide me? I think the volume part will be easy to implement with:

pactl set-sink-volume "$MY_SINK" "$VOLUME_CHANGE"  

source

When it comes tso pausing playback, as far as I can tell, the following commands are not a good match for the requirements of my script:

pactl suspend-sink "$MY_SINK"
pactl suspend-sink "$MY_SINK" FALSE

The above approach doesn't just pause the playing audio, it disables all sound from all apps and it seems to have other potential side effects.

From what I have seen here, controlling playback and pause generically (across any audio player) with pactl looks difficult. Surely there must be a simpler way. I'm OK if it is KDE specific.

  • I'd assume audio players to be sufficiently different that I don't think there's a generic way to send all of them a "pause" signal. You may have to do this on a case-by-case basis. I'm not familiar with deadbeef, so I can't give advice regarding that audio player. Suspending audio sinks may or may not work with audioplayers; in general, I'd expect funny things to happen (like an audio player not able to resume, etc.) – dirkt Apr 22 '18 at 13:11
1

If you look at the deadbeef source for main.c the help() function lists the options that should be enough for you:

--pause              Pause playback
--nowplaying FMT     Print formatted track name to stdout
--nowplaying-tf FMT  Print formatted track name to stdout
--volume [NUM]       Print or set deadbeef volume level
0

Here is the script I ended up using. Because the --volume option is not yet available in the stable version, I used pactl commands instead.

This is a countdown sleep timer for DeaDBeeF. It supports all except one of the features from my Audacious script. They are:

  • Pick a sleep countdown timer value from a GUI (kdialog)
  • Pause audio playback in X minutes
  • Show time remaining in GUI (or via desktop notifications)
  • Show current volume level in GUI
  • Gradually reduce volume over the last 10 minutes
  • After playback is paused, reset volume level to the initial value
  • Allow countdown timer to be reset to a new value without disrupting playback
  • Allow countdown timer to be canceled without disrupting playback
  • Stop playback manually from the countdown timer GUI
  • If stopped, start playback again from the countdown timer GUI

Code:

#!/bin/bash

echo "DeaDBeeF control version 0.9"
function_pid=0

echo "true" > /dev/shm/allow_resetting_pactl_volume

function get_default_sink_name() {
    pacmd stat | awk -F": " '/^Default sink name: /{print $2}'
}

function get_default_sink_volume() {
    pacmd list-sinks | awk '/^\s+name: /{indefault = $2 == "<'$(get_default_sink_name)'>"} /^\s+volume: / && indefault {print $5; exit}'
}

function set_default_sink_volume() {
    pactl set-sink-volume $(get_default_sink_name) "$1"
}
#source: https://unix.stackexchange.com/a/251920/15010

function music_sleep(){
    countdown=$(($1*60-1))
    datestop=$((`date +%s` + $countdown));
    echo "pausing DeaDBeeF in $1 minutes..."

    #begin reducing sound volume 10 minutes (600 sec) from end
    voldown=$(($datestop - 600))

    while [ "$datestop" -ge `date +%s` ]; do
        datestr=$(printf "%s" $(date -u --date @$(($datestop + 1 - `date +%s`)) +%H:%M:%S))
        echo -ne "$datestr\r";
        #echo "$datestr";
        kdialog --passivepopup "DeaDBeeF will pause in: $datestr" 3
        if [ $(</dev/shm/allow_resetting_pactl_volume) == "true" ]; then
            countdown_saved_pactl_volume=$(get_default_sink_volume)
            echo $countdown_saved_pactl_volume > /dev/shm/countdown_saved_pactl_volume
        fi
        if [ `date +%s` -ge "$voldown" ]; then
            echo "false" > /dev/shm/allow_resetting_pactl_volume
            #reduce volume in 40 steps of 2 = 80% reduction (starting at 100) over 10 min
            set_default_sink_volume "-2%"
            currvol=$(get_default_sink_volume)
            echo -ne "\t\tvolume = $currvol\r"
            #echo "volume = $currvol"
            kdialog --passivepopup "volume = $currvol" 3
        fi
        sleep 15
    done

    deadbeef --pause
    echo "DeaDBeeF paused at $(date)"

    countdown_saved_pactl_volume=$(</dev/shm/countdown_saved_pactl_volume)
    set_default_sink_volume "$countdown_saved_pactl_volume"
    echo "true" > /dev/shm/allow_resetting_pactl_volume
}

countdown_saved_pactl_volume=$(get_default_sink_volume)
echo $countdown_saved_pactl_volume > /dev/shm/countdown_saved_pactl_volume
echo "initial volume is: $countdown_saved_pactl_volume"

while true; do

    choice=$(kdialog --combobox "          DeaDBeeF Sleep Timer:          " "cancel" "stop" "5" "10" "15" "20" "25" "30" "35" "45" "45" "50" "60" "90" "120" "180" "360" "480" --default "30");
    retval="$?"

    if [ "$retval" -eq 0 ]; then
            if [ $function_pid -ne 0 ]; then
                    kill $function_pid
                    function_pid=0
                    echo "countdown process terminated..."
            fi

            if [ "$choice" == cancel ]; then
                    echo "countdown canceled by user at $(date)"
                    kdialog --passivepopup "countdown canceled" 5
            elif [ "$choice" == stop ]; then
                    deadbeef --stop
                    echo "DeaDBeeF playback stopped at $(date)"
                    kdialog --passivepopup "DeaDBeeF playback stopped" 5
            else
                    echo "countdown (re)set by user at $(date)"
                    kdialog --passivepopup "countdown started" 5
                    #audresult=$(audtool playlist-shuffle-status)
                    #if [ "$audresult" == "on" ]; then audtool playlist-shuffle-toggle; fi
                    isplaying=$(deadbeef --nowplaying-tf "%isplaying%")
                    ispaused=$(deadbeef --nowplaying-tf "%ispaused%")
                    echo "isplaying=$isplaying, ispaused=$ispaused"
                    if [[ "$isplaying" -ne 1 || "$ispaused" -eq 1 ]]; then deadbeef --play-pause; echo "playback started"; fi
                    music_sleep "$choice" &
                    function_pid=$!
                    echo "function_pid=$function_pid"
            fi
            countdown_saved_pactl_volume=$(</dev/shm/countdown_saved_pactl_volume)
            set_default_sink_volume "$countdown_saved_pactl_volume"
            echo "reset volume to: $countdown_saved_pactl_volume"
            allow_reset_saved_volume="true"
            echo "true" > /dev/shm/allow_resetting_pactl_volume

    elif [ "$retval" -eq 1 ]; then
            echo "exiting DeaDBeeFctl"
            break
    else
            kdialog --error "ERROR";
    fi;

done

rm /dev/shm/allow_resetting_pactl_volume
rm /dev/shm/countdown_saved_pactl_volume

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.