aboutsummaryrefslogtreecommitdiff
path: root/watch.c
blob: b731062ce8a853f7e738848a8485e16d42fd44d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32)
#error Systems other than Windows are not supported.
#endif

#include <windows.h>
#include <signal.h>

#include <shellapi.h>
#pragma comment(lib, "Shell32")
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

#include <stdio.h>

#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]

char out[MAX_PATH];

void sigbreak(int sig) {
  /* open playlist */
  if (ShellExecute(NULL, "open", out, NULL, NULL, 5) <= (HINSTANCE)32)
    die("failed to open %s\n", out);
  exit(0);
}

int main(int argc, char *argv[]) {
  bool new, title;
  char *cmd, temp[MAX_PATH];
  FILE *f, *p;
  HINSTANCE r;
  int c, i, linecount;
  ULONGLONG last;
  
  signal(SIGBREAK, sigbreak);
  
  /* 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 -eg \"\"") + strlen(argv[1]) * sizeof(char));
  if (cmd == NULL) err(1, "malloc");
  if (sprintf(cmd, "youtube-dl -eg \"%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;
  title = false;
  last = GetTickCount();
  
  c = fgetc(p);
  if (c == EOF) goto end;
  fprintf(f, "MPCPLAYLIST\n");
  goto loop;
  
  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++;
        fprintf(stderr, "Retrieving video #%d\n", linecount);
        fprintf(f, "%d,type,0\n", linecount);
        fprintf(f, "%d,label,", linecount);
      } else
        fprintf(f, "%d,filename,", linecount);
    }
    fputc(c, f);
    if (c == '\n') {
      last = GetTickCount();
      new = true;
    }
  }
  
end:
  if (i = _pclose(p))
    if (i != -1073741510) /* Ctrl-Break */
      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;
}