aboutsummaryrefslogtreecommitdiff
path: root/watch.c
diff options
context:
space:
mode:
Diffstat (limited to 'watch.c')
-rw-r--r--watch.c72
1 files changed, 52 insertions, 20 deletions
diff --git a/watch.c b/watch.c
index 09cc154..9f097d2 100644
--- a/watch.c
+++ b/watch.c
@@ -2,6 +2,8 @@
#error Systems other than Windows are not supported.
#endif
+/* libraries */
+
#include <windows.h>
#include <signal.h>
@@ -12,28 +14,39 @@
#include <stdio.h>
+/* convenience macros */
+
#define err(code, string) do { fprintf(stderr, "%s: %s: %s\n", string, strerror(errno)); exit(code); } while (0)
#define die(...) do { fprintf(stderr, __VA_ARGS__); system("pause"); exit(1); } while (0)
#define bool int
#define true 1
#define false 0
+#define USAGE "usage: %s [/c argument-string] URL\n", argv[0]
+
+/* constants */
#define MAX_PATH 260
#define SR_ERR_NOASSOC (HINSTANCE)31
-#define USAGE "usage: %s [/c argument-string] URL\n", argv[0]
-char out[MAX_PATH];
+/* global variables */
+
+char out[MAX_PATH]; /* temporary playlist file path */
+
+/* handle break signal (Ctrl-Break) */
void sigbreak(int sig) {
- /* open playlist */
+ /* open playlist at break signal */
if (ShellExecute(NULL, "open", out, NULL, NULL, 5) <= (HINSTANCE)32)
die("failed to open %s\n", out);
exit(0);
}
+/* main interface */
+
int main(int argc, char *argv[]) {
bool new, title;
char *cmd, *extra, temp[MAX_PATH], *url;
+ const char *fmt;
FILE *f, *p;
HINSTANCE r;
int c, i, linecount;
@@ -48,6 +61,8 @@ int main(int argc, char *argv[]) {
if (temp[strlen(temp)-1] != '\\') strcat(out, "\\");
}
strcat(out, "watch.tmp.mpcpl");
+
+ /* parse command-line flags and set default parameters */
if (argc == 1) goto open; /* open previous link */
@@ -57,27 +72,36 @@ int main(int argc, char *argv[]) {
url = argv[3];
} else {
if (argc != 2) die(USAGE);
- extra = NULL;
+ extra = "-f \"bestvideo[height<=1200],bestaudio/best\"";
url = argv[1];
}
-
- if (strncmp(url, "watch:", 6) == 0) /* support watch: urls */
+
+ /* support watch: urls */
+
+ if (strncmp(url, "watch:", 6) == 0)
url += 6;
+
+ /* support cloudtube urls */
+
+ if (strncmp(url, "https://cadence.moe/cloudtube/video/", 36) == 0) {
+ url += 36 - 28;
+ memcpy(url, "https://youtube.com/watch?v=", 28);
+ } else if (strncmp(url, "https://cadence.moe/cloudtube/", 30) == 0) {
+ url += 30 - 20;
+ memcpy(url, "https://youtube.com/", 20);
+ }
+
+ /* validate url format */
for (i = 0; i < strlen(url); i++)
if (url[i] == '"') die("URL cannot contain quotes (\")\n");
/* start youtube-dl */
- if (extra != NULL) {
- cmd = malloc(sizeof("youtube-dl -eg --youtube-skip-dash-manifest \"\"") + (strlen(url) + strlen(extra)) * sizeof(char));
- if (cmd == NULL) err(1, "malloc");
- if (sprintf(cmd, "youtube-dl -eg --youtube-skip-dash-manifest %s \"%s\"", extra, url) < 0) err(1, "sprintf");
- } else {
- cmd = malloc(sizeof("youtube-dl -eg --youtube-skip-dash-manifest \"\"") + strlen(url) * sizeof(char));
- if (cmd == NULL) err(1, "malloc");
- if (sprintf(cmd, "youtube-dl -eg --youtube-skip-dash-manifest \"%s\"", url) < 0) err(1, "sprintf");
- }
+ fmt = "youtube-dl -eg --youtube-skip-dash-manifest %s \"%s\"";
+ cmd = malloc(0 + (strlen(fmt) + strlen(url) + strlen(extra)) * sizeof(char));
+ if (cmd == NULL) err(1, "malloc");
+ if (sprintf(cmd, fmt, extra, url) < 0) err(1, "sprintf");
p = _popen(cmd, "r");
if (p == NULL) err(1, "popen");
@@ -87,7 +111,7 @@ int main(int argc, char *argv[]) {
f = fopen(out, "w");
if (f == NULL) err(1, "fopen");
- /* read/write stream urls */
+ /* read/write stream urls (from youtube-dl, to temporary playlist file) */
linecount = 0;
new = true;
@@ -98,12 +122,17 @@ int main(int argc, char *argv[]) {
if (c == EOF) goto end;
fprintf(f, "MPCPLAYLIST\n");
goto loop;
+
+ /* In the output from youtube-dl, each line contains a video or audio stream
+ * belonging to a specific video. The only way to tell which streams belong
+ * to the same video is to count the time between the output of each line. If
+ * there is a pause between two lines, then the second one belongs to a new
+ * video. */
while ((c = fgetc(p)) != EOF) {
loop:
if (new) {
new = false;
- /* if new line immediately follows last one, it belongs to the same video */
if (GetTickCount() - last > 20) { /* new video */
title = true;
linecount++;
@@ -119,15 +148,18 @@ loop:
new = true;
}
}
+
+ /* check status of youtube-dl command */
end:
- if (i = _pclose(p))
- if (i != -1073741510) /* Ctrl-Break */
+ if (i = _pclose(p)) /* if unsuccessful */
+ if (i != -1073741510) /* and it wasn't due to Ctrl-Break (handled above) */
die("youtube-dl exited with %d\n", i);
/* open playlist */
+
open:
if (ShellExecute(NULL, "open", out, NULL, NULL, 5) <= (HINSTANCE)32)
die("failed to open %s\n", out);
return 0;
-} \ No newline at end of file
+}