GUI-STUDIO commited on
Commit
b5a110c
·
1 Parent(s): 60d1989

Add disabled deploy targets and FFmpeg DL v2

Browse files

Skip disabled deployment entries across hosting workflows. Add a v2 download route with server-to-server progress relaying, move Redis and offline-store utilities into shared packages, and enable audio re-encoding for input-phase FFmpeg jobs.

src/lib/ffmpeg-v2.ts CHANGED
@@ -605,7 +605,7 @@ async function F_build_ffmpeg_flags_t1(arg0: {
605
  // const re_encode_va = !IS_RENDER_COM();
606
 
607
  if (phase_input) must_re_encode = false;
608
- if (phase_input) re_encode_a = false;
609
 
610
  flags.push("-map", "0:v");
611
  flags.push("-map", "0:a?");
 
605
  // const re_encode_va = !IS_RENDER_COM();
606
 
607
  if (phase_input) must_re_encode = false;
608
+ if (phase_input) re_encode_a = true;
609
 
610
  flags.push("-map", "0:v");
611
  flags.push("-map", "0:a?");
src/lib/offline-store.ts DELETED
@@ -1,72 +0,0 @@
1
- // Simple Store using Map
2
- class OfflineStore {
3
- state: Map<any, any>;
4
- subscribers: Set<(state: any) => void>;
5
-
6
- constructor() {
7
- this.state = new Map();
8
- this.subscribers = new Set();
9
- }
10
-
11
- // Get a value by key
12
- get(key: string) {
13
- return this.state.get(key);
14
- }
15
-
16
- // Set a value by key and notify subscribers
17
- set(key: string, value: any) {
18
- this.state.set(key, value);
19
- this.notifySubscribers();
20
- }
21
-
22
- // Delete a value by key and notify subscribers
23
- delete(key: string) {
24
- this.state.delete(key);
25
- this.notifySubscribers();
26
- }
27
-
28
- // Clear the entire store and notify subscribers
29
- clear() {
30
- this.state.clear();
31
- this.notifySubscribers();
32
- }
33
-
34
- // Subscribe to store changes
35
- subscribe(callback: (state: any) => void) {
36
- this.subscribers.add(callback);
37
- return () => this.subscribers.delete(callback);
38
- }
39
-
40
- // Notify all subscribers
41
- notifySubscribers() {
42
- this.subscribers.forEach((callback) => {
43
- return callback(this.state);
44
- });
45
- }
46
- }
47
-
48
- const offline_store = new OfflineStore();
49
-
50
- export { offline_store };
51
-
52
- // Example usage
53
- // Subscribe to changes
54
- // const unsubscribe = store.subscribe((state: any[]) => {
55
- // console.log("Store updated:", Array.from(state.entries()));
56
- // });
57
-
58
- // Set values
59
- // store.set("user", { name: "Alice", age: 30 });
60
- // store.set("theme", "dark");
61
-
62
- // Get a value
63
- // console.log(store.get("user")); // { name: "Alice", age: 30 }
64
-
65
- // Delete a value
66
- // store.delete("theme");
67
-
68
- // Clear the store
69
- // store.clear();
70
-
71
- // Unsubscribe
72
- // unsubscribe();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/upstash.ts DELETED
@@ -1,18 +0,0 @@
1
- import { Redis } from "@upstash/redis";
2
- import { NS_runtime } from "@x/types/env.runtime";
3
-
4
- const UPSTASH_REDIS_REST_URL = () =>
5
- NS_runtime.ENV_VAR_DB?.UPSTASH_REDIS_REST_URL ||
6
- process.env.UPSTASH_REDIS_REST_URL;
7
- const UPSTASH_REDIS_REST_TOKEN = () =>
8
- NS_runtime.ENV_VAR_DB?.UPSTASH_REDIS_REST_TOKEN ||
9
- process.env.UPSTASH_REDIS_REST_TOKEN;
10
-
11
- const redis = () => {
12
- return new Redis({
13
- url: UPSTASH_REDIS_REST_URL(),
14
- token: UPSTASH_REDIS_REST_TOKEN(),
15
- });
16
- };
17
-
18
- export { redis };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/sub-router/probe.ts CHANGED
@@ -8,10 +8,8 @@ import UserAgent from "user-agents";
8
  import { NS_promise } from "@x/core/client/promise.ts";
9
  import { NS_crypto_client } from "@x/core/client/crypto.ts";
10
  import { NS_unpack_proxima } from "@x/core/server/proxima/unpack.ts";
11
- import { redis } from "../lib/upstash";
12
- import { offline_store } from "../lib/offline-store";
13
  import { estimateHlsSize } from "./hls-size";
14
- import { NS_scrape_post_processing_helper } from "@x/post-process/helper";
15
  import {
16
  NS_probe_validator_v2,
17
  type T_probe_playback,
@@ -20,6 +18,7 @@ import {
20
  import { NS_ff } from "@x/ff-dl/helper";
21
  import { NS_ffmpeg_v2 } from "../lib/ffmpeg-v2";
22
  import { NS_error } from "@x/core/client/error.ts";
 
23
 
24
  const APP_ACCOUNT_ABC = () =>
25
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
@@ -544,7 +543,7 @@ const sub_router = new Elysia({ prefix: "/ffmpeg" })
544
  if (APP_ENV() === "dev") {
545
  offline_store.set(key, delivery_payload);
546
  } else {
547
- await redis().set(key, delivery_payload, {
548
  ex: ONE_MONTH_IN_SECONDS
549
  });
550
  }
 
8
  import { NS_promise } from "@x/core/client/promise.ts";
9
  import { NS_crypto_client } from "@x/core/client/crypto.ts";
10
  import { NS_unpack_proxima } from "@x/core/server/proxima/unpack.ts";
11
+ import { offline_store } from "@x/ff-dl/offline-store";
 
12
  import { estimateHlsSize } from "./hls-size";
 
13
  import {
14
  NS_probe_validator_v2,
15
  type T_probe_playback,
 
18
  import { NS_ff } from "@x/ff-dl/helper";
19
  import { NS_ffmpeg_v2 } from "../lib/ffmpeg-v2";
20
  import { NS_error } from "@x/core/client/error.ts";
21
+ import { redis } from "@x/post-process/cache";
22
 
23
  const APP_ACCOUNT_ABC = () =>
24
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
 
543
  if (APP_ENV() === "dev") {
544
  offline_store.set(key, delivery_payload);
545
  } else {
546
+ await redis()?.set(key, delivery_payload, {
547
  ex: ONE_MONTH_IN_SECONDS
548
  });
549
  }
src/sub-router/showtime.ts CHANGED
@@ -4,14 +4,13 @@ import {
4
  IS_RENDER_COM,
5
  NS_runtime
6
  } from "@x/types/env.runtime";
7
- import { redis } from "../lib/upstash";
8
  import { spawn } from "child_process";
9
  import { type Context, Elysia, t } from "elysia";
10
  import path from "node:path";
11
  import { PassThrough, Transform } from "node:stream";
12
  import { NS_ffmpeg_v2 } from "../lib/ffmpeg-v2";
13
  import { NS_misc } from "../lib/misc";
14
- import { offline_store } from "../lib/offline-store";
15
  import { NS_promise } from "@x/core/client/promise.ts";
16
  import node_fs from "node:fs";
17
  import { NS_pack_proxima } from "@x/core/server/proxima/pack.ts";
@@ -32,6 +31,8 @@ import {
32
  import type { T_delivery_payload, T_probe_playback } from "@x/ff-dl/types";
33
  import { NS_ff } from "@x/ff-dl/helper";
34
  import { homedir } from "node:os";
 
 
35
 
36
  const APP_ACCOUNT_ABC = () =>
37
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
@@ -55,97 +56,150 @@ const is_dev = (() => {
55
  return APP_ENV() === "dev";
56
  })();
57
 
58
- const sub_router = new Elysia({ prefix: "/dlV1" }).get(
59
- "/delivery/:data_key",
60
- async (ctx) => {
61
- const { params, query, request } = ctx;
62
- let { data_key } = params;
63
- let { ops } = query;
64
 
65
- const REQ0 = new URL(request.url);
66
- const REQ_ORIGIN = (ctx as any).publicOrigin || REQ0.origin;
 
 
 
67
 
68
- const metadata = await (async () => {
69
- try {
70
- if (is_dev) {
71
- const _ = offline_store.get(data_key);
72
 
73
- if (_) return _;
 
 
 
 
 
 
 
 
 
 
 
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- const _ = await redis().get(data_key);
 
 
 
 
 
77
 
78
- return _;
79
- } catch {
80
- return;
81
- }
82
- })();
83
 
84
- if (!metadata) {
85
- ctx.set.status = 404;
86
- return "Metadata not found";
87
- }
88
 
89
- if (ops === "raw" || ops === "decode") {
90
- return metadata;
91
- }
92
 
93
- const [E_, R_] = await NS_promise.F_catch_promise({
94
- promise: handle_data({
95
- data_key,
96
- metadata,
97
- REQ0,
98
- REQ_ORIGIN,
99
- ctx: ctx as any,
100
- ops
101
- })
102
- });
 
 
103
 
104
- if (E_) {
105
- const { message, status } = NS_error.F_collect_error_status_n_message({
106
- ERR: E_
 
 
 
 
 
 
 
 
 
 
107
  });
108
 
109
- return ctx.status(status, message);
110
- }
 
 
111
 
112
- return R_;
113
- },
114
- {
115
- params: t.Object({
116
- data_key: t.String({
117
- minLength: 1,
118
- error() {
119
- return "Invalid process data, Expected string";
120
- }
121
- })
122
- }),
123
- query: t.Object({
124
- raw: t.Optional(
125
- t.Number({
126
- minimum: 0,
127
- maximum: 1,
128
- error: () => "Invalid raw, Expected binary boolean"
129
  })
130
- ),
131
- ops: t.Optional(
132
- t.Union(
133
- [
134
- t.Literal("cmd"),
135
- t.Literal("raw"),
136
- t.Literal("decode"),
137
- t.Literal("jc")
138
- ],
139
- {
140
- error() {
141
- return "Invalid operation, must be one of: cmd, raw, decode";
 
 
 
 
 
 
 
 
 
142
  }
143
- }
144
  )
145
- )
146
- })
147
- }
148
- );
149
 
150
  export const dlV1Router = sub_router;
151
  export const dlV1RouterHandlePayload = handle_data;
@@ -176,6 +230,8 @@ async function handle_data(arg0: {
176
  station
177
  } = metadata as T_delivery_payload;
178
 
 
 
179
  const is_download_mode = delivery_mode === "download";
180
  const is_stream_mode = delivery_mode === "stream";
181
 
@@ -266,6 +322,20 @@ async function handle_data(arg0: {
266
  _
267
  );
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  return __;
270
  })();
271
 
@@ -1884,8 +1954,6 @@ async function handle_data(arg0: {
1884
  // TWO STEP: a .ts cannot carry mov_text subtitles, they are added in step 2
1885
  has_subs = two_step ? false : subs === false ? false : true;
1886
 
1887
- console.log({ use_s3_pipe });
1888
-
1889
  const data = await NS_ffmpeg_v2.F_build_ffmpeg_flags_t1({
1890
  playback: new_playback,
1891
  subtitles: two_step || subs === false ? undefined : subtitles,
@@ -1897,8 +1965,6 @@ async function handle_data(arg0: {
1897
  dl_to_s3: use_s3_pipe
1898
  });
1899
 
1900
- console.log({ data });
1901
-
1902
  return data;
1903
  }
1904
 
 
4
  IS_RENDER_COM,
5
  NS_runtime
6
  } from "@x/types/env.runtime";
 
7
  import { spawn } from "child_process";
8
  import { type Context, Elysia, t } from "elysia";
9
  import path from "node:path";
10
  import { PassThrough, Transform } from "node:stream";
11
  import { NS_ffmpeg_v2 } from "../lib/ffmpeg-v2";
12
  import { NS_misc } from "../lib/misc";
13
+ import { offline_store } from "@x/ff-dl/offline-store";
14
  import { NS_promise } from "@x/core/client/promise.ts";
15
  import node_fs from "node:fs";
16
  import { NS_pack_proxima } from "@x/core/server/proxima/pack.ts";
 
31
  import type { T_delivery_payload, T_probe_playback } from "@x/ff-dl/types";
32
  import { NS_ff } from "@x/ff-dl/helper";
33
  import { homedir } from "node:os";
34
+ import { redis } from "@x/post-process/cache";
35
+ import { NS_crypto_client } from "@x/core/client/crypto.ts";
36
 
37
  const APP_ACCOUNT_ABC = () =>
38
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
 
56
  return APP_ENV() === "dev";
57
  })();
58
 
59
+ const sub_router = new Elysia({ prefix: "/dlV1" })
 
 
 
 
 
60
 
61
+ .post(
62
+ "/s2s",
63
+ async (ctx) => {
64
+ const { body, request } = ctx;
65
+ const { job_id, data_key, status, info } = body;
66
 
67
+ const REQ0 = new URL(request.url);
68
+ const REQ_ORIGIN = (ctx as any).publicOrigin || REQ0.origin;
 
 
69
 
70
+ record_task_info({
71
+ job_id,
72
+ status: status as any,
73
+ info
74
+ });
75
+
76
+ relay_progress_info_ws({
77
+ channel: data_key,
78
+ payload: {
79
+ channel: data_key,
80
+ status,
81
+ data: info
82
  }
83
+ });
84
+ },
85
+ {
86
+ body: t.Object({
87
+ job_id: t.String({
88
+ minLength: 1,
89
+ error() {
90
+ return "Invalid job id";
91
+ }
92
+ }),
93
+ status: t.String({
94
+ minLength: 1,
95
+ error() {
96
+ return "Invalidstatus";
97
+ }
98
+ }),
99
+ data_key: t.String({
100
+ minLength: 1,
101
+ error() {
102
+ return "Invalid data key";
103
+ }
104
+ }),
105
+ info: t.Record(t.String(), t.Any(), {
106
+ error: "info must be a valid object"
107
+ })
108
+ })
109
+ }
110
+ )
111
 
112
+ .get(
113
+ "/delivery/:data_key",
114
+ async (ctx) => {
115
+ const { params, query, request } = ctx;
116
+ let { data_key } = params;
117
+ let { ops } = query;
118
 
119
+ const REQ0 = new URL(request.url);
120
+ const REQ_ORIGIN = (ctx as any).publicOrigin || REQ0.origin;
 
 
 
121
 
122
+ const metadata = await (async () => {
123
+ try {
124
+ if (is_dev) {
125
+ const _ = offline_store.get(data_key);
126
 
127
+ if (_) return _;
128
+ }
 
129
 
130
+ const _ = await redis()?.get(data_key);
131
+
132
+ return _;
133
+ } catch {
134
+ return;
135
+ }
136
+ })();
137
+
138
+ if (!metadata) {
139
+ ctx.set.status = 404;
140
+ return "Metadata not found";
141
+ }
142
 
143
+ if (ops === "raw" || ops === "decode") {
144
+ return metadata;
145
+ }
146
+
147
+ const [E_, R_] = await NS_promise.F_catch_promise({
148
+ promise: handle_data({
149
+ data_key,
150
+ metadata,
151
+ REQ0,
152
+ REQ_ORIGIN,
153
+ ctx: ctx as any,
154
+ ops
155
+ })
156
  });
157
 
158
+ if (E_) {
159
+ const { message, status } = NS_error.F_collect_error_status_n_message({
160
+ ERR: E_
161
+ });
162
 
163
+ return ctx.status(status, message);
164
+ }
165
+
166
+ return R_;
167
+ },
168
+ {
169
+ params: t.Object({
170
+ data_key: t.String({
171
+ minLength: 1,
172
+ error() {
173
+ return "Invalid process data, Expected string";
174
+ }
 
 
 
 
 
175
  })
176
+ }),
177
+ query: t.Object({
178
+ raw: t.Optional(
179
+ t.Number({
180
+ minimum: 0,
181
+ maximum: 1,
182
+ error: () => "Invalid raw, Expected binary boolean"
183
+ })
184
+ ),
185
+ ops: t.Optional(
186
+ t.Union(
187
+ [
188
+ t.Literal("cmd"),
189
+ t.Literal("raw"),
190
+ t.Literal("decode"),
191
+ t.Literal("jc")
192
+ ],
193
+ {
194
+ error() {
195
+ return "Invalid operation, must be one of: cmd, raw, decode";
196
+ }
197
  }
198
+ )
199
  )
200
+ })
201
+ }
202
+ );
 
203
 
204
  export const dlV1Router = sub_router;
205
  export const dlV1RouterHandlePayload = handle_data;
 
230
  station
231
  } = metadata as T_delivery_payload;
232
 
233
+ metadata.s2s_progress = (() => new URL("/dlV1/s2s", REQ_ORIGIN).toString())();
234
+
235
  const is_download_mode = delivery_mode === "download";
236
  const is_stream_mode = delivery_mode === "stream";
237
 
 
322
  _
323
  );
324
 
325
+ const [E_, R_] = await NS_promise.F_catch_promise({
326
+ promise: (async () => {
327
+ return NS_crypto_client.F_encode_unicode_v1({
328
+ data_payload: metadata,
329
+ url_safe: true,
330
+ encode: "hex"
331
+ });
332
+ })()
333
+ });
334
+
335
+ if (R_) {
336
+ __.searchParams.set("data_key", `${R_}`);
337
+ }
338
+
339
  return __;
340
  })();
341
 
 
1954
  // TWO STEP: a .ts cannot carry mov_text subtitles, they are added in step 2
1955
  has_subs = two_step ? false : subs === false ? false : true;
1956
 
 
 
1957
  const data = await NS_ffmpeg_v2.F_build_ffmpeg_flags_t1({
1958
  playback: new_playback,
1959
  subtitles: two_step || subs === false ? undefined : subtitles,
 
1965
  dl_to_s3: use_s3_pipe
1966
  });
1967
 
 
 
1968
  return data;
1969
  }
1970
 
src/sub-router/stream.ts CHANGED
@@ -1,11 +1,11 @@
1
  import { type Context, Elysia, t } from "elysia";
2
  import { NS_runtime, IS_HF } from "@x/types/env.runtime";
3
- import { offline_store } from "../lib/offline-store";
4
- import { redis } from "../lib/upstash";
5
  import { NS_promise } from "@x/core/client/promise.ts";
6
  import { NS_error } from "@x/core/client/error.ts";
7
  import { NS_ff_dl_stream } from "@x/ff-dl/dl-stream";
8
  import { NS_Misc } from "@x/core/client/misc.ts";
 
9
 
10
  const APP_ACCOUNT_ABC = () =>
11
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
@@ -44,7 +44,7 @@ const sub_router = new Elysia({ prefix: "/stream" }).get(
44
  if (_) return _;
45
  }
46
 
47
- const _ = await redis().get(data_key);
48
 
49
  return _;
50
  } catch {
 
1
  import { type Context, Elysia, t } from "elysia";
2
  import { NS_runtime, IS_HF } from "@x/types/env.runtime";
3
+ import { offline_store } from "@x/ff-dl/offline-store";
 
4
  import { NS_promise } from "@x/core/client/promise.ts";
5
  import { NS_error } from "@x/core/client/error.ts";
6
  import { NS_ff_dl_stream } from "@x/ff-dl/dl-stream";
7
  import { NS_Misc } from "@x/core/client/misc.ts";
8
+ import { redis } from "@x/post-process/cache";
9
 
10
  const APP_ACCOUNT_ABC = () =>
11
  NS_runtime.ENV_VAR_DB?.APP_ACCOUNT_ABC || process.env.APP_ACCOUNT_ABC;
 
44
  if (_) return _;
45
  }
46
 
47
+ const _ = await redis()?.get(data_key);
48
 
49
  return _;
50
  } catch {