Pages

Change volume with script

dimanche 17 juillet 2016

This ruby script works here.
May need to install ruby.

Code:

#!/usr/bin/ruby

#
# Moved to: http://ift.tt/29H99I2
#
# This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 
# Unported License. To view a copy of this license, visit 
# http://ift.tt/gc84jZ.
#
# Forked/derived from original by Jasper Van der Jeugt (jaspervdj);
# large chunks rewritten by Steven Saus (uriel1998)
# This is designed to set your pulseaudio volume settings, muting, and
# default sink from the command line.  It will even switch currently
# running streams to the new sink when you switch it!
# Usage will be largely for folks who are using keybinds for volume, etc.
# Originally wrote this to work with ALSA cards - that's what I have.
# (see line 46) but the code at line 45 *should* work for anything
# that's set up as a device in PulseAudio.  This is written to work
# with the version of PulseAudio I have on my system - 0.9.22.
# By perusing the online PulseAudio documentation, it looks like this
# *should* still work just fine for later versions.  Please ping me one
# way or another so I can properly document/fix it...

# To do:   -Set toggle (like the q toggle) so that actions only impact
#           current default sink
#          -Add in toggle so simple output available for notify-osd

# 20121114:uriel1998: Added introduction/description above
# 20121114:uriel1998: Standardized indentations
# 20121114:uriel1998: Rewrote if/else statements into case statements
# 20121114:uriel1998: Added usage instructions when no arguments given
# 20121114:uriel1998: Added quiet option
# 20121114:uriel1998: Added explicit setting of volume
# 20121114:uriel1998: Added explicit muting/unmuting instead of just
#                     toggling mute
# 20121114:uriel1998: Formatted output to be somewhat more human-
#                     readable, including padding & volume percentages
# 20121114:uriel1998: Added function to allow changing default sink
# 20121114:uriel1998: Added code to switch playing streams to new sink.
# 20121114:uriel1998: Rewrote array; arranged by sink id instead of name
# 20120210:uriel1998: Changed bit of code toggling mute
# 20120210:uriel1998: Added output, so it could be piped to a notify-osd
#                     or somesuch if desired. (superceded 20121114)
# 20120210:uriel1998: Original fork from http://ift.tt/29H91rF


# Function to test if argument is number, from
#http://ift.tt/29H946S
class String
        def is_number?
                true if Float(self) rescue false
        end
end

