code: plan9front

Download patch

ref: 91791a03db3747cdcb480d62b1fd90b92626f1aa
parent: 338e4a0a88982da9f3ea0ce96c167877105bb669
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Sep 19 15:14:33 EDT 2022

audio/zuke: use digits to enter exact seek position

--- a/sys/man/1/zuke
+++ b/sys/man/1/zuke
@@ -86,7 +86,7 @@
 .I Zuke
 provides a number of keyboard controls:
 .RS
-.TF "p c Space"
+.TF "↑ ↓ Pgup Pgdown Home End"
 .TP
 .B -
 Lower volume.
@@ -94,12 +94,6 @@
 .B + =
 Increase volume.
 .TP
-.B ← →
-Seek 10 seconds back/forward.
-.TP
-.B , .
-Seek 60 seconds back/forward.
-.TP
 .B ↑ ↓ Pgup Pgdown Home End
 Move within the playlist.
 .TP
@@ -115,6 +109,12 @@
 .B < z
 Skip to previous track.
 .TP
+.B ← →
+Seek 10 seconds back/forward.
+.TP
+.B , .
+Seek 60 seconds back/forward.
+.TP
 .B v
 Stop
 .TP
@@ -140,6 +140,10 @@
 Repeat search backwards.
 .RE
 .PD
+.PP
+Typing any digit initiates a "Seek to" prompt. Minutes, hours and
+seconds can be separated with a colon, if needed, otherwise the
+position is taken as seconds from the beginning of the track.
 .PP
 .I Zuke
 can be controlled by emulating key presses via the plumber port
--- a/sys/src/cmd/audio/zuke/zuke.c
+++ b/sys/src/cmd/audio/zuke/zuke.c
@@ -274,8 +274,8 @@
 
 	/* seekbar playback/duration text */
 	msec = 0;
-	dur = getmeta(pcurplaying)->duration;
 	if(pcurplaying >= 0){
+		dur = getmeta(pcurplaying)->duration;
 		msec = byteswritten*1000/Bps;
 		if(dur > 0){
 			snprint(tmp, sizeof(tmp), "%s%P/%P 100%%",
@@ -297,6 +297,7 @@
 				msec/1000, volume);
 		}
 	}else{
+		dur = 0;
 		snprint(tmp, sizeof(tmp), "%s%d%%", shuffle != nil ? "∫ " : "", 100);
 		w = stringwidth(f, tmp);
 		snprint(tmp, sizeof(tmp), "%s%d%%", shuffle != nil ? "∫ " : "", volume);
@@ -722,8 +723,7 @@
 	boffsetlast = boffset;
 	byteswritten = boffset;
 	pcurplaying = player->pcur;
-	if(c != Cseekrel)
-		redraw(0);
+	redraw(1);
 
 	while(1){
 		n = ioread(io, p[1], buf, Relbufsz);
@@ -950,6 +950,25 @@
 }
 
 static void
+seekto(char *s)
+{
+	uvlong p;
+	char *e;
+
+	for(p = 0; *s; s = e){
+		p += strtoll(s, &e, 10);
+		if(s == e)
+			break;
+		if(*e == ':'){
+			p *= 60;
+			e++;
+		}
+	}
+
+	seekrel(playercurr, p - byteswritten/Bps);
+}
+
+static void
 search(char d)
 {
 	Meta *m;
@@ -1372,6 +1391,16 @@
 			break;
 		case Ekey:
 			switch(key){
+			default:
+				if(isdigit(key) && pcurplaying >= 0 && getmeta(pcurplaying)->duration > 0){
+					buf[0] = key;
+					buf[1] = 0;
+					if(enter("seek:", buf, sizeof(buf), mctl, &kctl, screen->screen) < 1)
+						redraw(1);
+					else
+						seekto(buf);
+				}
+				break;
 			case Kleft:
 				seekrel(playercurr, -(double)Seek);
 				break;