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){