Fandom

Music Player Daemon Community Wiki

Hack:stop after current

525pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

A hack to wait until the current song is finished, then stop MPD.

Per request in the Hacks list.


In the latest mpc version there is a cool option --wait. Si no it's really simple (requires mpc)

mpc current --wait ; mpc stop


From [1]:

sleep $(mpc | awk -F"[ /:]" '/playing/ {print 60*($8-$6)+$9-$7}');mpc pause




I'm sure there are many nicer ways to achieve this, but it works for me.

In shuffle mode, the playlist is re-shuffled after playing is stopped. This script pauses, instead of stopping, to avoid this. If you want to really stop playing, change the last line from 'pause' to 'stop'.

by Harun Vos


Requires mpc


stop_after_current.sh

#!/bin/bash
# MPD script to stop playback after the current track.
# Was a simple hack, but I got a bit carried away.
# Designed to run in the background eg. in response to a keypress, so no error messages.
# If it detects that anything has changed outside of its control, it silently aborts.
# Written by Harun Vos, released into the public domain.

# Requires mpc - set the path here.
MPC=mpc

# Extract the interesting line from the mpc output.
# There must be a nicer way of dealing with multi-line shell variables.
function getDetailsLine()
{
  local d=$($MPC --format "no file name")
  d=$(tail -1 <<EOL
$(head -2 <<EOL2
$d
EOL2)
EOL)
  echo $d
}

# Get the playing/paused status.
function getStateFromLine()
{
  echo $*|cut -d' ' -f1
}

# Get the number of the currently playing song.
function getSongFromLine()
{
  echo $*|cut -d' ' -f2|cut -d'/' -f1|cut -d'#' -f2
}

