shithub: zuke

Download patch

ref: fbeb4cd4542ba98f54caa4892bd334fa34c8cbf4
parent: 4a98f6822ee85d5ab2d9ba98e3e5e8124a1f6605
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jan 13 10:27:50 EST 2021

plumbing music files (only the ones in the playlist for now) and playlists

--- a/README.md
+++ b/README.md
@@ -14,7 +14,8 @@
 
 ## 2020/12/22
 
-New playlist format. Zuke still will load old format and you can convert to the new one like so:
+New playlist format.  Zuke still will load old format and you can
+convert to the new one like so:
 
 	audio/zuke -G <old.plist >new.plist
 
@@ -28,17 +29,31 @@
 itself.  The other one is `audio/mkplist`, it's used to make playlists
 that are then fed to `audio/zuke`'s stdin:
 
-```
-% audio/mkplist /n/somefs/dir /n/otherfs/file.mp3 http://stream.nauticradio.net:14280/ > $home/somefs.plist
-% audio/zuke < $home/somefs.plist
-```
+	audio/mkplist /n/somefs/dir /n/otherfs/file.mp3 http://stream.nauticradio.net:14280/ > $home/somefs.plist
+	audio/zuke < $home/somefs.plist
 
 Of course, one can combine these steps into one:
 
-```
-% audio/mkplist /n/music | audio/zuke
-```
+	audio/mkplist /n/music | audio/zuke
 
+*NOTE*: don't forget to pass the *full* path to `audio/mkplist`, not a
+relative one.
+
+## Plumbing
+
+Plumbing music files and playlists is supported via "audio" port.  New
+files can't be added to the current playlist just yet.
+
+	type	is	text
+	data	matches	'.+\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS|plist)$'
+	arg	isfile	$0
+	plumb	to	audio
+	plumb	start	window -scroll play $file
+
+To disable plumbing, execute before launching zuke:
+
+	bind /dev/null /mnt/plumb/audio
+
 ## Formats
 
 The ones supported with stock 9front: mp3, ogg/vorbis, flac, wav.
@@ -64,47 +79,41 @@
 Zuke has an optional argument `-c` that specifies which columns to
 display, the default is `-c AatD`.
 
-```
-A  artist
-a  album
-t  title
-D  duration
-d  date
-T  track number
-p  file path
-```
+	A  artist
+	a  album
+	t  title
+	D  duration
+	d  date
+	T  track number
+	p  file path
 
 With `-s` zuke will start in shuffled mode.
 
 ## Hot keys
 
-```
--    volume down
-+ =  volume up
+	-    volume down
+	+ =  volume up
 
-left/right                  seek backwards/forward (10 seconds step)
-, .                         seek backwards/forward (one minute step)
-up down pgup pgdn home end  move within the playlist
-o i                         move to the currently playing track
-enter                       play the selected track
+	left/right                  seek backwards/forward (10 seconds step)
+	, .                         seek backwards/forward (one minute step)
+	up down pgup pgdn home end  move within the playlist
+	o i                         move to the currently playing track
+	enter                       play the selected track
 
-> b         skip next
-< z         skip prev
-v           stop
-p c space   pause/resume
-s           toggle shuffle
-q/del       quit
+	> b         skip next
+	< z         skip prev
+	v           stop
+	p c space   pause/resume
+	s           toggle shuffle
+	q/del       quit
 
-/  search forward
-?  search backwards
-n  repeat search forward
-N  repeat search backwards
-```
+	/  search forward
+	?  search backwards
+	n  repeat search forward
+	N  repeat search backwards
 
 ## Mouse
 
-```
-left   - select a track
-right  - menu
-middle - play the track under the pointer
-```
+	left   - select a track
+	right  - menu
+	middle - play the track under the pointer
--- a/zuke.c
+++ b/zuke.c
@@ -5,6 +5,7 @@
 #include <draw.h>
 #include <mouse.h>
 #include <keyboard.h>
+#include <plumb.h>
 #include <ctype.h>
 #include "plist.h"
 #include "theme.h"
@@ -57,7 +58,7 @@
 static int scroll, scrollsz;
 static Font *f;
 static Image *cover;
-static Channel *ev;
+static Channel *playc;
 static Mousectl *mctl;
 static Keyboardctl *kctl;
 static int colwidth[7];
