frontAnswerer/lib/ui_kit/VideoIframe/helper.ts
2024-06-17 17:12:53 +03:00

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 };
};