💾 Archived View for runjimmyrunrunyoufuckerrun.com › rc › music captured on 2021-12-17 at 13:26:06.

View Raw

More Information

-=-=-=-=-=-=-

#!/bin/rc
# music player in rc using plumbing rules:
#
#type is text
#data matches ⏶|⏷|⏮|⏪|⏴|⏯|⏵|⏩|⏭|🎲|↻|♪.*
#plumb to audio
#
#type is text
#data matches .+\.(mp3|ogg|flac|aac|mid|wav|it|mod|MOD)
#arg isfile $data
#data set $file
#plumb to audio

if(! test -f /mnt/plumb/audio){
	echo /mnt/plumb/audio not found! >[1=2]
	exit 'no plumb port for audio'
}
rfork en
nl = '
'
ramfs -m /mnt/musicramfs
cd /mnt/musicramfs
@{echo pri 12 >/proc/$pid/ctl} >/dev/null >[2=1] 
cur = ''
>list
if(! ~ $#* 0)
	cur = `{sed -n '${p;q;};w list' $*}
fn redraw{
	>/dev/text{
		cat list
		echo ⏶ ⏷ ⏮ ⏪ ⏴ ⏯ ⏵ ⏩ ⏭ 🎲 ↻ $state
		echo $cur
	}
}
fn stopdec{
	if(! ~ $decpid '' && test -d /proc/$decpid){
		@{echo kill >/proc/$decpid/notepg}&
		wait $decpid
	}
	decpid = ''
}
fn sighup sigint sigexit{
	stopdec
	echo kill >/proc/$readpid/ctl
	wait $readpid
	echo >/dev/kbdin
}
fn start{
	if(~ $cur '')
		state = (stopped: playlist empty)
	if not if(! test -w /dev/audio)
		state = (stopped: /dev/audio busy)
	if not if(test -r $cur){
		state = `{file -m $cur}
		switch($state){
		case audio/mpeg
			{audio/mp3dec -s $secs < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/wave
			{audio/wavdec -s $secs < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/basic
			secs = 0
			{audio/sundec < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/midi
			secs = 0
			{games/midi -c < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/mus
			secs = 0
			{games/mus | games/midi -c < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/*
			if(test -x /bin/^$state^dec){
				{$state^dec -s $secs < $cur >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
				decpid = $apid
			}
			if not
				state = (stopped: no decoder)
		}
		if(~ $state audio/*){
			⏱ = `{date -u $secs}
			state = (playing from $⏱(4))
			⏱ = `{date -n}
		}
		if not{
			plumb $cur
			state = playing
			plumb -d audio ⏭
		}
	}
	if not{
		url = `{echo $cur | tr -d ♪}
		>[2]/dev/null hget -r 'User-Agent: play' -r 'Icy-MetaData: 0' $url | read -c 512 > stream
		secs = 0
		state = (playing stream)
		switch(`{file -m stream}){
		case audio/mpeg
			{hget $url | audio/mp3dec >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
			decpid = $apid
		case audio/*
			if(test -x /bin/^$state^dec){
				{hget $url | $state^dec >/dev/audio >[2]/dev/null; plumb -d audio ⏭}&
				decpid = $apid
			}
			if not
				state = (stopped: no decoder)
		case *
			state = (stopped: bad track name!)
		}
		rm stream
	}
}
fn stop{
	stopdec
	if(~ $state(2) stream)
		state = (stopped: stream)
	if not{
		secs = `{echo $secs `{date -n} $⏱ -+p | dc}
		⏱ = `{date -u $secs}
		state = (paused at $⏱(4))
	}
}
fn skip{
	if(~ $state(1) playing && ! ~ $state(2) stream){
		stop
		secs = `{echo '[0pq]sx' $secs $1 'd0>xp' | dc}
		start
		redraw
	}
	if(~ $state(1) paused){
		secs = `{echo '[0pq]sx' $secs $1 'd0>xp' | dc}
		⏱ = `{date -u $secs}
		state = (paused at $⏱(4))
		redraw
	}
}
label music
echo scroll >/dev/wctl
secs = 0
state = (stopped: press space to start)
redraw
>[3]/dev/consctl{
	echo rawon >[1=3]
	while(k = `''{read -c 1 /dev/cons}){
		if(~ $k q   a z p '<' , ' ' . '>' n s S r c )
			plumb -d audio $k
		if not if(~ $k w){
			echo -n 'write playlist: '
			echo rawoff >[1=3]
			k = `{read /dev/cons}
			sed '/⏶/{N;s/.*\n//;q;}' /dev/text > $k
			echo rawon >[1=3]
		}
	}
}&
readpid = $apid
</mnt/plumb/audio while(plumb = `$nl{syscall -o read 0 buf 1048575 >[2]/dev/null}){
	plumb = $plumb($#plumb)
	switch($plumb){
	case q  
		exit
	case ⏶ a
		awk '/master/{print $2 + 3; exit}' /dev/volume >/dev/volume
	case ⏷ z
		awk '/master/{print $2 - 3; exit}' /dev/volume >/dev/volume
	case ⏮ p
		cur = `{echo /⏶/+t--^$nl^/⏶/,d^$nl^1p^$nl^d^$nl^w list | ed - /dev/text}
		if(~ $state(1) playing){
			stop
			secs = 0
			start
		}
		if not{
			secs = 0
			state = (stopped: press space to start)
		}
		redraw
	case ⏪ '<'
		skip 60-
	case ⏴ ,
		skip 10-
	case ⏯ ' '
		if(~ $state(1) playing)
			stop
		if not
			start
		redraw
	case ⏵ .
		skip 10+
	case ⏩ '>'
		skip 60+
	case ⏭ n
		cur = `{echo /⏶/+m0^$nl^/⏶/,d^$nl^'$p'^$nl^d^$nl^w list | ed - /dev/text}
		if(~ $state(1) playing){
			stop
			secs = 0
			start
		}
		if not{
			secs = 0
			state = (stopped: press space to start)
		}
		redraw
	case 🎲 s
		sed '/⏶/,$d' /dev/text | shuffle > list
		redraw
	case ↻ S
		sed '/⏶/{N;s/.*\n//;q;}' /dev/text | sort -r > tmp
		found = 0
		>a
		>b
		<tmp while(line = `{read}){
			if(~ $line $cur)
				found = 1
			if not if(~ $found 1)
				echo $line >> a
			if not
				echo $line >> b
		}
		cat a b > list
		rm a b tmp
		redraw
	case r c 
		redraw
	case *
		sed '/⏶/{N;s/.*\n//;q;}' /dev/text > tmp
		cur = $plumb
		found = 0
		>a
		>b
		<tmp while(line = `{read}){
			if(~ $line $cur)
				found = 1
			if not if(~ $found 1)
				echo $line >> a
			if not
				echo $line >> b
		}
		cat a b > list
		rm a b tmp
		if(~ $state(1) playing)
			stop
		secs = 0
		start
		redraw
	}
}