From 24dcea3490e11f422ba327472a6b83263915a079 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 10 Feb 2024 21:04:29 +0000 Subject: [PATCH] all: initial clip scaffolding --- src/modules/processing/matchActionDecider.js | 7 +++- src/modules/stream/manage.js | 4 ++ src/modules/stream/stream.js | 5 ++- src/modules/stream/types.js | 41 +++++++++++++++++--- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/modules/processing/matchActionDecider.js b/src/modules/processing/matchActionDecider.js index 7aa154bd..4116f161 100644 --- a/src/modules/processing/matchActionDecider.js +++ b/src/modules/processing/matchActionDecider.js @@ -18,6 +18,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di if (r.isPhoto) action = "photo"; else if (r.picker) action = "picker" + else if (r.isClip) action = "clip"; // TODO: user-specified clips else if (r.isGif && toGif) action = "gif"; else if (isAudioMuted) action = "muteVideo"; else if (isAudioOnly) action = "audio"; @@ -40,7 +41,11 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di case "photo": responseType = 1; break; - + + case "clip": + params = { type: "clip" } + break; + case "gif": params = { type: "gif" } break; diff --git a/src/modules/stream/manage.js b/src/modules/stream/manage.js index 459e5a6b..1339f259 100644 --- a/src/modules/stream/manage.js +++ b/src/modules/stream/manage.js @@ -34,6 +34,10 @@ export function createStream(obj) { isAudioOnly: !!obj.isAudioOnly, audioFormat: obj.audioFormat, time: obj.time ? obj.time : false, + clip: obj.clip ? { + start: parseFloat(obj.clip.start).toFixed(6), + end: parseFloat(obj.clip.end).toFixed(6), + } : false, copy: !!obj.copy, mute: !!obj.mute, metadata: obj.fileMetadata ? obj.fileMetadata : false diff --git a/src/modules/stream/stream.js b/src/modules/stream/stream.js index f254dacc..babf5616 100644 --- a/src/modules/stream/stream.js +++ b/src/modules/stream/stream.js @@ -1,4 +1,4 @@ -import { streamAudioOnly, streamDefault, streamLiveRender, streamVideoOnly, convertToGif } from "./types.js"; +import { streamAudioOnly, streamDefault, streamLiveRender, streamVideoOnly, streamClip, convertToGif } from "./types.js"; export default async function(res, streamInfo) { try { @@ -17,6 +17,9 @@ export default async function(res, streamInfo) { case "mute": streamVideoOnly(streamInfo, res); break; + case "clip": + streamClip(streamInfo, res); + break; default: await streamDefault(streamInfo, res); break; diff --git a/src/modules/stream/types.js b/src/modules/stream/types.js index d07ac3d2..f29c14a9 100644 --- a/src/modules/stream/types.js +++ b/src/modules/stream/types.js @@ -1,10 +1,12 @@ -import ffmpeg from "ffmpeg-static"; -import { ffmpegArgs, genericUserAgent } from "../config.js"; -import { spawn, pipe, killProcess } from "./shared.js"; -import { metadataManager } from "../sub/utils.js"; -import { request } from "undici"; -import { create as contentDisposition } from "content-disposition-header"; +import { request } from "undici" +import ffmpeg from "ffmpeg-static" import { AbortController } from "abort-controller" +import { create as contentDisposition } from "content-disposition-header" + +import { makeCut } from "./cut.js" +import { metadataManager } from "../sub/utils.js" +import { spawn, pipe, killProcess } from "./shared.js" +import { ffmpegArgs, genericUserAgent } from "../config.js" function closeRequest(controller) { try { controller.abort() } catch {} @@ -226,3 +228,30 @@ export function convertToGif(streamInfo, res) { shutdown(); } } + +export async function streamClip(streamInfo, res) { + if (typeof streamInfo.urls === 'string') + streamInfo.urls = [streamInfo.urls]; + + const shutdown = () => (killProcess(process), closeResponse(res)); + + try { + const [ video, audio ] = streamInfo.urls; + const { start, end } = streamInfo.clip; + if (!start || !end || start === 'NaN' || end === 'NaN') + return shutdown(); + + const stream = await makeCut(video, { start, end }, audio); + process = stream.process; + + res.setHeader('Connection', 'keep-alive'); + res.setHeader('Content-Disposition', contentDisposition(streamInfo.filename)); + + pipe(stream, res, shutdown); + + process.on('close', shutdown); + res.on('finish', shutdown); + } catch { + shutdown(); + } +} \ No newline at end of file