Advertisement
TakeFive

Silent gap for Strawberry audio player (alpha).

Jan 12th, 2025 (edited)
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.35 KB | None | 0 0
  1. #!/usr/bin/env bash
  2.  
  3. # https://forum.strawberrymusicplayer.org/topic/3417/optional-gap-between-each-song-playback
  4. #
  5. # Poor man's custom gap for the Strawberry audio player via "Stop after this track" feature.
  6. # Use case: Introduce a silent period after each track.
  7.  
  8. ###################################### IMPORTANT ################################################
  9. #                                                                                               #
  10. #                  Close Strawberry first and make sure the process doesn't exist.              #
  11. #                       Otherwise you may backup a corrupted database.                          #
  12. #                                                                                               #
  13. #    Backup the database:                                                                       #
  14. #  echo cp ~/.local/share/strawberry/strawberry/strawberry.db{,__$(date +'%Y-%m-%d_%H:%M')__OK} #
  15. #  ls -l ~/.local/share/strawberry/strawberry/                                                  #
  16. #                                                                                               #
  17. #    Install the latest version of Strawberry (1.2.4 as of now) from                            #
  18. #   https://github.com/strawberrymusicplayer/strawberry/releases                                #
  19. #                                                                                               #
  20. #################################################################################################
  21.  
  22.  
  23. # On the sunny side:
  24. #   After running the script, every finished track will be followed by the chosen period of
  25. # silent time, and then the next track will be played. During the gap, the player is stopped.
  26. # Double clicks anywhere on the playlist work normally while playing or in Pause.
  27. # The previous attempt (a different approach using Previous and pausing there, with an older
  28. # Strawberry) lead to freezes of the player, other programs and the sound system. Never happened
  29. # with this one, but be cautious.
  30.  
  31. # Limitations/nuisances:
  32. #   The script uses D-Bus MPRIS interface, which doesn't account for the end of a track nor can
  33. # it detect how Play, Stop and other actions were initiated. There is no way to differentiate
  34. # between mouse clicks, commands or actions automatically performed by the player.
  35. #   So, if the user clicks on Stop, the information received by the script will be the same as
  36. # that of "Stop after this track", and it will start the countdowm of the silent period. Use
  37. # pause instead to stop the audio temporarily, or interrupt the script.
  38. #
  39. #   The OSD/notification system of Strawberry is not controllable externally, aside from the two
  40. # actions assignable to keyboard shortcuts. If it is active, it will notify the stop of every track.
  41. # And in any case, the album cover pane will disappear when the player is stopped, as usual.
  42.  
  43. #   This alpha is to test and decide if the benefit of the general idea outweights its disadvantages.
  44. # Several things are on the to-do list and may be achieved or not depending on availability of wisdom
  45. # and possible comments: better argument handling, change of track during silence, start/end from a
  46. # desktop icon, time units for the gap (minutes, currently only seconds are used), alternatives for
  47. # the dbus tools, user input at runtime, custom layout of the metadata shown in the terminal,
  48. # image-to-ascii for the album cover -kidding-, etc.
  49.  
  50. # Tested only for the general case of a regular static playlist.
  51.  
  52. ##### User config.
  53.  
  54. gap_secs_default="30"           # The gap: seconds to wait before playing the next track.
  55. show_countdown="yes"            # A little feedback in the terminal; not necessary.
  56. countdown_step="0.2"            # "Faster seconds" for the first tests. Set to 1 when done.
  57.  
  58. #############################################################################
  59.  
  60. short="${0##*\/}"
  61. _debug_=":"
  62.  
  63.  
  64. _help () {
  65.     echo "Usage: $short [-h|--help] [-nc] [N]"
  66.     echo "Gap maker for Strawberry. Stops it for N seconds after each track and plays the next one."
  67.     echo "        N  :    Seconds. Default: $gap_secs_default"
  68.     echo "       -nc :    Don't show countdown."
  69. #    echo "  --verbose:    "
  70.     echo "       -h  :    This help."
  71.     echo ""
  72.     echo "  Example: ./$short -nc 35"
  73.     echo "  Quit: Control-C                                       $short v0.1-alpha - \"Gapper's Delight.\""
  74.     }
  75.  
  76.  
  77. _args () {
  78.     while : ; do
  79.         case "$1" in
  80.                      "--debug") _debug_="echo "  ; shift ;;
  81.                  "-h"|"--help") _help ; exit ;;
  82.         "-nc"|"--no-countdown") show_countdown="no" ; shift ;;
  83.                    "--verbose") _debug_="echo " ; shift ;;
  84.                             "") gap_secs="$gap_secs_default" ; break ;;
  85.                              *) [[ "$1" =~ ^[0-9]+ ]] && gap_secs="$1" || \
  86.                                     echo "Ignored parameter: $1" >&2
  87.                                     break ;;
  88.         esac
  89.     done
  90.     }
  91.  
  92.  
  93. _checkTools () {
  94.     for tool in gdbus dbus-monitor; do
  95.         which "$tool" >/dev/null 2>&1 || {
  96.             echo "$tool not found."
  97.             missing="yes" ; }
  98.     done
  99.     [[ "$missing" == "yes" ]] && {
  100.         echo "Can't find the above program(s). Exiting..."
  101.         exit 1
  102.         }
  103.     }
  104.  
  105.  
  106. args=( "$@" )
  107. _args "${args[@]}"
  108.  
  109.  
  110. _playerStatus () {
  111.     player_status="$(gdbus call -e  --dest org.mpris.MediaPlayer2.strawberry --object-path /org/mpris/MediaPlayer2 --method org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player PlaybackStatus)"
  112.     }
  113.  
  114.  
  115. _metadataAlt () {
  116.     metadata="$(gdbus call -e  --dest org.mpris.MediaPlayer2.strawberry --object-path /org/mpris/MediaPlayer2 --method org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player Metadata)"
  117.  
  118.     # xesam's quoting is worth it
  119.     mod1="${metadata#????}"
  120.     mod1="${mod1%????}"$'\n'
  121.     mod1="${mod1//, \'mpris:/$'\n'}"
  122.     mod1="${mod1//, \'xesam:/$'\n'}"
  123.     mod1="${mod1/>, \'year\': </>$'\n'year\': <}"
  124.     mod1="${mod1//\': <[/=}"
  125.     mod1="${mod1//\': </=}"
  126.     mod1="${mod1//\]>$'\n'/$'\n'}"
  127.     mod1="${mod1/length=int64 /length=}"
  128.     mod1="${mod1/trackid=objectpath \'/trackid=\'}"
  129.     mod1="${mod1//>$'\n'/$'\n'}"
  130.     mod1="${mod1/\{sv\} \{$'\n'/}"
  131.     mod1="${mod1%$'\n'}"
  132.  
  133.     while read -r -u 8 line ; do
  134.         eval "$line"
  135.     done 8<<<"$mod1"
  136.  
  137.     art_url="$artUrl"
  138.     duration="${length%???}"
  139.     playlist_pos="${trackid##*\/}"
  140.     album_artist="$albumArtist"
  141.     birth="${contentCreated/T/ }"
  142.     last_used="${lastUsed/T/ }"
  143.     track_number="$trackNumber"
  144.     use_count="$useCount"
  145.     }
  146.  
  147.  
  148. _printMetadata () {
  149.     echo "    playlist_pos:  $(( playlist_pos + 1 ))"
  150.  
  151.     echo "    artist:        $artist"
  152.     echo "    title:         $title"
  153.     echo "    duration:      $duration"
  154.     echo "    album:         $album"
  155.     echo "    year:          $year"
  156.     echo "    track_number:  $track_number"
  157.     echo "    album_artist:  $album_artist"
  158.     echo "    genre:         $genre"
  159.     echo "    composer:      $composer"
  160.     echo "    comment:       $comment"
  161.  
  162.     echo "    bitrate:       $bitrate"
  163.     echo "    url:           $url"
  164.     echo "    art_url:       $art_url"
  165.     echo "    birth:         $birth"
  166.     echo "    last_used:     $last_used"
  167.     echo "    use_count:     $use_count"
  168.     }
  169.  
  170.  
  171. _gap () {
  172.     unset cdi_length
  173.     countdown="$gap_secs"
  174.     [[ "$show_countdown" != "yes" ]] && {
  175.         echo -n "Waiting... "
  176.         sleep "$gap_secs" ; } || {
  177.                 cd0_length=$(( 13 + ${#countdown} ))
  178.             echo -n "  Countdown: $countdown "
  179.             ((countdown--))
  180.             for ((i=countdown; i>=0; i--)); do
  181.                 sleep "$countdown_step"
  182.                 [[ "$show_countdown" == "yes" ]] && echo -n "$i "
  183.                 cdi_length="$(( cdi_length + ${#i} + 1 ))"
  184.             done
  185.     len="$(( cd0_length + cdi_length ))"
  186.     echo -ne "\r"
  187.     printf "%${len}s"
  188.     echo -ne "\r"
  189.      }
  190.     }
  191.  
  192. ############################################################### end functions
  193.  
  194. date -u
  195.  
  196. _checkTools
  197.  
  198. _metadataAlt
  199.  
  200. [[ "$_debug_" == ":" ]] || _printMetadata
  201.  
  202. st="strawberry"
  203.  
  204.  
  205. coproc dbus_monitor {
  206.     dbus-monitor --monitor --session \
  207.         "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/mpris/MediaPlayer2'" | \
  208.             grep --line-buffered --no-group-separator -A 1 '         string "PlaybackStatus"'
  209.     }
  210.  
  211. coproc_pid="$dbus_monitor_PID"
  212.  
  213. $_debug_ "File descriptor is ${dbus_monitor[1]} -- \$dbus_monitor_PID is $dbus_monitor_PID  --  \$\$ is $$  "
  214. $_debug_ "playlist_pos is $(( playlist_pos + 1 ))"
  215.  
  216. [[ -n "$title" ]] && echo "Títle:    $title"
  217.  
  218. while read -r line; do
  219.     $_debug_
  220.     $_debug_ ">> $line"
  221.     case "$line" in
  222.                      'string "PlaybackStatus"') : ;;
  223.        'variant             string "Paused"'  ) $_debug_ $'\x0a'"PAUSED"
  224.                                                 paused="yes" ;;
  225.        'variant             string "Playing"' ) $_debug_ $'\x0a'"PLAYING"
  226.                                                 _metadataAlt
  227.                                                 [[ "$_debug_" == ":" ]] || _printMetadata
  228.                                                 [[ "$paused" != "yes" ]] && {
  229.                                                     echo "Title:    $title" ; }
  230.                                                 paused="no"
  231.                                                 $_debug_ "PLAYING NUM $(( playlist_pos + 1 ))"
  232.                                                 $st -q
  233.                                                 $_debug_ "requested STOP-after"  ;;
  234.        'variant             string "Stopped"')  $_debug_ $'\x0a'"STOPPED (waiting)"
  235.                                                 $_debug_ "Waiting $gap_secs"
  236.                                                 _metadataAlt
  237.                                                 [[ "$_debug_" == ":" ]] || _printMetadata
  238.                                                 _gap
  239.                                                 $st -k $(( playlist_pos + 1 )) ;;
  240.                                              *) $_debug_ "Stray line: --$line--" ;;
  241.  
  242.     esac
  243. done <&"${dbus_monitor[0]}"
  244.  
  245.  
  246. wait "${dbus_monitor[1]}"
  247.  
  248.  
  249.  
  250.  
  251. exit
  252. #############################################################################
  253. exit
  254.  
  255.  
  256. # Better safe than sorry: backup the database!
  257.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement