From c7c9cf2f0ff4f2e52872449c7e6d4982f88c5222 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 29 Jan 2025 15:00:50 +0600 Subject: [PATCH] api: add local processing response type & param `local-processing` type returns needed info for on-device processing and creates basic proxy tunnels --- api/src/processing/match-action.js | 28 ++++++++++++++++++++++++++-- api/src/processing/match.js | 1 + api/src/processing/request.js | 21 ++++++++++++++++++++- api/src/processing/schema.js | 8 +++----- api/src/stream/manage.js | 27 +++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/api/src/processing/match-action.js b/api/src/processing/match-action.js index 363cb403..32551cb0 100644 --- a/api/src/processing/match-action.js +++ b/api/src/processing/match-action.js @@ -5,7 +5,22 @@ import { audioIgnore } from "./service-config.js"; import { createStream } from "../stream/manage.js"; import { splitFilenameExtension } from "../misc/utils.js"; -export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disableMetadata, filenameStyle, twitterGif, requestIP, audioBitrate, alwaysProxy }) { +const extraProcessingTypes = ["merge", "remux", "mute", "audio", "gif"]; + +export default function({ + r, + host, + audioFormat, + isAudioOnly, + isAudioMuted, + disableMetadata, + filenameStyle, + twitterGif, + requestIP, + audioBitrate, + alwaysProxy, + localProcessing +}) { let action, responseType = "tunnel", defaultParams = { @@ -216,5 +231,14 @@ export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disab params.type = "proxy"; } - return createResponse(responseType, {...defaultParams, ...params}) + // TODO: add support for HLS + // (very painful) + if (localProcessing && !params.isHLS && extraProcessingTypes.includes(params.type)) { + responseType = "local-processing"; + } + + return createResponse( + responseType, + { ...defaultParams, ...params } + ); } diff --git a/api/src/processing/match.js b/api/src/processing/match.js index 9fabf379..9337e96b 100644 --- a/api/src/processing/match.js +++ b/api/src/processing/match.js @@ -304,6 +304,7 @@ export default async function({ host, patternMatch, params }) { requestIP, audioBitrate: params.audioBitrate, alwaysProxy: params.alwaysProxy, + localProcessing: params.localProcessing, }) } catch { return createResponse("error", { diff --git a/api/src/processing/request.js b/api/src/processing/request.js index d512bfe5..d0b851e8 100644 --- a/api/src/processing/request.js +++ b/api/src/processing/request.js @@ -1,7 +1,7 @@ import ipaddr from "ipaddr.js"; -import { createStream } from "../stream/manage.js"; import { apiSchema } from "./schema.js"; +import { createProxyTunnels, createStream } from "../stream/manage.js"; export function createResponse(responseType, responseData) { const internalError = (code) => { @@ -49,6 +49,25 @@ export function createResponse(responseType, responseData) { } break; + case "local-processing": + response = { + tunnel: createProxyTunnels(responseData), + + type: responseData?.type, + service: responseData?.service, + filename: responseData?.filename, + metadata: responseData?.fileMetadata, + + audio: { + copy: responseData?.audioCopy, + format: responseData?.audioFormat, + bitrate: responseData?.audioBitrate, + }, + + isHLS: responseData?.isHLS, + } + break; + case "picker": response = { picker: responseData?.picker, diff --git a/api/src/processing/schema.js b/api/src/processing/schema.js index 48d8b058..967ef802 100644 --- a/api/src/processing/schema.js +++ b/api/src/processing/schema.js @@ -36,16 +36,14 @@ export const apiSchema = z.object({ .regex(/^[0-9a-zA-Z\-]+$/) .optional(), - // TODO: remove this variable as it's no longer used - // and is kept for schema compatibility reasons - youtubeDubBrowserLang: z.boolean().default(false), - - alwaysProxy: z.boolean().default(false), disableMetadata: z.boolean().default(false), tiktokFullAudio: z.boolean().default(false), tiktokH265: z.boolean().default(false), twitterGif: z.boolean().default(true), + alwaysProxy: z.boolean().default(false), + localProcessing: z.boolean().default(false), + youtubeHLS: z.boolean().default(false), }) .strict(); diff --git a/api/src/stream/manage.js b/api/src/stream/manage.js index 0e6d496a..e64a3799 100644 --- a/api/src/stream/manage.js +++ b/api/src/stream/manage.js @@ -70,6 +70,33 @@ export function createStream(obj) { return streamLink.toString(); } +export function createProxyTunnels(info) { + const proxyTunnels = []; + + let urls = info.url; + + if (typeof urls === "string") { + urls = [urls]; + } + + for (const url of urls) { + proxyTunnels.push( + createStream({ + url, + type: "proxy", + + service: info?.service, + headers: info?.headers, + requestIP: info?.requestIP, + + originalRequest: info?.originalRequest + }) + ); + } + + return proxyTunnels; +} + export function getInternalTunnel(id) { return internalStreamCache.get(id); }