shithub: zuke

Download patch

ref: d074aa0d3c51d95dc943a50cf82623f680c99c16
parent: d24b93d9572b1272e0649468789458358656c7d0
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Jun 9 12:10:51 EDT 2020

add livestreams support

--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@
  * seeking
  * playlists
  * good metadata support
+ * basic livestreams support
 
 ## Installing
 
@@ -22,7 +23,7 @@
 that are then fed to `audio/zuke`'s stdin:
 
 ```
-% audio/mkplist /n/somefs/mymusic > $home/somefs.plist
+% audio/mkplist /n/somefs/mymusic /n/otherfs/moremusic http://83.137.145.141:14280 > $home/somefs.plist
 % audio/zuke < $home/somefs.plist
 ```
 
--- a/mkplist.c
+++ b/mkplist.c
@@ -295,8 +295,16 @@
 	}
 
 	for(i = 1; i < argc; i++){
-		dir = strdup(argv[i]);
-		scan(&dir, 0);
+		if(strncmp(argv[i], "http://", 7) == 0 || strncmp(argv[i], "https://", 8) == 0){
+			if((curr = newmeta()) == nil)
+				sysfatal("no memory");
+			curr->title = argv[i];
+			curr->path = argv[i];
+			curr->filefmt = "";
+		}else{
+			dir = strdup(argv[i]);
+			scan(&dir, 0);
+		}
 	}
 	qsort(all, numall, sizeof(Meta), cmpmeta);
 	print("# %d\n", numall);
--- a/zuke.c
+++ b/zuke.c
@@ -243,9 +243,20 @@
 		}
 	}
 
-	if(pcurplaying >= 0)
-		snprint(tmp, sizeof(tmp), "%s%P/%P %d%%", shuffle != nil ? "∫ " : "", (int)(byteswritten/Bps), getmeta(pcurplaying)->duration/1000, volume);
-	else
+	if(pcurplaying >= 0){
+		if(getmeta(pcurplaying)->duration != 0){
+			snprint(tmp, sizeof(tmp), "%s%P/%P %d%%",
+				shuffle != nil ? "∫ " : "",
+				(int)(byteswritten/Bps),
+				getmeta(pcurplaying)->duration/1000,
+				volume);
+		}else{
+			snprint(tmp, sizeof(tmp), "%s%P %d%%",
+				shuffle != nil ? "∫ " : "",
+				(int)(byteswritten/Bps),
+				volume);
+		}
+	}else
 		snprint(tmp, sizeof(tmp), "%s%d%%", shuffle != nil ? "∫ " : "", volume);
 	r = screen->r;
 	r.min.x = r.max.x - stringwidth(f, tmp) - 4;
@@ -413,8 +424,10 @@
 static int
 openaudio(int audio)
 {
-	while(audio < 0 && (audio = open("/dev/audio", OWRITE)) < 0)
+	while(audio < 0 && (audio = open("/dev/audio", OWRITE)) < 0){
+		fprint(2, "audio busy\n");
 		sleep(1000);
+	}
 
 	return audio;
 }
@@ -422,7 +435,7 @@
 static void
 playerthread(void *player_)
 {
-	char *buf, cmd[32];
+	char *buf, cmd[256], *fmt;
 	Player *player;
 	Ioproc *io;
 	Image *thiscover;
@@ -430,6 +443,7 @@
 	int p[2], fd, pid, n, got, noinit, trycoverload;
 	u64int bytesfrom, bf;
 	int audio;
+	Meta *cur;
 
 	threadsetname("player");
 	player = player_;
@@ -443,7 +457,10 @@
 	audio = -1;
 
 restart:
-	if((fd = open(getmeta(player->pcur)->path, OREAD)) < 0){
+	cur = getmeta(player->pcur);
+	fmt = cur->filefmt;
+	fd = -1;
+	if(*fmt && (fd = open(cur->path, OREAD)) < 0){
 		fprint(2, "%r\n");
 		sendul(player->ev, Everror);
 		goto freeplayer;
@@ -451,17 +468,24 @@
 
 	pipe(p);
 	if((pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
-		dup(p[0], 1); close(p[0]);
+		if(fd < 0)
+			fd = open("/dev/null", OREAD);
 		dup(fd, 0); close(fd);
-		dup(open("/dev/null", OWRITE), 2);
+		dup(p[0], 1); close(p[0]);
+		dup(fd = open("/dev/null", OWRITE), 2); close(fd);
 		close(p[1]);
-		snprint(cmd, sizeof(cmd), "/bin/audio/%sdec", getmeta(player->pcur)->filefmt);
-		execl(cmd, cmd, nil);
+		if(*fmt){
+			snprint(cmd, sizeof(cmd), "/bin/audio/%sdec", fmt);
+			execl(cmd, cmd, nil);
+		}else{
+			execl("/bin/play", "play", "-o", "/fd/1", cur->path, nil);
+		}
 		sysfatal("execl: %r");
 	}
 	if(pid < 0)
 		sysfatal("rfork: %r");
-	close(fd);
+	if(fd >= 0)
+		close(fd);
 	close(p[0]);
 
 	byteswritten = 0;
@@ -560,6 +584,8 @@
 			start(playercurr);
 			goto stop;
 		}
+		close(audio);
+		audio = -1;
 		goto restart;
 	}