saveapi.org

Node.js'da ijtimoiy tarmoq videosini yuklab olish

Butun mijoz — bitta fetch chaqiruvi. Vaqtni uning atrofidagi narsalar oladi: yechilgan manzilni o'z foydalanuvchingiz bosadigan yuklamaga aylantirish, sekin manba handlerni osib qo'ymasligi va qaysi xato qaytarib bo'lmasligini bilish. Hammasi quyida.

Yangilangan

Birinchi chaqiruv

Node 18'dan beri fetch ichida bor, ya'ni o'rnatiladigan mijoz kutubxonasi yo'q. Nusxa olishga arziydigan qismi — AbortSignal.timeout: usiz sekin manba handlerni platforma o'ldirguncha tirik ushlab turadi.

JavaScript
const API = "https://api.saveapi.org/v1/download";

async function resolve(link) {
  const res = await fetch(API + "?url=" + encodeURIComponent(link), {
    headers: { Authorization: "Bearer sk_live_xxxx" },
    signal: AbortSignal.timeout(30_000),
  });
  return res.json();
}

Javobni o'qing

medias[] postdagi hamma faylni o'z tartibida saqlaydi. TikTok slayd-shousi rasm yozuvlarini va fon musiqasi uchun alohida audio yozuvini beradi, shuning uchun medias[0] ga umid qilmasdan type bo'yicha find() qiling.

JavaScript
const data = await resolve("https://www.tiktok.com/@user/video/123");

if (!data.success) throw new Error(data.error.code);

const video = data.medias.find((m) => m.type === "video");
const images = data.medias.filter((m) => m.type === "image");
const audio = data.medias.find((m) => m.type === "audio");

Faylni foydalanuvchiga oqizing

Agar foydalanuvchilaringiz yuklash tugmasini bossa, faylni xotirada to'plamang va ularni manba CDN'iga yo'naltirmang — havola imzolangan va tez o'chadi. Upstream tanasini o'z javobingizga pipe qiling va Content-Disposition sarlavhasi bilan brauzer uni siz tanlagan nom bilan saqlaydi.

JavaScript
import { Readable } from "node:stream";

app.get("/save", async (req, res) => {
  const data = await resolve(req.query.url);
  if (!data.success) return res.status(400).json(data.error);

  const upstream = await fetch(data.medias[0].url);
  res.setHeader("Content-Type", "video/mp4");
  res.setHeader("Content-Disposition", 'attachment; filename="video.mp4"');
  Readable.fromWeb(upstream.body).pipe(res);
});

Faqat qaytarib bo'ladigan xatoni qayta urinib ko'ring

Timeout va upstream xatosi ikkinchi urinishga arziydi. Yopiq, topilmagan va qo'llab-quvvatlanmaydigan javoblar esa yakuniy — ularni takrorlash vaqtni, hisoblanadigan xatolarda esa kreditni ham behuda sarflaydi. Qayta uriniladigan kodlarni Set ichida saqlang, qoida bitta joyda tursin.

JavaScript
const RETRY = new Set(["UPSTREAM_TIMEOUT", "UPSTREAM_ERROR"]);

async function withRetry(link) {
  for (let attempt = 0; attempt < 2; attempt++) {
    const data = await resolve(link);
    if (data.success) return data;
    if (!RETRY.has(data.error.code)) throw new Error(data.error.message);
  }
  throw new Error("source unavailable");
}

Qo'lingizdagi sarlavhalarni o'qing

Har javobda daqiqalik chegara, undan qolgani va qolgan kredit bor. Chegaralanishdan oldin sekinlashish va paket tugayotganida ogohlantirish uchun shuning o'zi yetarli — qo'shimcha so'rovsiz.

JavaScript
const res = await fetch(API + "?url=" + encodeURIComponent(link), { headers });

const perMinute = Number(res.headers.get("X-RateLimit-Limit"));
const left = Number(res.headers.get("X-RateLimit-Remaining"));
const credits = Number(res.headers.get("X-Credits-Remaining"));

Kredit sarflashdan oldin havolani tekshiring

Foydalanuvchi ixtiyoriy matn tashlaydigan joyda /v1/detect havola qaysi platformaga tegishli ekanini kreditga tegmasdan aytadi. U rate limitga kiradi, ya'ni bu bepul zond emas, tekshirish qadami.

JavaScript
const check = await fetch(
  "https://api.saveapi.org/v1/detect?url=" + encodeURIComponent(userInput),
  { headers },
);
const { platform } = await check.json();   // kredit sarflanmaydi

Boshlashdan oldingi savollar

Buni brauzerdan chaqirsa bo'ladimi?
Texnik jihatdan ha, lekin kerak emas: kalit bundlingizda hammaga ko'rinib qoladi. Chaqiruvni serveringizdagi marshrutga qo'ying — qayta urinish mantig'i va chegaralarni boshqarish ham o'sha yerga tegishli.
Javob uchun TypeScript tipi bormi?
Shakl barqaror va o'zingiz e'lon qiladigan darajada kichik — success, platform, type, medias[], ixtiyoriy formats[], meta va credits. Uni o'zingizda e'lon qilish yana bir foyda beradi: yangi ixtiyoriy maydon buildingizni buzolmaydi.
Nega media manziliga yo'naltirmay, oqizish kerak?
CDN havolasi imzolangan va qisqa umrli, yo'naltirish esa uni ochib qo'yadi. O'z marshrutingiz orqali oqizsangiz, fayl nomi, Content-Type va havolaning umri sizning nazoratingizda qoladi.

Bu yerda ishlatilgan platformalar

Boshqa qo'llanmalar

Qo'llanmani o'z kalitingiz bilan ishga tushiring

Kalit bir daqiqada. 1 000 bepul kredit, kartasiz, muddatsiz.

Kalit oling va sinab ko'ringTo'liq API ma'lumotnomasi