From 359befdfd3b45d3b9d77fc830b07eede0f2f4d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Sat, 24 Oct 2020 19:58:18 +0200 Subject: release 2.2.1 --- .gitignore | 1 + CHANGELOG.txt | 10 ++++---- watch.c | 72 ++++++++++++++++++++++++++++++++++++++++++---------------- watch.exe | Bin 70144 -> 70656 bytes watch.obj | Bin 5641 -> 0 bytes 5 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 .gitignore delete mode 100644 watch.obj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..281748d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.obj \ No newline at end of file diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f5e1b84..501b7b7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,6 @@ -CHANGELOG ----------------------- 2.2 ---------------------- 2020-06-13 +CHANGELOG --------------------- 2.2.1 ---------------------- 2020-08-02 -NEW: You can now specify custom command line parameters for youtube-dl - with the /c flag. -FIX: Now skips YouTube DASH manifest using --youtube-skip-dash-manifest - flag, as MPC-HC does not support it. \ No newline at end of file +NEW: If no extra youtube-dl options are specified via /c, then watch + will use "bestvideo[height<=1200],bestaudio/best". +NEW: Now supports cadence.moe/cloudtube URLs. +FIX: Improved code documentation. 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 #include @@ -12,28 +14,39 @@ #include +/* 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 +} diff --git a/watch.exe b/watch.exe index 7e2212f..c8c7b42 100644 Binary files a/watch.exe and b/watch.exe differ diff --git a/watch.obj b/watch.obj deleted file mode 100644 index 8320f55..0000000 Binary files a/watch.obj and /dev/null differ -- cgit v1.2.3