# Pulseaudio volume control
class Pulse
  attr_reader :volumes, :mutes

  # Constructor
  def initialize
        dump = `pacmd dump`.lines
        @volumes = {}
        @mutes = {}
        @names = {}
        @id = {}
        $longname = 0

        dump.each do |line|
        args = line.split

        #We are using the id to actually enumerate this bloody array.
        if !args[2].nil? and args[2].include? "device_id" then # this should work for any recognized device
        #if args[1] == "module-alsa-card" then  # this works if you only have ALSA cards.
                s1 = args[2].sub("device_id=\"","")
                      s2 = s1.sub("\"","")
                      number = s2.to_i
                        @id[number] = number
                      crapstring = args[3].sub("name=\"","")
                      @names[number] = crapstring.sub("\"","")
                      if @names[number].length > $longname
                                $longname = @names[number].length
                        end
        else
                if @names.keys.length > 0   # we already have something in the array
                        @names.keys.each do |sink|
                                if !args[1].nil? and args[1].include? @names[sink]   # and if it's a sink we recognize AND not nil...
                                        result = case args[0]
                                                when "set-default-sink" then $defaultsink = args[1].sub("alsa_output.","")  # static variable
                                                when "set-sink-volume" then @volumes[@id[sink]] = args[2].hex
                                                when "set-sink-mute" then @mutes[@id[sink]] = args[2]
                                        end
                                end
                        end
                end
          end
  end

  # Adjust the volume with the given increment for every sink
  def volume_set_relative(increment)
        @volumes.keys.each do |sink|
                volume = @volumes[sink] + increment
                volume = [[0, volume].max, 0x10000].min
                @volumes[sink] = volume
                `pacmd set-sink-volume #{sink} #{"0x%x" % volume}`
        end
  end

  # Adjust the volume with the given increment for every sink
  def volume_set_absolute(setvol)
    if setvol < 100.1
            @volumes.keys.each do |sink|
                volume = setvol * 65536 / 100
                @volumes[sink] = volume
                `pacmd set-sink-volume #{sink} #{"0x%x" % volume}`
        end
    end
  end

  # Toggle the mute setting for every sink
  def mute_toggle
        @mutes.keys.each do |sink|
                if @mutes[sink] == "yes"
                        `pacmd set-sink-mute #{sink} no`
                else
                        `pacmd set-sink-mute #{sink} yes`
                end
            end
  end
  def mute(setting)
        @mutes.keys.each do |sink|
                `pacmd set-sink-mute #{sink} #{setting}`
            end
  end

  # give me that sweet percentage value.
  def percentage(vol)
          return vol * 100 / 65536
  end

  def setdefault
        @names.keys.each do |sink|
                if $defaultsink.include? @names[sink]
                        puts "#{@id[sink]}. #{@names[sink]} *"
                else
                        puts "#{@id[sink]}. #{@names[sink]}"
                end
        end
        puts "Which sink shall be set as default (enter the number)"
        scratch = STDIN.gets.chomp
        newdefault = scratch.to_i
        if @id.include? newdefault
                `pacmd set-default-sink #{newdefault}`

                # Now to move all current playing stuff to the new sink....
                dump2 = `pacmd list-sink-inputs`.lines
                @inputs = {}
                counter = 0
                dump2.each do |line|
                        args = line.split
                        if args[0] == "index:"  # We need to find the item index for each playing stream
                                @inputs[counter] = args[1]
                                counter += 1
                        end
                end
                # And now to shift them all to the new sink.
                count2 = 0
                while count2 < counter
                        `pacmd move-sink-input #{@inputs[count2]} #{newdefault}`
                        count2 += 1
                end
        else
                puts "That input index does not exist.  You silly person."
        end
  end


  # so we can have nice things.
  def padstring(strlen)
        dyncounter = 0
        counter = $longname.to_i - strlen.to_i
        padder = " "
        while dyncounter < counter do
                padder << " "
                dyncounter += 1
        end
        return padder
  end

  # Report out settings for each sink.
  def status
        # needed to get new values
        initialize
        puts "##Current status##########################################"
        puts "ID  Sink Name#{padstring(11)} Mute Vol Default"
        @id.keys.each do |sink|
                # making volume into a percentage for humans
                # Not sure why I have to pass to a subprocess to make it do, but...
                volpercent = percentage(@volumes[sink])
                if $defaultsink.include? @names[sink]
                        puts "#{@id[sink]}. #{@names[sink]}#{padstring(@names[sink].length)} #{@mutes[sink]}  #{volpercent}%    *"
                else
                        puts "#{@id[sink]}. #{@names[sink]}#{padstring(@names[sink].length)} #{@mutes[sink]}  #{volpercent}%"
                end
        end
        puts "##########################################################"
  end
end

# Control code
p = Pulse.new
        unless ARGV.length > 0
                puts "\nUsage: ruby volume.rb [0-100|up|down|toggle|mute|unmute|default] [q]\n[0-100] - set percentage of max volume for all sinks\nup|down - Changes volume on all sinks\ntoggle|mute|unmute - Sets mute on all sinks\ndefault - Select default sink from commandline\nq - quiet; no status output\n"
        else
                if ARGV.first.is_number?
                        absvolume = ARGV.first.to_i
                        p.volume_set_absolute(absvolume)
                else
                        result = case ARGV.first
                                when "up" then p.volume_set_relative 0x1000
                                when "down" then p.volume_set_relative -0x1000
                                when "toggle" then p.mute_toggle
                                when "mute" then p.mute("yes")
                                when "unmute" then p.mute("no")
                                when "default" then p.setdefault
                                # status not needed; it's included
                        end
                end
        end
# Always give us the results.
        if !ARGV.include? "q"
                p.status
        end
end

Let's block ads! (Why?)



Change volume with script

Aucun commentaire:

Enregistrer un commentaire