Shell-Script

Linux 的通用音頻睡眠倒數計時器

  • May 5, 2018

我為Audacious創建了一個 bash 腳本,它在 X 分鐘內暫停播放(並且在過去 10 分鐘內逐漸降低音量)。這個腳本在使用 Audacious 時很好地滿足了我的需求。但是,現在我正在切換到DeaDBeF

我有兩個選擇:修改我現有的腳本以使用 DeaDBeeF,或者創建一個通用方法,幾乎可以與任何 Linux 或 KDE 音頻播放器一起使用。我正在尋求任何一種方法的幫助。

但是,我無法找到 DeaDBeeF 的文件,這些文件允許我以我能夠使用 Audacious 的方式進行操作。如果我能找到文件(並且如果 DeaDBeeF 提供等效命令),我可以輕鬆地修改我現有的腳本。或者,如果有更多幫助,我可以實現一個通用腳本。

我不是開發人員,所以我首選的實現是一個簡單的 bash 腳本(儘管我對其他同樣簡單的實現選項持開放態度)。

如前所述,我正在尋求幫助來修改我的 bash 腳本以使用 DeaDBeeF 或以通用方式工作。這是我的腳本:

#!/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

此腳本中實現的基本功能是:

  • 從 GUI 中選擇睡眠倒計時計時器值
  • 倒數計時器啟動時禁用隨機(隨機)播放
  • 在 X 分鐘內暫停音頻播放
  • 在 GUI 中顯示剩餘時間(或通過桌面通知)
  • 在 GUI 中顯示目前音量級別
  • 在最後 10 分鐘內逐漸降低音量
  • 播放暫停後,將音量重置為初始值
  • 允許倒數計時器重置為新值而不中斷播放
  • 允許在不中斷播放的情況下取消倒數計時器
  • 從倒數計時器 GUI 手動停止播放

一些問題是:

DeadBeeF 有等效的命令嗎?

如果是,等效的 DeaDBeeF 命令的文件在哪裡?

對於已經熟悉 DeaDBeeF 的任何人,我是否可以期望在我的腳本中簡單地將 DeaDBeeF 命令替換為我現有的 Audacious 命令?或者差異是否大到需要完全重寫腳本?

如果具有上述功能的通用倒數計時器實現起來相對簡單,有人要指導我嗎?我認為音量部分將很容易實現:

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

來源

當涉及到 tso 暫停播放時,據我所知,以下命令不適合我的腳本要求:

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

上述方法不僅會暫停播放音頻,還會禁用所有應用程序的所有聲音,而且似乎還有其他潛在的副作用。

從我在這裡看到的情況來看,使用 pactl 控製播放和暫停(跨任何音頻播放器)看起來很困難。當然必須有一個更簡單的方法。如果它是特定於 KDE 的,我可以。

如果您查看main.c的 deadbeef 原始碼,該help()函式會列出對您來說應該足夠的選項:

--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

這是我最終使用的腳本。由於該--volume選項在穩定版本中尚不可用,因此我使用了pactl命令。

這是 DeaDBeeF 的倒計時睡眠定時器。它支持除我的 Audacious 腳本中的一項功能之外的所有功能。他們是:

  • 從 GUI (kdialog) 中選擇睡眠倒計時計時器值
  • 在 X 分鐘內暫停音頻播放
  • 在 GUI 中顯示剩餘時間(或通過桌面通知)
  • 在 GUI 中顯示目前音量級別
  • 在最後 10 分鐘內逐漸降低音量
  • 播放暫停後,將音量重置為初始值
  • 允許倒數計時器重置為新值而不中斷播放
  • 允許在不中斷播放的情況下取消倒數計時器
  • 從倒數計時器 GUI 手動停止播放
  • 如果停止,請從倒數計時器 GUI 重新開始播放

程式碼:

#!/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

引用自:https://unix.stackexchange.com/questions/439160