Volumechanger.sh
From MythTV Official Wiki
Note: The correct title of this article is volumechanger.sh. It appears incorrectly here due to technical restrictions.
| Author | Pieter Hoekstra |
| Description | Script to control volume, even when not playing media, with OSD-support |
| Supports | |
Contents |
Why this script
- Be able to control volume all the time, even when not playing media or playing other media-players, like MPD, mplayer or mythnetvision
- Apply different volumes to different channels. My center-speaker is now always 1.5 times louder
- Myth currently does not support my soundcard (Xonar D2X) master volume and is changing only one channel. Probably should file a bug for that...
OSD requires
- osd_cat (Ubuntu package: xosd-bin)
- Frontend control socket enabled
- Configure internal volume with a dummy soundcard (So it seems myth is changing volume and displays a nice OSD)
- Configure Frontend display/username in script
Script
#!/bin/bash
# Frontend display/username (Needed for OSD)
export DISPLAY=:0
export XAUTHORITY=/home/mediacenter/.Xauthority
#gdm:
#export XAUTHORITY=`find /var/run/gdm/ -name database | grep mediacenter`
CARD="hw:CARD=D2X"
# Change volume:
VOLUMEDB=$(amixer -D $CARD set Master $1 | sed '/^ *Front Left: /{s/^.*\[-\([0-9]*\).*dB\].*/\1/;p;};d;')
VOLUME=$(amixer -D $CARD get Master | sed '/^ *Front Left: /{s/^.*\[\([0-9]*\).*\%\].*/\1/;p;};d;')
# Multiply Center-volume with 2/3 (in Db this is louder)
let CVOLUMEDB=($VOLUMEDB)*2/3
amixer -d -D $CARD set Master "center -${CVOLUMEDB}dB"
if [ "$2" != "noosd" ]; then
# OSD with notify-send. Dont use it anymore, it stays to long on the screen
#
#STATUS=$(amixer -D 'hw:CARD=D2X' sget Master | awk '$1 == "Front" && $2 == "Left:" { print $NF; }')
#if [ $STATUS = '[off]' ]; then
# ICON=notification-audio-volume-muted
#elif [ $VOLUME -lt 33 ]; then
# ICON=notification-audio-volume-low
#elif [ $VOLUME -lt 66 ]; then
# ICON=notification-audio-volume-medium
#else
# ICON=notification-audio-volume-high
#fi
#notify-send "Volume" -i $ICON -h int:value:$VOLUME -h string:x-canonical-private-synchronous: -u critical
# OSD with Frontend control socket, using Myth internal volume control with dummy-soundcard and osd_cat fallback
if ! echo "play volume $VOLUME%" | nc localhost 6546 | grep "OK"; then
killall osd_cat
osd_cat -b percentage -P $VOLUME -p bottom -A center -d5 -c grey -f -misc-fixed-medium-r-semicondensed--*-500-*-*-c-*-*-* &
fi
fi
#if ! pidof -xs lcd.pl; then
# /path/to/lcd.pl &
#fi
Adding to Lirc
Config added to /etc/lirc/lircrc:
begin
remote = devinput
prog = irexec
button = KEY_VOLUMEDOWN
# config = amixer sset Master 2dB-
config = /path/to/volumechanger.sh 2dB-
repeat = 1
delay = 0
end
begin
remote = devinput
prog = irexec
button = KEY_VOLUMEUP
# config = amixer sset Master 2dB+
config = /path/to/volumechanger.sh 2dB+
repeat = 1
delay = 0
end
begin
remote = devinput
prog = irexec
button = KEY_MUTE
# config = amixer sset Master toggle
config = /path/to/volumechanger.sh toggle
repeat = 0
delay = 0
end
LCD support
Below is a hack to add the volume-changing to LCD as well. Add this to volumechanger.sh at the bottom to enable:
if ! pidof -xs lcd.pl; then
/path/to/lcd.pl &
fi
#!/usr/bin/perl -w
use 5.004;
use strict;
use IO::Socket;
use Fcntl;
# Host which runs lcdproc daemon (LCDd)
my $server = "localhost";
# Port on which LCDd listens to requests
my $port = "13666";
# wait-time (in seconds) when we are all done
my $waittime = 5;
############################################################
# End of user configurable parts
############################################################
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# Connect to the server...
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $server,
PeerPort => $port,
) or die "Cannot connect to LCDproc port ($server:$port)\n";
# Make sure our messages get there right away
$remote->autoflush(1);
print $remote "hello\n";
my $lcdconnect = <$remote>;
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name volume\n";
print $remote "screen_add volume\n";
print $remote "screen_set volume name {Volume} priority input heartbeat off\n";
print $remote "widget_add volume title string\n";
print $remote "widget_add volume vol hbar\n";
my $counter = 20;
my $status;
my $db;
my $ostatus = "";
my $mix;
my $volume;
while($counter > 0)
{
$mix = `amixer -D hw:CARD=D2X sget Master`;
if ($mix =~ / *Front Left:.+ \[(.*)%\] \[(.*).\d0dB\]/)
{
$volume = $1;
$db = "$2dB";
}
if ($mix =~ / *Front Left:.+ \[(.*)\]/)
{
$status = ($1 eq 'off' ? 'Uit' : "$volume% $db");
}
print $remote "widget_set volume vol 1 2 $volume\n";
if ($status ne $ostatus)
{
print $remote "widget_set volume title 1 1 {Volume $status} \n";
$counter = 20;
$ostatus = $status;
}
$counter--;
select(undef, undef, undef, 0.1);
}
while(defined(my $input = <$remote>)) { }
close($remote);
exit;