@@ -700,10 +701,8 @@
 	Meta *m;
 	int plsz;
 
-	plnum = 0;
-	plsz = 0;
-	pl = nil;
 	m = nil;
+	plsz = 0;
 	for(s = plraw;; s = e){
 		if((e = strchr(s, '\n')) == nil)
 			break;
@@ -750,12 +749,15 @@
 }
 
 static void
-readplist(void)
+readplist(int fd)
 {
 	Meta *m;
 	char *s, *e, *endrec;
 	int i, n, sz, alloc, tagsz, intval;
 
+	plnum = 0;
+	pl = nil;
+
 	s = nil;
 	for(alloc = sz = 0;;){
 		alloc += 65536;
@@ -762,7 +764,7 @@
 		if((s = realloc(s, alloc)) == nil)
 			sysfatal("no memory");
 		for(n = 0; sz < alloc; sz += n){
-			n = readn(0, s+sz, alloc-sz);
+			n = readn(fd, s+sz, alloc-sz);
 			if(n < 0)
 				sysfatal("%r");
 			if(n == 0)
@@ -771,7 +773,6 @@
 		if(n == 0)
 			break;
 	}
-	close(0);
 
 	plraw = s;
 	plrawsize = sz;
@@ -998,6 +999,46 @@
 }
 
 static void
+plumbaudio(void *)
+{
+	int i, f, pf;
+	Plumbmsg *m;
+	char *s, *e;
+
+	threadsetname("audio/plumb");
+	if((f = plumbopen("audio", OREAD)) >= 0){
+		while((m = plumbrecv(f)) != nil){
+			s = m->data;
+			if(*s != '/' && m->wdir != nil)
+				s = smprint("%s/%s", m->wdir, m->data);
+
+			if((e = strrchr(s, '.')) != nil && strcmp(e, ".plist") == 0 && (pf = open(s, OREAD)) >= 0){
+				stop(playercurr);
+				free(pl);
+				free(plraw);
+				plnum = 0;
+				readplist(pf);
+				close(pf);
+				sendul(playc, 0);
+			}else{
+				for(i = 0; i < plnum; i++){
+					if(strcmp(pl[i].path, s) == 0){
+						sendul(playc, i);
+						break;
+					}
+				}
+			}
+
+			if(s != m->data)
+				free(s);
+			plumbfree(m);
+		}
+	}
+
+	threadexits(nil);
+}
+
+static void
 usage(void)
 {
 	fprint(2, "usage: %s [-s] [-G] [-c aAdDtTp]\n", argv0);
@@ -1009,11 +1050,13 @@
 {
 	Rune key;
 	Mouse m;
+	ulong ind;
 	Alt a[] =
 	{
 		{ nil, &m, CHANRCV },
 		{ nil, nil, CHANRCV },
 		{ nil, &key, CHANRCV },
+		{ nil, &ind, CHANRCV },
 		{ nil, nil, CHANEND },
 	};
 	int n, scrolling, oldpcur, oldbuttons, pnew, shuffled, themetid, nogui;
@@ -1040,7 +1083,8 @@
 		break;
 	}ARGEND;
 
-	readplist();
+	readplist(0);
+	close(0);
 	if(plnum < 1){
 		fprint(2, "empty playlist\n");
 		sysfatal("empty");
@@ -1068,6 +1112,8 @@
 	a[0].c = mctl->c;
 	a[1].c = mctl->resizec;
 	a[2].c = kctl->c;
+	a[3].c = chancreate(sizeof(ind), 0);
+	playc = a[3].c;
 
 	srand(time(0));
 	pcurplaying = -1;
@@ -1087,6 +1133,8 @@
 	scrolling = 0;
 	themetid = -1;
 
+	proccreate(plumbaudio, nil, 4096);
+
 	for(;;){
 ev:
 		oldpcur = pcur;
@@ -1206,6 +1254,7 @@
 				pcur = 0;
 				break;
 			case '\n':
+playcur:
 				stop(playercurr);
 				playercurr = newplayer(pcur, 1);
 				start(playercurr);
@@ -1279,6 +1328,10 @@
 				search(key);
 				break;
 			}
+			break;
+		case 3:
+			pcur = ind;
+			goto playcur;
 		}
 
 		if(pcur != oldpcur){