# Convert the mm:ss format to the number of seconds.
# This 10#stuff forces the numbers into base 10, even if they start with a 0.
function minToSec()
{
  echo $((10#$(echo $1|cut -d':' -f1) * 60 + 10#$(echo $1|cut -d':' -f2)))
}

# Find out how long we should wait for the end of the current song.
function getTimeRemainingFromLine()
{
  local current=$(echo $*|cut -d' ' -f3|cut -d'/' -f1)
  local total=$(echo $*|cut -d' ' -f3|cut -d'/' -f2)
  current=$(minToSec $current)
  total=$(minToSec $total)
  echo $(($total - $current))
}

# Dont do anything if we arent playing.
details=$(getDetailsLine)
currState=$(getStateFromLine $details)
if [ "$currState" != "[playing]" ]; then exit; fi

currSong=$(getSongFromLine $details)
timeRemaining=$(getTimeRemainingFromLine $details)
# Wait till almost the end of the current song.
# Try to stop before the end of the current song, rather than after the start of the next one.
if [ $timeRemaining -gt 1 ]; then
  sleep $(($timeRemaining - 1))
fi

# Make sure it is still playing.
details=$(getDetailsLine)
currState=$(getStateFromLine $details)
if [ "$currState" != "[playing]" ]; then exit; fi

# And make sure it is still the same song.
finalSong=$(getSongFromLine $details)
if [ "$finalSong" != "$currSong" ]; then exit; fi

# And make sure the song is actually ending now - it hasnt been restarted.
timeRemaining=$(getTimeRemainingFromLine $details)
if [ $timeRemaining -gt 2 ]; then exit; fi

# Make sure the playlist advances, even though we stop on the old song.
$MPC --no-status pause 2>&1 >> /dev/null
details=$(getDetailsLine)
finalSong=$(getSongFromLine $details)
if [ "$finalSong" == "$currSong" ]; then
  $MPC --no-status next 2>&1 >> /dev/null
fi
$MPC --no-status pause 2>&1 >> /dev/null




By JustJ: I made a few arragements which are mostly suited for a remote controlled pc e.g. linux music box. Also in this version you can, by starting the program multiple times, make the program stop after 2 or more songs. Basicly I've splitted the program in two, one is the original programm that is always running (now called mpdsaca (mpd stop after current always)), and the other one is a start script (mpdsac) which if the main program is not yet running starts is, but if it's running it does the following: it checks for a file, in this case /tog/mpdsac, if it doesn't exist, it creates it and writes 1 in it. If it already exists it adds one to the number.

I've altered the main program in a way that instead of pausing (which is the last paragraph) it checks weather /tog/mpdsac exists, then if its content is 1 removes it and if it's a number higher than 1 it decreases it by 1 and in both cases restarts itself. If the file (/tog/mpdsac) is no longer present it does what it was supposed to do and pauses mpd.

What I have to add is that the syntax is possiby horrible, and the style wharever you may call it, this is just a built-to-work solution.

Main file (mpdsaca)

#!/bin/bash
# MPD script to stop playback after the current track.
# Was a simple hack, but I got a bit carried away.
# Designed to run in the background eg. in response to a keypress, so no 
#error messages.
# If it detects that anything has changed outside of its control, it 
#silently aborts.
# Written by Harun Vos, released into the public domain.

# Requires mpc - set the path here.
MPC=mpc

# Extract the interesting line from the mpc output.
# There must be a nicer way of dealing with multi-line shell variables.
function getDetailsLine()
{
  local d=$($MPC --format "no file name")
  d=$(tail -1 <<EOL
$(head -2 <<EOL2
$d
EOL2)
EOL)
  echo $d
}

# Get the playing/paused status.
function getStateFromLine()
{
  echo $*|cut -d' ' -f1
}

# Get the number of the currently playing song.
function getSongFromLine()
{
  echo $*|cut -d' ' -f2|cut -d'/' -f1|cut -d'#' -f2
}

# Convert the mm:ss format to the number of seconds.
# This 10#stuff forces the numbers into base 10, even if they start with a 
#0.
function minToSec()
{
  echo $((10#$(echo $1|cut -d':' -f1) * 60 + 10#$(echo $1|cut -d':' -f2)))
}

# Find out how long we should wait for the end of the current song.
function getTimeRemainingFromLine()
{
  local current=$(echo $*|cut -d' ' -f3|cut -d'/' -f1)
  local total=$(echo $*|cut -d' ' -f3|cut -d'/' -f2)
  current=$(minToSec $current)
  total=$(minToSec $total)
  echo $(($total - $current))
}

# Dont do anything if we arent playing.
details=$(getDetailsLine)
currState=$(getStateFromLine $details)
if [ "$currState" != "[playing]" ]; then exit; fi

currSong=$(getSongFromLine $details)
timeRemaining=$(getTimeRemainingFromLine $details)
# Wait till almost the end of the current song.
# Try to stop before the end of the current song, rather than after the 
# start of the next one.
if [ $timeRemaining -gt 1 ]; then
  sleep $(($timeRemaining - 1))
fi

# Make sure it is still playing.
details=$(getDetailsLine)
currState=$(getStateFromLine $details)
if [ "$currState" != "[playing]" ]; then exit; fi

# And make sure it is still the same song.
finalSong=$(getSongFromLine $details)
if [ "$finalSong" != "$currSong" ]; then exit; fi

# And make sure the song is actually ending now - it hasnt been restarted.
timeRemaining=$(getTimeRemainingFromLine $details)
if [ $timeRemaining -gt 2 ]; then exit; fi

# Make sure the playlist advances, even though we stop on the old song.
# This is the only area that is modified in the alternate script
TOG="/tog/mpdsac"
if [ -e $TOG ]
	then
	if [ $(head -1 $TOG ) = "1"
		then
		rm $TOG
		mpdsaca &
		else
		echo $(expr $(head -1 $TOG) - 1) > $TOG
		mpdsaca &
	fi
	else
	$MPC --no-status pause 2>&1 >> /dev/null
	details=$(getDetailsLine)
	finalSong=$(getSongFromLine $details)
	if [ "$finalSong" == "$currSong" ]; then
	$MPC --no-status next 2>&1 >> /dev/null
	fi
	$MPC --no-status pause 2>&1 >> /dev/null
fi

Start File (mpdsac)

#!/bin/sh

TOG="/tog/mpdsac"

if [ $(pexist mpdsaca) ]
	then
	if [ -e $TOG ]
		then
		echo $(expr $(head -1 $TOG) + 1) > $TOG
		else
		echo 1 > $TOG
	fi
	else
	rm -f /tog/mpdsac
	mpdsaca &
fi

there are also two more or less usefull scripts:

This one completely aborts the stopping after a song

#!/bin/sh
killall mpdsaca>/dev/null 2>/dev/null
rm -f /tog/mpdsac

And this one announces via any speak synthesizer (here represented by speak) how many songs till stop

#!/bin/sh

if [ $(pexist mpdsaca) ]
	then
	if [ -e /tog/mpdsac ]
		then
		speak "stopping after $(expr $(head -1 /tog/mpdsac) + 1 ) songs"
		else
		speak "stopping after this song"
	fi
	else
	speak "not stopping at all"
fi

Also on Fandom

Random Wiki