From 47ced886fbd41a35d275526e18164aaa71202bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Sat, 24 Oct 2020 19:57:00 +0200 Subject: release 2.0 --- CHANGELOG.txt | 8 +++++ watch.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ watch.cmd | 18 ----------- watch.exe | Bin 0 -> 69120 bytes watch.js | 42 ++++++++++++++++++++++++ watch.obj | Bin 0 -> 4196 bytes watch.reg | 12 +++++++ 7 files changed, 163 insertions(+), 18 deletions(-) create mode 100644 CHANGELOG.txt create mode 100644 watch.c delete mode 100644 watch.cmd create mode 100644 watch.exe create mode 100644 watch.js create mode 100644 watch.obj create mode 100644 watch.reg diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..24c31de --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,8 @@ +CHANGELOG ----------------------- 2.0 ---------------------- 2020-06-03 + +NEW: Rewrote main program in C. +NEW: Playlist support. +FIX: Removed requirement for separate video and audio streams. As such, + most sites are now supported, although some YouTube videos still + fail. +NEW: Rewrote bookmarklet (see watch.js). \ No newline at end of file diff --git a/watch.c b/watch.c new file mode 100644 index 0000000..9d9169c --- /dev/null +++ b/watch.c @@ -0,0 +1,101 @@ +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) +#error Systems other than Windows are not supported. +#endif + +#include +#include +#pragma comment(lib, "Shell32") +#include +#pragma comment(lib, "Shlwapi.lib") + +#include + +#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 MAX_PATH 260 +#define SR_ERR_NOASSOC (HINSTANCE)31 +#define USAGE "usage: %s URL\n", argv[0] + +int main(int argc, char *argv[]) { + bool new; + char *cmd, out[MAX_PATH], temp[MAX_PATH]; + FILE *f, *p; + HINSTANCE r; + int c, i, linecount; + ULONGLONG last; + + /* construct temporary playlist file path */ + + if (GetTempPath(1 + MAX_PATH, temp) > 0 && strlen(temp) + 1 + 16 <= MAX_PATH) { + strcpy(out, temp); + if (temp[strlen(temp)-1] != '\\') strcat(out, "\\"); + } + strcat(out, "watch.tmp.mpcpl"); + + if (argc == 1) goto open; /* open previous link */ + if (argc > 2) die(USAGE); + + if (strncmp(argv[1], "watch:", 6) == 0) /* support watch: urls */ + argv[1] += 6; + + for (i = 0; i < strlen(argv[1]); i++) + if (argv[1][i] == '"') die("URL cannot contain quotes (\")\n"); + + /* start youtube-dl */ + + cmd = malloc(sizeof("youtube-dl -g \"\"") + strlen(argv[1]) * sizeof(char)); + if (cmd == NULL) err(1, "malloc"); + if (sprintf(cmd, "youtube-dl -g \"%s\"", argv[1]) < 0) err(1, "sprintf"); + + p = _popen(cmd, "r"); + if (p == NULL) err(1, "popen"); + + /* open temporary playlist file */ + + f = fopen(out, "w"); + if (f == NULL) err(1, "fopen"); + + /* read/write stream urls */ + + linecount = 0; + new = true; + last = GetTickCount(); + + c = fgetc(p); + if (c == EOF) goto end; + fprintf(f, "MPCPLAYLIST\n"); + goto loop; + + while ((c = fgetc(p)) != EOF) { +loop: + if (new) { + /* if new line immediately follows last one, it is only audio */ + if (GetTickCount() - last > 20) { + fprintf(stderr, "Retrieved video #%d\n", linecount); + linecount++; + fprintf(f, "%d,type,0\n", linecount); + } + fprintf(f, "%d,filename,", linecount, linecount); + new = false; + } + fputc(c, f); + if (c == '\n') { + last = GetTickCount(); + new = true; + } + } + +end: + if (i = _pclose(p)) + 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.cmd b/watch.cmd deleted file mode 100644 index 1c7ea1b..0000000 --- a/watch.cmd +++ /dev/null @@ -1,18 +0,0 @@ -@echo off -set url=%* -set url=%url:watch:=% - -youtube-dl -j %url% > %TEMP%\youtubejson - -type %TEMP%\youtubejson ^ - | jq ".formats[] | select(.ext == """mp4""") | {width, url}"^ - | jq -sr "sort_by(.width) | .[-1].url"^ - > %TEMP%\youtubevideo - -type %TEMP%\youtubejson^ - | jq ".formats[] | select(.ext == """m4a""") | {url}" | jq -sr ".[-1].url"^ - > %TEMP%\youtubeaudio - -for /f %%v in (%TEMP%\youtubevideo) ^ -do for /f %%a in (%TEMP%\youtubeaudio) ^ -do start "" "%ProgramFiles%\MPC-HC\mpc-hc" "%%v" /dub "%%a" \ No newline at end of file diff --git a/watch.exe b/watch.exe new file mode 100644 index 0000000..d5de636 Binary files /dev/null and b/watch.exe differ diff --git a/watch.js b/watch.js new file mode 100644 index 0000000..be0c7ef --- /dev/null +++ b/watch.js @@ -0,0 +1,42 @@ +/* This is a bookmarklet. Copy it to a bookmark in your web browser and + add javascript: in front of it. */ + +var watch = function () { + if (window.watchclicked == undefined) + window.watchclicked = 0; + if (window.watchlasttime == undefined) + window.watchlasttime = 0; + var vid = function (href) { + return 'watch:' + href.replace(/(https?:\/?\/?www\.youtube\.com\/watch.*)&list=.*$/,'$1'); + }; + var reset = function () { + window.watchclicked = 0; + Array.from(document.getElementsByTagName('a')).forEach(function (el) { + el.onclick = undefined; + el.style.cursor = el.getAttribute('data-watch-cursor-orig'); + }); + }; + var open = function (ev) { + reset(); + location.href = vid(ev.target.href); + ev.preventDefault(); + }; + var d = new Date(); + if (d.getTime() - window.watchlasttime <= 500) { /* double click */ + location.href = vid(location.href); + window.watchlasttime = d.getTime(); + return; + } + window.watchlasttime = d.getTime(); + if (window.watchclicked == 0) { + window.watchclicked = 1; + Array.from(document.getElementsByTagName('a')).forEach(function (el) { + el.onclick = open; + el.setAttribute('data-watch-cursor-orig', el.style.cursor); + el.style.setProperty('cursor', 'alias', 'important'); + }); + } else { + reset(); + } +}; +watch(); diff --git a/watch.obj b/watch.obj new file mode 100644 index 0000000..2f5208c Binary files /dev/null and b/watch.obj differ diff --git a/watch.reg b/watch.reg new file mode 100644 index 0000000..97e1652 --- /dev/null +++ b/watch.reg @@ -0,0 +1,12 @@ +REGEDIT4 + +[HKEY_CLASSES_ROOT\watch] +@="URL:watch Protocol" +"URL Protocol"="" + +[HKEY_CLASSES_ROOT\watch\shell] + +[HKEY_CLASSES_ROOT\watch\shell\open] + +[HKEY_CLASSES_ROOT\watch\shell\open\command] +@="\"C:\\watch.exe\" \"%1\"" -- cgit v1.2.3