166 lines
4.4 KiB
TypeScript
166 lines
4.4 KiB
TypeScript
import axios from "axios";
|
|
|
|
type SourceType = "youtube" | "short" | "vk" | "google" | "yandex" | "mail" | "tiktok" | "custom";
|
|
|
|
export type VideoUrlResult = {
|
|
sourceName: SourceType;
|
|
url: string;
|
|
};
|
|
|
|
type TiktokResponse = {
|
|
version: string;
|
|
type: string;
|
|
title: string;
|
|
author_url: string;
|
|
author_name: string;
|
|
width: string;
|
|
height: string;
|
|
html: string;
|
|
thumbnail_width: number;
|
|
thumbnail_height: number;
|
|
thumbnail_url: string;
|
|
provider_url: string;
|
|
provider_name: string;
|
|
author_unique_id: string;
|
|
embed_product_id: string;
|
|
embed_type: string;
|
|
};
|
|
|
|
type YandexResponse = {
|
|
antivirus_status: string;
|
|
views_count: number;
|
|
resource_id: string;
|
|
file: string;
|
|
owner: {
|
|
login: string;
|
|
display_name: string;
|
|
uid: string;
|
|
};
|
|
size: number;
|
|
exif: unknown;
|
|
media_type: string;
|
|
preview: string;
|
|
type: string;
|
|
mime_type: string;
|
|
revision: number;
|
|
public_url: string;
|
|
path: string;
|
|
md5: string;
|
|
public_key: string;
|
|
sha256: string;
|
|
name: string;
|
|
created: string;
|
|
sizes: {
|
|
url: string;
|
|
name: string;
|
|
}[];
|
|
modified: string;
|
|
comment_ids: {
|
|
private_resource: string;
|
|
public_resource: string;
|
|
};
|
|
};
|
|
|
|
const FILTER_SITES_REGEX: Record<Exclude<SourceType, "short" | "custom">, RegExp> = {
|
|
youtube: /^(https?:\/\/)?(www\.)?((m\.youtube|youtube)\.com|youtu\.be)\/.+$/,
|
|
vk: /^(https?:\/\/)?(m.)?vk\..+$/,
|
|
tiktok: /^(https?:\/\/)?((www|vt).)?tiktok\..+$/,
|
|
google: /^(https?:\/\/)?(www.)?drive\.google\..+$/,
|
|
yandex: /^(https?:\/\/)?disk\.yandex\..+$/,
|
|
mail: /^(https?:\/\/)?cloud\.mail\..+$/,
|
|
};
|
|
|
|
const EXTRACT_VIDEO_ID_REGEX: Record<Exclude<SourceType, "custom">, RegExp> = {
|
|
youtube: /(?<=v=|v\/|d\/|be\/|embed\/)[\w-]+/,
|
|
short: /(?<=v=|v\/|d\/|be\/|embed\/)[\w-]+/,
|
|
vk: /(-?(\d+)_(\d+))/,
|
|
google: /(?<=(file\/d\/))[\w-]+/,
|
|
yandex: /(?<=i\/)[\w-]+/,
|
|
mail: /$/,
|
|
tiktok: /(?<=video\/|\.com\/)[\w-]+/,
|
|
};
|
|
|
|
export const getVideo = async (videoUrl: string): Promise<VideoUrlResult> => {
|
|
if (videoUrl.match(FILTER_SITES_REGEX.youtube)?.[0]) {
|
|
if (videoUrl.includes("youtube.com/shorts")) {
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.short)?.[0];
|
|
|
|
return {
|
|
sourceName: "short",
|
|
url: `https://www.youtube.com/embed/${videoId}?controls=0&autoplay=1&modestbranding=0&showinfo=0&disablekb=1&mute=1&loop=1`,
|
|
};
|
|
}
|
|
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.youtube)?.[0];
|
|
return {
|
|
sourceName: "youtube",
|
|
url: `https://www.youtube.com/embed/${videoId}?controls=0&autoplay=1&modestbranding=0&showinfo=0&disablekb=1&mute=1&loop=1`,
|
|
};
|
|
}
|
|
|
|
if (videoUrl.match(FILTER_SITES_REGEX.vk)) {
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.vk)?.[0];
|
|
|
|
return {
|
|
sourceName: "vk",
|
|
url: `https://vk.com/video_ext.php?oid=${videoId?.split("_")[0]}&id=${videoId?.split("_")[1]}`,
|
|
};
|
|
}
|
|
|
|
if (videoUrl.match(FILTER_SITES_REGEX.tiktok)) {
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.tiktok)?.[0] ?? "";
|
|
|
|
if (/[a-zA-Z]/.test(videoId)) {
|
|
try {
|
|
const { data } = await axios.get<TiktokResponse>("https://www.tiktok.com/oembed", {
|
|
params: { url: videoUrl },
|
|
});
|
|
|
|
return {
|
|
sourceName: "tiktok",
|
|
url: `https://www.tiktok.com/embed/v2/${data.embed_product_id}?embedFrom=embed_page_preview`,
|
|
};
|
|
} catch {}
|
|
|
|
return {
|
|
sourceName: "tiktok",
|
|
url: `https://www.tiktok.com/embed/v2/${videoId}?embedFrom=embed_page_preview`,
|
|
};
|
|
}
|
|
|
|
return {
|
|
sourceName: "tiktok",
|
|
url: `https://www.tiktok.com/embed/v2/${videoId}?embedFrom=embed_page_preview`,
|
|
};
|
|
}
|
|
|
|
if (videoUrl.match(FILTER_SITES_REGEX.google)) {
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.google)?.[0];
|
|
|
|
return {
|
|
sourceName: "google",
|
|
url: `https://drive.google.com/file/d/${videoId}/preview`,
|
|
};
|
|
}
|
|
|
|
if (videoUrl.match(FILTER_SITES_REGEX.yandex)) {
|
|
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.yandex);
|
|
|
|
try {
|
|
const { data } = await axios.get<YandexResponse>("https://cloud-api.yandex.net/v1/disk/public/resources", {
|
|
params: { public_key: `https://disk.yandex.ru/i/${videoId}` },
|
|
});
|
|
|
|
return { sourceName: "yandex", url: data.file };
|
|
} catch {}
|
|
|
|
return { sourceName: "yandex", url: "" };
|
|
}
|
|
|
|
if (videoUrl.match(FILTER_SITES_REGEX.mail)) {
|
|
return { sourceName: "mail", url: videoUrl };
|
|
}
|
|
|
|
return { sourceName: "custom", url: videoUrl };
|
|
};
|