-1

I have written a script for Elementary OS that pauses all running media players. This is because the sound may be really loud before suspension. Sadly, I can't get it to properly work.

#! /bin/sh
# 
# Copyright (c) Jason Anderson 2014 <sirius-C at iname dot com>
# License: GPL-2
# * December 1, 2014
# - Version 0.1
# - Initial version
# * December 4, 2014
# - Version 0.2
# - Changed it for Totem video player
# - This is compatible with Audacious, Clementine, and VLC
# - Doesn't work for SMplayer
# * December 13, 2014
# - Cleaned up the code a little (added "suspend" to the case arguments).
# - Found out Banshee works, too.
# * December 14, 2014
# - Version 0.3
# - Refactored D-Bus code that sends the pause signal.

# Function for pausing the audio of each MPRIS-enabled media player.
pause_music() {
# Walk through the available media players via a call to qdbus and tell each of them
# to pause.  Usually the user has just one media player going, but we don't know which
# one.  So we have to do it this way.
  for i in $(qdbus org.mpris.MediaPlayer2.*)
    do
# Had a problem with Totem video player.  This works for the currently running
# instance of Totem.
      if [[ $i =~ "totem" ]]; then
# Don't know how this works for multiple instances of Totem.  But then again, who
# has multiple versions of Totem running at once?
         logger "[pause_media_players] Pausing Totem..."
         totem --pause.
      fi

      logger "[pause_media_players] Pausing the media player..."

      dbus-send --print-reply --dest=$i /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause
      logger "[pause_media_players] ...Okay, they've been paused."
  done
}

logger "[13_pause-media-players] Started the pausing script."

# TODO: use another D-Bus application that's installed by default (i.e. gdbus).

# We need to use dbus-send so as to pause all of the media players that are listening via MPRIS.
case "$1" in
     hibernate|suspend)
       logger "[13_pause-media-players] We're hibernating.  Going down!"
       pause_music
            ;;
     resume|thaw)
       logger "[13_pause-media-players] We're unthawing.  Rise and shine!"
       pause_music
            ;;
# If we have anything else than a hibernate or a thaw, try to exit gracefully.
     *) 
       exit $NA 
            ;;
esac

exit 0

I thought it could be that when the computer comes back from suspension, it resumes the running media player. Turns out that's wrong, too. I also thought it was the order in which the scripts are executing. That wasn't the problem, either.

So I can't figure out whether it's just the syntax of the script, or it's something that has to do with D-Bus.

Ertain
  • 67
  • 11
  • do you want to execute `dbus-send ...` even if you've processed a `totem`? If not, put the `dbus-send ...` in an `else` block to the initial `if ... ` block. Good luck. – shellter Dec 14 '14 at 22:03
  • _*After trying the suggestion*_ Looks like that didn't work. While I was able to progress with the script, it doesn't stop the media players when I suspend to disk. Heck, I think that in the current condition (seen [here](http://pastebin.com/BT8TVhWa)) the system can't _return_ from suspension, and so I have do do a hard reboot. Also please bear in mind that I'm using the beta version of Freya for Elementary OS. – Ertain Dec 15 '14 at 01:03
  • as `dbus-send` and `totem` seem to be the 2 programs that do the "heavy-lifting" , I would use `man dbus-send` etc and see if there is a debug/verbose mode (usually `-v, -vv, -vvv`) so the program will show you how far it is geting. (I don't have experience with what your working with, I'm just offering general observations). Good luck! – shellter Dec 15 '14 at 01:15

1 Answers1

0

I was finally able to do it. But I had to use setuid extensively, which I don't think is very secure. Anyway, here's the finished script:

#!/bin/bash

# Function for pausing the audio of each MPRIS-enabled media player.
pause_music() {
    # This has to get the current address for the X server's DISPLAY variable.
    # ...How I get that, I do not know. 
    DISPLAY=":0"
    export DISPLAY
    object_path="/org/mpris/MediaPlayer2"
    method="org.mpris.MediaPlayer2.Player.Pause"
    # Use the users command and go through each user that's logged in.
    for user in $(users); do
      user_id=$(id -u $user)
      # Here's the hard part: making the system think that the originating user issued the command.
      # Usually when you call mdbus2 it returns a list of services on the session bus, which is what
      # we need.
      output=$(setuid $user_id mdbus2 | grep MediaPlayer2)
      # Now let's check to see if we really did have some output from that mdbus2 query.
      if [ -z $output ]; then
        logger "[$0] No media player detected."
        exit 0
      # Use pgrep to see if an instance of Totem is running.
      else if [ $(pgrep totem) ]; then
      # Apparently, this is the only way I know how to pause a Totem session already
      # in progress.
        logger "[$0] Now attempting to pause the media player..."
        totem --pause
        logger "[$0] ...Okay, the media player been paused."
      else
        logger "[$0] Now attempting to pause the media player..."
        setuid $user_id gdbus call --session --dest $output --object-path $object_path --method $method
        logger "[$0] ...Okay, the media player been paused."
      fi
    done
}

case "$1" in
     hibernate|suspend)
       logger "[$0] We're hibernating.  Going down!"
       pause_music
            ;;
     resume|thaw)
       logger "[$0] We're thawing.  Rise and shine!"
            ;;
# If we have anything else than a hibernate or a thaw, try to exit gracefully.
     *) 
       exit 0
            ;;
esac

exit 0
Ertain
  • 67
  • 11