ani-cli-npm 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/ani-cli-npm.iml +11 -11
- package/.idea/discord.xml +6 -6
- package/.idea/jsLibraryMappings.xml +5 -5
- package/.idea/modules.xml +7 -7
- package/.idea/vcs.xml +5 -5
- package/README.MD +77 -77
- package/bin/Anime.js +393 -393
- package/bin/core_utils/curl.js +35 -35
- package/bin/core_utils/interfaces.js +2 -2
- package/bin/core_utils/libs.js +12 -12
- package/bin/core_utils/regex.js +8 -8
- package/bin/download.js +36 -36
- package/bin/file_managment/cache.js +87 -87
- package/bin/file_managment/change_config.js +121 -121
- package/bin/file_managment/load_config.js +110 -110
- package/bin/generate_link.js +47 -47
- package/bin/help.js +59 -59
- package/bin/index.js +159 -159
- package/bin/input.js +89 -89
- package/bin/search_anime.js +39 -39
- package/package.json +45 -45
- package/tsconfig.json +109 -109
- package/.idea/git_toolbox_prj.xml +0 -15
- package/.idea/inspectionProfiles/Project_Default.xml +0 -10
- package/bin/cache.js +0 -79
- package/bin/change_config.js +0 -99
- package/bin/curl.js +0 -35
- package/bin/interfaces.js +0 -2
- package/bin/libs.js +0 -12
- package/bin/load_config.js +0 -106
- package/bin/regex.js +0 -8
- package/bin/video_quality.js +0 -6
package/bin/Anime.js
CHANGED
@@ -1,393 +1,393 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.Anime = void 0;
|
4
|
-
const curl_1 = require("./core_utils/curl");
|
5
|
-
const regex_1 = require("./core_utils/regex");
|
6
|
-
const generate_link_1 = require("./generate_link");
|
7
|
-
const cache_1 = require("./file_managment/cache");
|
8
|
-
const input_1 = require("./input");
|
9
|
-
const load_config_1 = require("./file_managment/load_config");
|
10
|
-
const W2GClient = require("w2g-client");
|
11
|
-
const open = require("open");
|
12
|
-
const PlayerController = require("media-player-controller");
|
13
|
-
const dl = require("download-file-with-progressbar");
|
14
|
-
const chalk = require("chalk");
|
15
|
-
class Anime {
|
16
|
-
/*
|
17
|
-
Class for handling a show/film
|
18
|
-
|
19
|
-
Stores anime dpage links assigned with anime_id.
|
20
|
-
|
21
|
-
Initialised with Anime.init()
|
22
|
-
|
23
|
-
*/
|
24
|
-
id = "";
|
25
|
-
episode_list = [];
|
26
|
-
most_recent = 0;
|
27
|
-
player = new class {
|
28
|
-
play(episode_link) {
|
29
|
-
return {};
|
30
|
-
}
|
31
|
-
player;
|
32
|
-
};
|
33
|
-
current_pos = 0;
|
34
|
-
current_episode = 0;
|
35
|
-
async init(anime_id, cache_folder) {
|
36
|
-
/*
|
37
|
-
Initiate Anime object
|
38
|
-
|
39
|
-
Will first search cache folder for cache file (this will contain id and dpage links)
|
40
|
-
|
41
|
-
If no cache is found, it will use get_ep_bases(anime_id) to get links. (Webscrapes from animixplay.to), then creates cache
|
42
|
-
|
43
|
-
anime_id:
|
44
|
-
*/
|
45
|
-
let cache_object = (0, cache_1.search_cache)(cache_folder, anime_id);
|
46
|
-
this.id = anime_id;
|
47
|
-
if (cache_object == 0) {
|
48
|
-
await this.get_ep_bases(this.id);
|
49
|
-
(0, cache_1.new_cache)(cache_folder, {
|
50
|
-
id: this.id,
|
51
|
-
episode_list: this.episode_list,
|
52
|
-
most_recent: this.most_recent
|
53
|
-
});
|
54
|
-
}
|
55
|
-
else {
|
56
|
-
try {
|
57
|
-
this.episode_list = cache_object.episode_list;
|
58
|
-
if (cache_object.most_recent != undefined) {
|
59
|
-
this.most_recent = cache_object.most_recent;
|
60
|
-
}
|
61
|
-
if (cache_object.position != undefined) {
|
62
|
-
this.current_pos = cache_object.position;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
catch {
|
66
|
-
await this.get_ep_bases(this.id);
|
67
|
-
}
|
68
|
-
}
|
69
|
-
(0, cache_1.new_cache)(cache_folder, {
|
70
|
-
id: this.id,
|
71
|
-
episode_list: this.episode_list,
|
72
|
-
most_recent: this.most_recent
|
73
|
-
});
|
74
|
-
return 0;
|
75
|
-
}
|
76
|
-
async get_episode_link(episode, player = "VLC") {
|
77
|
-
let episode_dpage = this.episode_list[episode];
|
78
|
-
let id = episode_dpage.replace("//gogohd.
|
79
|
-
id = id.slice(0, id.indexOf("="));
|
80
|
-
let link = await (0, generate_link_1.generate_link)(1, id, player);
|
81
|
-
if (!link) {
|
82
|
-
link = await (0, generate_link_1.generate_link)(2, id, player);
|
83
|
-
}
|
84
|
-
if (!link) {
|
85
|
-
console.log(chalk.red("Failed to generate links"));
|
86
|
-
}
|
87
|
-
if (player == "VLC" && link.includes("m3u8")) {
|
88
|
-
console.log(chalk.red("Warning; VLC is not compatible with m3u8 playlist files without custom plugins."));
|
89
|
-
}
|
90
|
-
return link;
|
91
|
-
}
|
92
|
-
async get_ep_bases(anime_id) {
|
93
|
-
/*
|
94
|
-
Scrapes animixplay.to for dpage links.
|
95
|
-
returns array with all dpage links
|
96
|
-
*/
|
97
|
-
let html = (await ((0, curl_1.curl)("https://animixplay.to/v1/" + anime_id))).split("\n"); //POTENTIAL BREAK POINT. animixplay.to may change domain address
|
98
|
-
let lines = "";
|
99
|
-
for (let x in html) {
|
100
|
-
if ((0, regex_1.RegexParse)(html[x], "*<div id=\"epslistplace\"*")) {
|
101
|
-
lines = (html[x]);
|
102
|
-
}
|
103
|
-
}
|
104
|
-
lines = lines.slice(55, lines.length).replace("}</div>", "");
|
105
|
-
lines = "{" + lines.slice(lines.indexOf(",") + 1, lines.length) + "}";
|
106
|
-
let json = JSON.parse(lines);
|
107
|
-
for (const value of Object.entries(json)) {
|
108
|
-
if (typeof value[1] == "string") {
|
109
|
-
this.episode_list.push(value[1].replace("//gogohd.
|
110
|
-
}
|
111
|
-
}
|
112
|
-
}
|
113
|
-
async play_head(episode, config, config_dir) {
|
114
|
-
/*
|
115
|
-
# Starts play cascade.
|
116
|
-
|
117
|
-
## Takes in:
|
118
|
-
### Episode number, counting from 0
|
119
|
-
### Config object
|
120
|
-
### Config save directory
|
121
|
-
|
122
|
-
- If config.player is set to MPV or VLC, it will use the media-player-controller package.
|
123
|
-
|
124
|
-
- If set to Browser, it will use the "open" packer.
|
125
|
-
|
126
|
-
- If set to Link, it will simply print the media stream link to console, primarily for debuting peruses.
|
127
|
-
*/
|
128
|
-
console.clear();
|
129
|
-
console.log(`Playing ${this.id} episode ${episode + 1}`); // from ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`)
|
130
|
-
if (this.current_pos != 0) {
|
131
|
-
console.log(`Most recent position: ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`);
|
132
|
-
}
|
133
|
-
switch (config.player) {
|
134
|
-
case "MPV":
|
135
|
-
console.log(("Opening MPV.."));
|
136
|
-
this.player.player = await new PlayerController({
|
137
|
-
app: 'mpv',
|
138
|
-
args: ['--fullscreen', '--keep-open=yes'],
|
139
|
-
media: await this.get_episode_link(episode, config.player),
|
140
|
-
ipcPath: config.mpv_socket_path
|
141
|
-
});
|
142
|
-
this.player.play = (async (episode_link) => {
|
143
|
-
this.player.player.load(episode_link);
|
144
|
-
});
|
145
|
-
this.player.player.on('playback', (data) => {
|
146
|
-
if (data.name == "time-pos" && data.value >= 0) {
|
147
|
-
this.current_pos = data.value;
|
148
|
-
}
|
149
|
-
//console.log(data)
|
150
|
-
});
|
151
|
-
this.player.player.on('app-exit', (code) => {
|
152
|
-
config.most_recent.anime_id = this.id;
|
153
|
-
config.most_recent.episode_number = episode;
|
154
|
-
config.most_recent.episode_second = this.current_pos;
|
155
|
-
(0, load_config_1.write_config)(config_dir, config);
|
156
|
-
this.most_recent = episode;
|
157
|
-
(0, cache_1.new_cache)(config_dir, {
|
158
|
-
id: this.id,
|
159
|
-
episode_list: this.episode_list,
|
160
|
-
most_recent: this.most_recent,
|
161
|
-
position: this.current_pos
|
162
|
-
});
|
163
|
-
});
|
164
|
-
// @ts-ignore
|
165
|
-
await this.player.player.launch(err => {
|
166
|
-
if (err)
|
167
|
-
return console.error(err.message);
|
168
|
-
});
|
169
|
-
break;
|
170
|
-
case "VLC":
|
171
|
-
console.log(("Opening VLC.."));
|
172
|
-
this.player.player = await new PlayerController({
|
173
|
-
app: 'vlc',
|
174
|
-
args: ['--fullscreen'],
|
175
|
-
media: await this.get_episode_link(episode, config.player),
|
176
|
-
//httpPort: (config.vlc_socket !== 0)? config.vlc_socket : null,
|
177
|
-
//httpPass: (config.vlc_pass !== "")? config.vlc_socket : null,
|
178
|
-
});
|
179
|
-
// @ts-ignore
|
180
|
-
await this.player.player.launch(err => {
|
181
|
-
if (err)
|
182
|
-
return console.error(err.message);
|
183
|
-
});
|
184
|
-
this.player.play = (async (episode_link) => {
|
185
|
-
this.player.player.quit();
|
186
|
-
this.player.player = await new PlayerController({
|
187
|
-
app: 'vlc',
|
188
|
-
args: ['--fullscreen'],
|
189
|
-
media: episode_link
|
190
|
-
//httpPort: (config.vlc_socket !== 0)? config.vlc_socket : null,
|
191
|
-
//httpPass: (config.vlc_pass !== "")? config.vlc_socket : null,
|
192
|
-
});
|
193
|
-
this.player.player.on('playback', (data) => {
|
194
|
-
if (data.name == "time-pos" && data.value >= 0) {
|
195
|
-
this.current_pos = data.value;
|
196
|
-
}
|
197
|
-
//console.log(data)
|
198
|
-
});
|
199
|
-
this.player.player.on('app-exit', (code) => {
|
200
|
-
config.most_recent.anime_id = this.id;
|
201
|
-
config.most_recent.episode_number = episode;
|
202
|
-
config.most_recent.episode_second = this.current_pos;
|
203
|
-
(0, load_config_1.write_config)(config_dir, config);
|
204
|
-
this.most_recent = episode;
|
205
|
-
(0, cache_1.new_cache)(config_dir, {
|
206
|
-
id: this.id,
|
207
|
-
episode_list: this.episode_list,
|
208
|
-
most_recent: this.most_recent,
|
209
|
-
position: this.current_pos
|
210
|
-
});
|
211
|
-
});
|
212
|
-
// @ts-ignore
|
213
|
-
await this.player.player.launch(err => {
|
214
|
-
if (err)
|
215
|
-
return console.error(err.message);
|
216
|
-
});
|
217
|
-
});
|
218
|
-
break;
|
219
|
-
case "BROWSER":
|
220
|
-
this.player.play = (async (episode_link) => {
|
221
|
-
console.log(("Opening browser..."));
|
222
|
-
await open(episode_link);
|
223
|
-
});
|
224
|
-
console.log(("Opening browser..."));
|
225
|
-
await open(await this.get_episode_link(episode, config.player));
|
226
|
-
break;
|
227
|
-
case "W2G":
|
228
|
-
try {
|
229
|
-
this.player.player = new W2GClient.W2GClient(config.w2g_api_key);
|
230
|
-
await this.player.player.create(await this.get_episode_link(episode, config.player));
|
231
|
-
console.log(chalk.green("Room link: " + await this.player.player.getLink()));
|
232
|
-
}
|
233
|
-
catch {
|
234
|
-
console.log(chalk.red("Failed to create w2g.tv room. \nthis can often be because your API token is invalid. You can change it in options."));
|
235
|
-
process.exit();
|
236
|
-
}
|
237
|
-
this.player.play = (async (episode_link) => {
|
238
|
-
console.log(("Updating W2G room..."));
|
239
|
-
console.log(chalk.green("Room link: " + await this.player.player.getLink()));
|
240
|
-
try {
|
241
|
-
await this.player.player.update(episode_link);
|
242
|
-
}
|
243
|
-
catch {
|
244
|
-
console.log(chalk.red("Error updating W2G room. Very sorry, w2g functionality is a bit broken at present. Worst case you should be able to just restart with a new room for each episode."));
|
245
|
-
}
|
246
|
-
});
|
247
|
-
console.log("Opening W2G.tv...");
|
248
|
-
await open(await this.player.player.getLink());
|
249
|
-
break;
|
250
|
-
case "LINK":
|
251
|
-
this.player.play = (async (episode_link) => {
|
252
|
-
console.log(chalk.green(episode_link));
|
253
|
-
});
|
254
|
-
this.player.play(await this.get_episode_link(episode));
|
255
|
-
break;
|
256
|
-
}
|
257
|
-
await this.play_controller(episode, config, config_dir, true);
|
258
|
-
}
|
259
|
-
async next(player) {
|
260
|
-
this.current_episode += 1;
|
261
|
-
this.current_pos = 0;
|
262
|
-
this.player.play(await this.get_episode_link(this.current_episode, player));
|
263
|
-
}
|
264
|
-
async previous(player) {
|
265
|
-
this.current_episode -= 1;
|
266
|
-
this.current_pos = 0;
|
267
|
-
this.player.play(await this.get_episode_link(this.current_episode, player));
|
268
|
-
}
|
269
|
-
async play_controller(episode, config, config_dir, first = false) {
|
270
|
-
console.log(`Playing ${this.id} episode ${episode + 1}`); // from ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`)
|
271
|
-
// if (!first){
|
272
|
-
// console.clear()
|
273
|
-
// console.log(chalk.blue(`Playing ${this.id} episode ${episode+1}`))
|
274
|
-
// if (this.player == 0){
|
275
|
-
// await open(await this.get_episode_link(episode, "BROWSER"))
|
276
|
-
// }else if(this.player == 1){
|
277
|
-
// console.log(await this.get_episode_link(episode))
|
278
|
-
// } else if (this.player.roomID != undefined){
|
279
|
-
// console.log(chalk.green("Room link: "+ await this.player.getLink()));
|
280
|
-
// this.player.update(await this.get_episode_link(episode))
|
281
|
-
// } else if (this.player.opts.app == "mpv"){
|
282
|
-
// await this.player.load(await this.get_episode_link(episode))
|
283
|
-
// }else{
|
284
|
-
// this.player.quit()
|
285
|
-
// this.player = await new PlayerController({
|
286
|
-
// app: 'vlc',
|
287
|
-
// args: ['--fullscreen'],
|
288
|
-
// media: await this.get_episode_link(episode, config.player)
|
289
|
-
// });
|
290
|
-
// // @ts-ignore
|
291
|
-
// await this.player.launch(err => {
|
292
|
-
// if (err) return console.error(err.message);
|
293
|
-
// });
|
294
|
-
// }
|
295
|
-
// }
|
296
|
-
this.current_episode = episode;
|
297
|
-
config.most_recent.anime_id = this.id;
|
298
|
-
config.most_recent.episode_number = episode;
|
299
|
-
config.most_recent.episode_second = this.current_pos;
|
300
|
-
(0, load_config_1.write_config)(config_dir, config);
|
301
|
-
this.most_recent = episode;
|
302
|
-
(0, cache_1.new_cache)(config_dir, {
|
303
|
-
id: this.id,
|
304
|
-
episode_list: this.episode_list,
|
305
|
-
most_recent: this.most_recent,
|
306
|
-
position: this.current_pos
|
307
|
-
});
|
308
|
-
let selected; // Look, I'm sorry, but there is no way I can possibly document this in a sane way. It's a dumb patch.
|
309
|
-
do {
|
310
|
-
selected = await (0, input_1.selection)((episode <= 0) ? [chalk.yellow("1/n) Next"), chalk.grey("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
|
311
|
-
(episode >= this.episode_list.length - 1) ? [chalk.grey("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
|
312
|
-
[chalk.yellow("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")], ["n", "p", "s", "q"], ((thing) => { return (thing); }), ((thing) => { return (thing); }), true);
|
313
|
-
if (!(selected != ((episode <= 0) ? 1 : (episode >= this.episode_list.length - 1) ? 0 : -1))) {
|
314
|
-
console.log(chalk.red("Invalid choice."));
|
315
|
-
}
|
316
|
-
} while (!(selected != ((episode <= 0) ? 1 : (episode >= this.episode_list.length - 1) ? 0 : -1)));
|
317
|
-
switch (selected) {
|
318
|
-
case 0:
|
319
|
-
if (episode >= this.episode_list.length - 1) {
|
320
|
-
await this.next(config.player);
|
321
|
-
await this.play_controller(episode - 1, config, config_dir);
|
322
|
-
}
|
323
|
-
else {
|
324
|
-
await this.next(config.player);
|
325
|
-
await this.play_controller(episode + 1, config, config_dir);
|
326
|
-
}
|
327
|
-
break;
|
328
|
-
case 1:
|
329
|
-
if ((episode >= this.episode_list.length - 1) || (episode <= 0)) {
|
330
|
-
break;
|
331
|
-
}
|
332
|
-
await this.previous(config.player);
|
333
|
-
await this.play_controller(episode - 1, config, config_dir);
|
334
|
-
break;
|
335
|
-
case 2:
|
336
|
-
if (this.episode_list.length == 1) {
|
337
|
-
this.player.play(await this.get_episode_link(0, config.player));
|
338
|
-
await this.play_controller(0, config, config_dir);
|
339
|
-
}
|
340
|
-
else {
|
341
|
-
console.log(`Select episode [1-${this.episode_list.length}]`);
|
342
|
-
let episode = await (0, input_1.number_input)(this.episode_list.length, 1) - 1;
|
343
|
-
this.player.play(await this.get_episode_link(episode, config.player));
|
344
|
-
await this.play_controller(episode, config, config_dir);
|
345
|
-
}
|
346
|
-
break;
|
347
|
-
case 3:
|
348
|
-
break;
|
349
|
-
}
|
350
|
-
}
|
351
|
-
async download(episode, download_folder, final_ep) {
|
352
|
-
/*
|
353
|
-
## Downloads an episode (counting from 0) to download_folder, with progress bar.
|
354
|
-
*/
|
355
|
-
try {
|
356
|
-
// @ts-ignore
|
357
|
-
let ep_link = await this.get_episode_link(episode);
|
358
|
-
let file_name = `${this.id}-${episode + 1}.mp4`;
|
359
|
-
if (ep_link.includes(".m3u8"))
|
360
|
-
console.log(chalk.red("Warning: Animixplay will download an m3u8 file. This will require some extra steps to play. It is advised to use a 3rd party website or tool to download these from the link."));
|
361
|
-
// @ts-ignore
|
362
|
-
let option = {
|
363
|
-
filename: (ep_link.includes("m3u8") ? file_name.replace("mp4", "m3u8") : file_name),
|
364
|
-
dir: download_folder,
|
365
|
-
onDone: (final_ep > episode) ? ((info) => {
|
366
|
-
// @ts-ignore
|
367
|
-
console.log(chalk.green(`\n -- 1Download finished -- \nLocation: ${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
|
368
|
-
this.download(episode + 1, download_folder, final_ep);
|
369
|
-
}) : ((info) => {
|
370
|
-
// @ts-ignore
|
371
|
-
console.log(chalk.green(`\n -- 2Download finished -- \n${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
|
372
|
-
}),
|
373
|
-
// @ts-ignore
|
374
|
-
onError: (err) => {
|
375
|
-
console.log(chalk.red('error', err));
|
376
|
-
this.download(episode, download_folder, final_ep);
|
377
|
-
},
|
378
|
-
// @ts-ignore
|
379
|
-
onProgress: (curr, total) => {
|
380
|
-
process.stdout.clearLine(0);
|
381
|
-
process.stdout.cursorTo(0);
|
382
|
-
process.stdout.write("\x1b[32m -- " + (curr / total * 100).toFixed(2) + "% " + "#".repeat(Math.ceil((curr / total) * ((process.stdout.columns - 20) / 1.5))) + "~".repeat(Math.ceil(((process.stdout.columns - 20) / 1.5) - (curr / total) * ((process.stdout.columns - 20) / 1.5))) + " -- \x1b[0m");
|
383
|
-
}
|
384
|
-
};
|
385
|
-
//console.log((`${option.dir}/${option.filename}`))
|
386
|
-
return await dl(ep_link, option);
|
387
|
-
}
|
388
|
-
catch {
|
389
|
-
this.download(episode, download_folder, final_ep);
|
390
|
-
}
|
391
|
-
}
|
392
|
-
}
|
393
|
-
exports.Anime = Anime;
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Anime = void 0;
|
4
|
+
const curl_1 = require("./core_utils/curl");
|
5
|
+
const regex_1 = require("./core_utils/regex");
|
6
|
+
const generate_link_1 = require("./generate_link");
|
7
|
+
const cache_1 = require("./file_managment/cache");
|
8
|
+
const input_1 = require("./input");
|
9
|
+
const load_config_1 = require("./file_managment/load_config");
|
10
|
+
const W2GClient = require("w2g-client");
|
11
|
+
const open = require("open");
|
12
|
+
const PlayerController = require("media-player-controller");
|
13
|
+
const dl = require("download-file-with-progressbar");
|
14
|
+
const chalk = require("chalk");
|
15
|
+
class Anime {
|
16
|
+
/*
|
17
|
+
Class for handling a show/film
|
18
|
+
|
19
|
+
Stores anime dpage links assigned with anime_id.
|
20
|
+
|
21
|
+
Initialised with Anime.init()
|
22
|
+
|
23
|
+
*/
|
24
|
+
id = "";
|
25
|
+
episode_list = [];
|
26
|
+
most_recent = 0;
|
27
|
+
player = new class {
|
28
|
+
play(episode_link) {
|
29
|
+
return {};
|
30
|
+
}
|
31
|
+
player;
|
32
|
+
};
|
33
|
+
current_pos = 0;
|
34
|
+
current_episode = 0;
|
35
|
+
async init(anime_id, cache_folder) {
|
36
|
+
/*
|
37
|
+
Initiate Anime object
|
38
|
+
|
39
|
+
Will first search cache folder for cache file (this will contain id and dpage links)
|
40
|
+
|
41
|
+
If no cache is found, it will use get_ep_bases(anime_id) to get links. (Webscrapes from animixplay.to), then creates cache
|
42
|
+
|
43
|
+
anime_id:
|
44
|
+
*/
|
45
|
+
let cache_object = (0, cache_1.search_cache)(cache_folder, anime_id);
|
46
|
+
this.id = anime_id;
|
47
|
+
if (cache_object == 0) {
|
48
|
+
await this.get_ep_bases(this.id);
|
49
|
+
(0, cache_1.new_cache)(cache_folder, {
|
50
|
+
id: this.id,
|
51
|
+
episode_list: this.episode_list,
|
52
|
+
most_recent: this.most_recent
|
53
|
+
});
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
try {
|
57
|
+
this.episode_list = cache_object.episode_list;
|
58
|
+
if (cache_object.most_recent != undefined) {
|
59
|
+
this.most_recent = cache_object.most_recent;
|
60
|
+
}
|
61
|
+
if (cache_object.position != undefined) {
|
62
|
+
this.current_pos = cache_object.position;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
catch {
|
66
|
+
await this.get_ep_bases(this.id);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
(0, cache_1.new_cache)(cache_folder, {
|
70
|
+
id: this.id,
|
71
|
+
episode_list: this.episode_list,
|
72
|
+
most_recent: this.most_recent
|
73
|
+
});
|
74
|
+
return 0;
|
75
|
+
}
|
76
|
+
async get_episode_link(episode, player = "VLC") {
|
77
|
+
let episode_dpage = this.episode_list[episode];
|
78
|
+
let id = episode_dpage.replace("//gogohd.pro/streaming.php?id=", "");
|
79
|
+
id = id.slice(0, id.indexOf("="));
|
80
|
+
let link = await (0, generate_link_1.generate_link)(1, id, player);
|
81
|
+
if (!link) {
|
82
|
+
link = await (0, generate_link_1.generate_link)(2, id, player);
|
83
|
+
}
|
84
|
+
if (!link) {
|
85
|
+
console.log(chalk.red("Failed to generate links"));
|
86
|
+
}
|
87
|
+
if (player == "VLC" && link.includes("m3u8")) {
|
88
|
+
console.log(chalk.red("Warning; VLC is not compatible with m3u8 playlist files without custom plugins."));
|
89
|
+
}
|
90
|
+
return link;
|
91
|
+
}
|
92
|
+
async get_ep_bases(anime_id) {
|
93
|
+
/*
|
94
|
+
Scrapes animixplay.to for dpage links.
|
95
|
+
returns array with all dpage links
|
96
|
+
*/
|
97
|
+
let html = (await ((0, curl_1.curl)("https://animixplay.to/v1/" + anime_id))).split("\n"); //POTENTIAL BREAK POINT. animixplay.to may change domain address
|
98
|
+
let lines = "";
|
99
|
+
for (let x in html) {
|
100
|
+
if ((0, regex_1.RegexParse)(html[x], "*<div id=\"epslistplace\"*")) {
|
101
|
+
lines = (html[x]);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
lines = lines.slice(55, lines.length).replace("}</div>", "");
|
105
|
+
lines = "{" + lines.slice(lines.indexOf(",") + 1, lines.length) + "}";
|
106
|
+
let json = JSON.parse(lines);
|
107
|
+
for (const value of Object.entries(json)) {
|
108
|
+
if (typeof value[1] == "string") {
|
109
|
+
this.episode_list.push(value[1].replace("//gogohd.pro/streaming.php?id=", ""));
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
async play_head(episode, config, config_dir) {
|
114
|
+
/*
|
115
|
+
# Starts play cascade.
|
116
|
+
|
117
|
+
## Takes in:
|
118
|
+
### Episode number, counting from 0
|
119
|
+
### Config object
|
120
|
+
### Config save directory
|
121
|
+
|
122
|
+
- If config.player is set to MPV or VLC, it will use the media-player-controller package.
|
123
|
+
|
124
|
+
- If set to Browser, it will use the "open" packer.
|
125
|
+
|
126
|
+
- If set to Link, it will simply print the media stream link to console, primarily for debuting peruses.
|
127
|
+
*/
|
128
|
+
console.clear();
|
129
|
+
console.log(`Playing ${this.id} episode ${episode + 1}`); // from ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`)
|
130
|
+
if (this.current_pos != 0) {
|
131
|
+
console.log(`Most recent position: ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`);
|
132
|
+
}
|
133
|
+
switch (config.player) {
|
134
|
+
case "MPV":
|
135
|
+
console.log(("Opening MPV.."));
|
136
|
+
this.player.player = await new PlayerController({
|
137
|
+
app: 'mpv',
|
138
|
+
args: ['--fullscreen', '--keep-open=yes'],
|
139
|
+
media: await this.get_episode_link(episode, config.player),
|
140
|
+
ipcPath: config.mpv_socket_path
|
141
|
+
});
|
142
|
+
this.player.play = (async (episode_link) => {
|
143
|
+
this.player.player.load(episode_link);
|
144
|
+
});
|
145
|
+
this.player.player.on('playback', (data) => {
|
146
|
+
if (data.name == "time-pos" && data.value >= 0) {
|
147
|
+
this.current_pos = data.value;
|
148
|
+
}
|
149
|
+
//console.log(data)
|
150
|
+
});
|
151
|
+
this.player.player.on('app-exit', (code) => {
|
152
|
+
config.most_recent.anime_id = this.id;
|
153
|
+
config.most_recent.episode_number = episode;
|
154
|
+
config.most_recent.episode_second = this.current_pos;
|
155
|
+
(0, load_config_1.write_config)(config_dir, config);
|
156
|
+
this.most_recent = episode;
|
157
|
+
(0, cache_1.new_cache)(config_dir, {
|
158
|
+
id: this.id,
|
159
|
+
episode_list: this.episode_list,
|
160
|
+
most_recent: this.most_recent,
|
161
|
+
position: this.current_pos
|
162
|
+
});
|
163
|
+
});
|
164
|
+
// @ts-ignore
|
165
|
+
await this.player.player.launch(err => {
|
166
|
+
if (err)
|
167
|
+
return console.error(err.message);
|
168
|
+
});
|
169
|
+
break;
|
170
|
+
case "VLC":
|
171
|
+
console.log(("Opening VLC.."));
|
172
|
+
this.player.player = await new PlayerController({
|
173
|
+
app: 'vlc',
|
174
|
+
args: ['--fullscreen'],
|
175
|
+
media: await this.get_episode_link(episode, config.player),
|
176
|
+
//httpPort: (config.vlc_socket !== 0)? config.vlc_socket : null,
|
177
|
+
//httpPass: (config.vlc_pass !== "")? config.vlc_socket : null,
|
178
|
+
});
|
179
|
+
// @ts-ignore
|
180
|
+
await this.player.player.launch(err => {
|
181
|
+
if (err)
|
182
|
+
return console.error(err.message);
|
183
|
+
});
|
184
|
+
this.player.play = (async (episode_link) => {
|
185
|
+
this.player.player.quit();
|
186
|
+
this.player.player = await new PlayerController({
|
187
|
+
app: 'vlc',
|
188
|
+
args: ['--fullscreen'],
|
189
|
+
media: episode_link
|
190
|
+
//httpPort: (config.vlc_socket !== 0)? config.vlc_socket : null,
|
191
|
+
//httpPass: (config.vlc_pass !== "")? config.vlc_socket : null,
|
192
|
+
});
|
193
|
+
this.player.player.on('playback', (data) => {
|
194
|
+
if (data.name == "time-pos" && data.value >= 0) {
|
195
|
+
this.current_pos = data.value;
|
196
|
+
}
|
197
|
+
//console.log(data)
|
198
|
+
});
|
199
|
+
this.player.player.on('app-exit', (code) => {
|
200
|
+
config.most_recent.anime_id = this.id;
|
201
|
+
config.most_recent.episode_number = episode;
|
202
|
+
config.most_recent.episode_second = this.current_pos;
|
203
|
+
(0, load_config_1.write_config)(config_dir, config);
|
204
|
+
this.most_recent = episode;
|
205
|
+
(0, cache_1.new_cache)(config_dir, {
|
206
|
+
id: this.id,
|
207
|
+
episode_list: this.episode_list,
|
208
|
+
most_recent: this.most_recent,
|
209
|
+
position: this.current_pos
|
210
|
+
});
|
211
|
+
});
|
212
|
+
// @ts-ignore
|
213
|
+
await this.player.player.launch(err => {
|
214
|
+
if (err)
|
215
|
+
return console.error(err.message);
|
216
|
+
});
|
217
|
+
});
|
218
|
+
break;
|
219
|
+
case "BROWSER":
|
220
|
+
this.player.play = (async (episode_link) => {
|
221
|
+
console.log(("Opening browser..."));
|
222
|
+
await open(episode_link);
|
223
|
+
});
|
224
|
+
console.log(("Opening browser..."));
|
225
|
+
await open(await this.get_episode_link(episode, config.player));
|
226
|
+
break;
|
227
|
+
case "W2G":
|
228
|
+
try {
|
229
|
+
this.player.player = new W2GClient.W2GClient(config.w2g_api_key);
|
230
|
+
await this.player.player.create(await this.get_episode_link(episode, config.player));
|
231
|
+
console.log(chalk.green("Room link: " + await this.player.player.getLink()));
|
232
|
+
}
|
233
|
+
catch {
|
234
|
+
console.log(chalk.red("Failed to create w2g.tv room. \nthis can often be because your API token is invalid. You can change it in options."));
|
235
|
+
process.exit();
|
236
|
+
}
|
237
|
+
this.player.play = (async (episode_link) => {
|
238
|
+
console.log(("Updating W2G room..."));
|
239
|
+
console.log(chalk.green("Room link: " + await this.player.player.getLink()));
|
240
|
+
try {
|
241
|
+
await this.player.player.update(episode_link);
|
242
|
+
}
|
243
|
+
catch {
|
244
|
+
console.log(chalk.red("Error updating W2G room. Very sorry, w2g functionality is a bit broken at present. Worst case you should be able to just restart with a new room for each episode."));
|
245
|
+
}
|
246
|
+
});
|
247
|
+
console.log("Opening W2G.tv...");
|
248
|
+
await open(await this.player.player.getLink());
|
249
|
+
break;
|
250
|
+
case "LINK":
|
251
|
+
this.player.play = (async (episode_link) => {
|
252
|
+
console.log(chalk.green(episode_link));
|
253
|
+
});
|
254
|
+
this.player.play(await this.get_episode_link(episode));
|
255
|
+
break;
|
256
|
+
}
|
257
|
+
await this.play_controller(episode, config, config_dir, true);
|
258
|
+
}
|
259
|
+
async next(player) {
|
260
|
+
this.current_episode += 1;
|
261
|
+
this.current_pos = 0;
|
262
|
+
this.player.play(await this.get_episode_link(this.current_episode, player));
|
263
|
+
}
|
264
|
+
async previous(player) {
|
265
|
+
this.current_episode -= 1;
|
266
|
+
this.current_pos = 0;
|
267
|
+
this.player.play(await this.get_episode_link(this.current_episode, player));
|
268
|
+
}
|
269
|
+
async play_controller(episode, config, config_dir, first = false) {
|
270
|
+
console.log(`Playing ${this.id} episode ${episode + 1}`); // from ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`)
|
271
|
+
// if (!first){
|
272
|
+
// console.clear()
|
273
|
+
// console.log(chalk.blue(`Playing ${this.id} episode ${episode+1}`))
|
274
|
+
// if (this.player == 0){
|
275
|
+
// await open(await this.get_episode_link(episode, "BROWSER"))
|
276
|
+
// }else if(this.player == 1){
|
277
|
+
// console.log(await this.get_episode_link(episode))
|
278
|
+
// } else if (this.player.roomID != undefined){
|
279
|
+
// console.log(chalk.green("Room link: "+ await this.player.getLink()));
|
280
|
+
// this.player.update(await this.get_episode_link(episode))
|
281
|
+
// } else if (this.player.opts.app == "mpv"){
|
282
|
+
// await this.player.load(await this.get_episode_link(episode))
|
283
|
+
// }else{
|
284
|
+
// this.player.quit()
|
285
|
+
// this.player = await new PlayerController({
|
286
|
+
// app: 'vlc',
|
287
|
+
// args: ['--fullscreen'],
|
288
|
+
// media: await this.get_episode_link(episode, config.player)
|
289
|
+
// });
|
290
|
+
// // @ts-ignore
|
291
|
+
// await this.player.launch(err => {
|
292
|
+
// if (err) return console.error(err.message);
|
293
|
+
// });
|
294
|
+
// }
|
295
|
+
// }
|
296
|
+
this.current_episode = episode;
|
297
|
+
config.most_recent.anime_id = this.id;
|
298
|
+
config.most_recent.episode_number = episode;
|
299
|
+
config.most_recent.episode_second = this.current_pos;
|
300
|
+
(0, load_config_1.write_config)(config_dir, config);
|
301
|
+
this.most_recent = episode;
|
302
|
+
(0, cache_1.new_cache)(config_dir, {
|
303
|
+
id: this.id,
|
304
|
+
episode_list: this.episode_list,
|
305
|
+
most_recent: this.most_recent,
|
306
|
+
position: this.current_pos
|
307
|
+
});
|
308
|
+
let selected; // Look, I'm sorry, but there is no way I can possibly document this in a sane way. It's a dumb patch.
|
309
|
+
do {
|
310
|
+
selected = await (0, input_1.selection)((episode <= 0) ? [chalk.yellow("1/n) Next"), chalk.grey("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
|
311
|
+
(episode >= this.episode_list.length - 1) ? [chalk.grey("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
|
312
|
+
[chalk.yellow("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")], ["n", "p", "s", "q"], ((thing) => { return (thing); }), ((thing) => { return (thing); }), true);
|
313
|
+
if (!(selected != ((episode <= 0) ? 1 : (episode >= this.episode_list.length - 1) ? 0 : -1))) {
|
314
|
+
console.log(chalk.red("Invalid choice."));
|
315
|
+
}
|
316
|
+
} while (!(selected != ((episode <= 0) ? 1 : (episode >= this.episode_list.length - 1) ? 0 : -1)));
|
317
|
+
switch (selected) {
|
318
|
+
case 0:
|
319
|
+
if (episode >= this.episode_list.length - 1) {
|
320
|
+
await this.next(config.player);
|
321
|
+
await this.play_controller(episode - 1, config, config_dir);
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
await this.next(config.player);
|
325
|
+
await this.play_controller(episode + 1, config, config_dir);
|
326
|
+
}
|
327
|
+
break;
|
328
|
+
case 1:
|
329
|
+
if ((episode >= this.episode_list.length - 1) || (episode <= 0)) {
|
330
|
+
break;
|
331
|
+
}
|
332
|
+
await this.previous(config.player);
|
333
|
+
await this.play_controller(episode - 1, config, config_dir);
|
334
|
+
break;
|
335
|
+
case 2:
|
336
|
+
if (this.episode_list.length == 1) {
|
337
|
+
this.player.play(await this.get_episode_link(0, config.player));
|
338
|
+
await this.play_controller(0, config, config_dir);
|
339
|
+
}
|
340
|
+
else {
|
341
|
+
console.log(`Select episode [1-${this.episode_list.length}]`);
|
342
|
+
let episode = await (0, input_1.number_input)(this.episode_list.length, 1) - 1;
|
343
|
+
this.player.play(await this.get_episode_link(episode, config.player));
|
344
|
+
await this.play_controller(episode, config, config_dir);
|
345
|
+
}
|
346
|
+
break;
|
347
|
+
case 3:
|
348
|
+
break;
|
349
|
+
}
|
350
|
+
}
|
351
|
+
async download(episode, download_folder, final_ep) {
|
352
|
+
/*
|
353
|
+
## Downloads an episode (counting from 0) to download_folder, with progress bar.
|
354
|
+
*/
|
355
|
+
try {
|
356
|
+
// @ts-ignore
|
357
|
+
let ep_link = await this.get_episode_link(episode);
|
358
|
+
let file_name = `${this.id}-${episode + 1}.mp4`;
|
359
|
+
if (ep_link.includes(".m3u8"))
|
360
|
+
console.log(chalk.red("Warning: Animixplay will download an m3u8 file. This will require some extra steps to play. It is advised to use a 3rd party website or tool to download these from the link."));
|
361
|
+
// @ts-ignore
|
362
|
+
let option = {
|
363
|
+
filename: (ep_link.includes("m3u8") ? file_name.replace("mp4", "m3u8") : file_name),
|
364
|
+
dir: download_folder,
|
365
|
+
onDone: (final_ep > episode) ? ((info) => {
|
366
|
+
// @ts-ignore
|
367
|
+
console.log(chalk.green(`\n -- 1Download finished -- \nLocation: ${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
|
368
|
+
this.download(episode + 1, download_folder, final_ep);
|
369
|
+
}) : ((info) => {
|
370
|
+
// @ts-ignore
|
371
|
+
console.log(chalk.green(`\n -- 2Download finished -- \n${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
|
372
|
+
}),
|
373
|
+
// @ts-ignore
|
374
|
+
onError: (err) => {
|
375
|
+
console.log(chalk.red('error', err));
|
376
|
+
this.download(episode, download_folder, final_ep);
|
377
|
+
},
|
378
|
+
// @ts-ignore
|
379
|
+
onProgress: (curr, total) => {
|
380
|
+
process.stdout.clearLine(0);
|
381
|
+
process.stdout.cursorTo(0);
|
382
|
+
process.stdout.write("\x1b[32m -- " + (curr / total * 100).toFixed(2) + "% " + "#".repeat(Math.ceil((curr / total) * ((process.stdout.columns - 20) / 1.5))) + "~".repeat(Math.ceil(((process.stdout.columns - 20) / 1.5) - (curr / total) * ((process.stdout.columns - 20) / 1.5))) + " -- \x1b[0m");
|
383
|
+
}
|
384
|
+
};
|
385
|
+
//console.log((`${option.dir}/${option.filename}`))
|
386
|
+
return await dl(ep_link, option);
|
387
|
+
}
|
388
|
+
catch {
|
389
|
+
this.download(episode, download_folder, final_ep);
|
390
|
+
}
|
391
|
+
}
|
392
|
+
}
|
393
|
+
exports.Anime = Anime;
|