mirror of
https://github.com/imputnet/cobalt.git
synced 2025-01-15 03:15:14 +00:00
api/create-filename: build & sanitize filenames in one place
This commit is contained in:
parent
407c27ed86
commit
6770738116
|
@ -1,5 +1,3 @@
|
||||||
const forbiddenCharsString = ['}', '{', '%', '>', '<', '^', ';', ':', '`', '$', '"', "@", '=', '?', '|', '*'];
|
|
||||||
|
|
||||||
export function convertMetadataToFFmpeg(obj) {
|
export function convertMetadataToFFmpeg(obj) {
|
||||||
const keys = Object.keys(obj);
|
const keys = Object.keys(obj);
|
||||||
const tags = [
|
const tags = [
|
||||||
|
@ -19,14 +17,6 @@ export function convertMetadataToFFmpeg(obj) {
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanString(string) {
|
|
||||||
for (const i in forbiddenCharsString) {
|
|
||||||
string = string.replaceAll("/", "_").replaceAll("\\", "_")
|
|
||||||
.replaceAll(forbiddenCharsString[i], '')
|
|
||||||
}
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getRedirectingURL(url) {
|
export function getRedirectingURL(url) {
|
||||||
return fetch(url, { redirect: 'manual' }).then((r) => {
|
return fetch(url, { redirect: 'manual' }).then((r) => {
|
||||||
if ([301, 302, 303].includes(r.status) && r.headers.has('location'))
|
if ([301, 302, 303].includes(r.status) && r.headers.has('location'))
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
const illegalCharacters = ['}', '{', '%', '>', '<', '^', ';', ':', '`', '$', '"', "@", '=', '?', '|', '*'];
|
||||||
|
|
||||||
|
const sanitizeString = (string) => {
|
||||||
|
for (const i in illegalCharacters) {
|
||||||
|
string = string.replaceAll("/", "_").replaceAll("\\", "_")
|
||||||
|
.replaceAll(illegalCharacters[i], '')
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
export default (f, style, isAudioOnly, isAudioMuted) => {
|
export default (f, style, isAudioOnly, isAudioMuted) => {
|
||||||
let filename = '';
|
let filename = '';
|
||||||
|
|
||||||
|
@ -5,7 +15,7 @@ export default (f, style, isAudioOnly, isAudioMuted) => {
|
||||||
let classicTags = [...infoBase];
|
let classicTags = [...infoBase];
|
||||||
let basicTags = [];
|
let basicTags = [];
|
||||||
|
|
||||||
const title = `${f.title} - ${f.author}`;
|
const title = `${sanitizeString(f.title)} - ${sanitizeString(f.author)}`;
|
||||||
|
|
||||||
if (f.resolution) {
|
if (f.resolution) {
|
||||||
classicTags.push(f.resolution);
|
classicTags.push(f.resolution);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { genericUserAgent, env } from "../../config.js";
|
import { genericUserAgent, env } from "../../config.js";
|
||||||
import { cleanString } from "../../misc/utils.js";
|
|
||||||
|
|
||||||
const resolutions = {
|
const resolutions = {
|
||||||
"ultra": "2160",
|
"ultra": "2160",
|
||||||
|
@ -44,8 +43,8 @@ export default async function(o) {
|
||||||
let bestVideo = videos.find(v => resolutions[v.name] === quality) || videos[videos.length - 1];
|
let bestVideo = videos.find(v => resolutions[v.name] === quality) || videos[videos.length - 1];
|
||||||
|
|
||||||
let fileMetadata = {
|
let fileMetadata = {
|
||||||
title: cleanString(videoData.movie.title.trim()),
|
title: videoData.movie.title.trim(),
|
||||||
author: cleanString((videoData.author?.name || videoData.compilationTitle).trim()),
|
author: (videoData.author?.name || videoData.compilationTitle).trim(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestVideo) return {
|
if (bestVideo) return {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import HLS from "hls-parser";
|
import HLS from "hls-parser";
|
||||||
|
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { cleanString } from "../../misc/utils.js";
|
|
||||||
|
|
||||||
async function requestJSON(url) {
|
async function requestJSON(url) {
|
||||||
try {
|
try {
|
||||||
|
@ -59,8 +57,8 @@ export default async function(obj) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileMetadata = {
|
const fileMetadata = {
|
||||||
title: cleanString(play.title.trim()),
|
title: play.title.trim(),
|
||||||
artist: cleanString(play.author.name.trim()),
|
artist: play.author.name.trim(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { cleanString } from "../../misc/utils.js";
|
|
||||||
|
|
||||||
const cachedID = {
|
const cachedID = {
|
||||||
version: '',
|
version: '',
|
||||||
|
@ -91,8 +90,8 @@ export default async function(obj) {
|
||||||
if (!file) return { error: "fetch.empty" };
|
if (!file) return { error: "fetch.empty" };
|
||||||
|
|
||||||
let fileMetadata = {
|
let fileMetadata = {
|
||||||
title: cleanString(json.title.trim()),
|
title: json.title.trim(),
|
||||||
artist: cleanString(json.user.username.trim()),
|
artist: json.user.username.trim(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { cleanString } from '../../misc/utils.js';
|
|
||||||
|
|
||||||
const gqlURL = "https://gql.twitch.tv/gql";
|
const gqlURL = "https://gql.twitch.tv/gql";
|
||||||
const clientIdHead = { "client-id": "kimne78kx3ncx6brgo4mv6wki5h1ko" };
|
const clientIdHead = { "client-id": "kimne78kx3ncx6brgo4mv6wki5h1ko" };
|
||||||
|
@ -73,13 +72,13 @@ export default async function (obj) {
|
||||||
token: req_token[0].data.clip.playbackAccessToken.value
|
token: req_token[0].data.clip.playbackAccessToken.value
|
||||||
})}`,
|
})}`,
|
||||||
fileMetadata: {
|
fileMetadata: {
|
||||||
title: cleanString(clipMetadata.title.trim()),
|
title: clipMetadata.title.trim(),
|
||||||
artist: `Twitch Clip by @${clipMetadata.broadcaster.login}, clipped by @${clipMetadata.curator.login}`,
|
artist: `Twitch Clip by @${clipMetadata.broadcaster.login}, clipped by @${clipMetadata.curator.login}`,
|
||||||
},
|
},
|
||||||
filenameAttributes: {
|
filenameAttributes: {
|
||||||
service: "twitch",
|
service: "twitch",
|
||||||
id: clipMetadata.id,
|
id: clipMetadata.id,
|
||||||
title: cleanString(clipMetadata.title.trim()),
|
title: clipMetadata.title.trim(),
|
||||||
author: `${clipMetadata.broadcaster.login}, clipped by ${clipMetadata.curator.login}`,
|
author: `${clipMetadata.broadcaster.login}, clipped by ${clipMetadata.curator.login}`,
|
||||||
qualityLabel: `${format.quality}p`,
|
qualityLabel: `${format.quality}p`,
|
||||||
extension: 'mp4'
|
extension: 'mp4'
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import HLS from "hls-parser";
|
import HLS from "hls-parser";
|
||||||
|
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { cleanString, merge } from '../../misc/utils.js';
|
|
||||||
|
|
||||||
const resolutionMatch = {
|
const resolutionMatch = {
|
||||||
"3840": 2160,
|
"3840": 2160,
|
||||||
|
@ -152,8 +150,8 @@ export default async function(obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileMetadata = {
|
const fileMetadata = {
|
||||||
title: cleanString(info.name),
|
title: info.name,
|
||||||
artist: cleanString(info.user.name),
|
artist: info.user.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
return merge(
|
return merge(
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { cleanString } from "../../misc/utils.js";
|
|
||||||
import { genericUserAgent, env } from "../../config.js";
|
import { genericUserAgent, env } from "../../config.js";
|
||||||
|
|
||||||
const resolutions = ["2160", "1440", "1080", "720", "480", "360", "240"];
|
const resolutions = ["2160", "1440", "1080", "720", "480", "360", "240"];
|
||||||
|
@ -43,8 +42,8 @@ export default async function(o) {
|
||||||
url = js.player.params[0][`url${quality}`];
|
url = js.player.params[0][`url${quality}`];
|
||||||
|
|
||||||
let fileMetadata = {
|
let fileMetadata = {
|
||||||
title: cleanString(js.player.params[0].md_title.trim()),
|
title: js.player.params[0].md_title.trim(),
|
||||||
author: cleanString(js.player.params[0].md_author.trim()),
|
author: js.player.params[0].md_author.trim(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url) return {
|
if (url) return {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { fetch } from "undici";
|
||||||
import { Innertube, Session } from "youtubei.js";
|
import { Innertube, Session } from "youtubei.js";
|
||||||
|
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { cleanString } from "../../misc/utils.js";
|
|
||||||
import { getCookie, updateCookieValues } from "../cookie/manager.js";
|
import { getCookie, updateCookieValues } from "../cookie/manager.js";
|
||||||
|
|
||||||
const PLAYER_REFRESH_PERIOD = 1000 * 60 * 15; // ms
|
const PLAYER_REFRESH_PERIOD = 1000 * 60 * 15; // ms
|
||||||
|
@ -403,8 +402,8 @@ export default async function(o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileMetadata = {
|
const fileMetadata = {
|
||||||
title: cleanString(basicInfo.title.trim()),
|
title: basicInfo.title.trim(),
|
||||||
artist: cleanString(basicInfo.author.replace("- Topic", "").trim())
|
artist: basicInfo.author.replace("- Topic", "").trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basicInfo?.short_description?.startsWith("Provided to YouTube by")) {
|
if (basicInfo?.short_description?.startsWith("Provided to YouTube by")) {
|
||||||
|
|
Loading…
Reference in a new issue