feat: added tiktok downloader v3
This commit is contained in:
parent
6f18c5112e
commit
f5849a600f
@ -2,3 +2,6 @@ export const _tiktokurl: string = "https://www.tiktok.com"
|
||||
export const _tiktokapi = (id: string): string => `https://api.tiktokv.com/aweme/v1/feed/?aweme_id=${id}`
|
||||
export const _ssstikapi: string = "https://ssstik.io/abc?url=dl"
|
||||
export const _ssstikurl: string = "https://ssstik.io"
|
||||
export const _musicaldownapi: string = "https://musicaldown.com/download"
|
||||
export const _musicaldownurl: string = "https://musicaldown.com"
|
||||
export const _musicaldownmusicapi: string = "https://musicaldown.com/mp3/download"
|
||||
|
||||
32
src/types/musicaldown.ts
Normal file
32
src/types/musicaldown.ts
Normal file
@ -0,0 +1,32 @@
|
||||
export interface getRequest {
|
||||
status: "success" | "error"
|
||||
request?: {
|
||||
[key: string]: string
|
||||
}
|
||||
message?: string
|
||||
cookie?: string
|
||||
}
|
||||
|
||||
export interface MusicalDownResponse {
|
||||
status: "success" | "error"
|
||||
message?: string
|
||||
result?: {
|
||||
type: "video" | "image"
|
||||
desc?: string
|
||||
author: {
|
||||
avatar?: string
|
||||
nickname: string
|
||||
}
|
||||
music?: string
|
||||
images?: string[]
|
||||
video1?: string
|
||||
video2?: string
|
||||
video_hd?: string
|
||||
video_watermark?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface getMusic {
|
||||
status: "success" | "error"
|
||||
result?: string
|
||||
}
|
||||
123
src/utils/musicaldown.ts
Normal file
123
src/utils/musicaldown.ts
Normal file
@ -0,0 +1,123 @@
|
||||
import Axios from "axios"
|
||||
import { load } from "cheerio"
|
||||
import { MusicalDownResponse, getMusic, getRequest } from "../types/musicaldown"
|
||||
import { _musicaldownapi, _musicaldownmusicapi, _musicaldownurl } from "../api"
|
||||
|
||||
/**
|
||||
* Using API from Website:
|
||||
* BASE URL : https://ssstik.io
|
||||
*/
|
||||
|
||||
const getRequest = (url: string) =>
|
||||
new Promise<getRequest>((resolve, reject) => {
|
||||
Axios.get(_musicaldownurl, {
|
||||
headers: {
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0"
|
||||
}
|
||||
})
|
||||
.then((data) => {
|
||||
const cookie = data.headers["set-cookie"][0].split(";")[0] + "; " + "lang=en"
|
||||
const $ = load(data.data)
|
||||
const input = $("div > input").map((_, el) => $(el))
|
||||
const request = {
|
||||
[input.get(0).attr("name")]: url,
|
||||
[input.get(1).attr("name")]: input.get(1).attr("value"),
|
||||
[input.get(2).attr("name")]: input.get(2).attr("value")
|
||||
}
|
||||
resolve({ status: "success", request, cookie })
|
||||
})
|
||||
.catch((e) => resolve({ status: "error", message: "Failed to get the request form!" }))
|
||||
})
|
||||
|
||||
const getMusic = (cookie: string) =>
|
||||
new Promise<getMusic>((resolve, reject) => {
|
||||
Axios.get(_musicaldownmusicapi, {
|
||||
headers: {
|
||||
cookie: cookie,
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0"
|
||||
}
|
||||
})
|
||||
.then(({ data }) => {
|
||||
const $ = load(data)
|
||||
const music = $("audio > source").attr("src")
|
||||
resolve({ status: "success", result: music })
|
||||
})
|
||||
.catch((e) => resolve({ status: "error" }))
|
||||
})
|
||||
|
||||
export const MusicalDown = (url: string) =>
|
||||
new Promise<MusicalDownResponse>(async (resolve, reject) => {
|
||||
const request: getRequest = await getRequest(url)
|
||||
if (request.status !== "success") return resolve({ status: "error", message: request.message })
|
||||
Axios(_musicaldownapi, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
cookie: request.cookie,
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0"
|
||||
},
|
||||
data: new URLSearchParams(Object.entries(request.request))
|
||||
})
|
||||
.then(async ({ data }) => {
|
||||
const $ = load(data)
|
||||
|
||||
// Get Image Video
|
||||
const images = []
|
||||
$("div.row > div[class='col s12 m3']")
|
||||
.get()
|
||||
.map((v) => {
|
||||
images.push($(v).find("img").attr("src"))
|
||||
})
|
||||
|
||||
// Get Result Video
|
||||
let i = 1
|
||||
let videos = {}
|
||||
$("div[class='col s12 l8'] > a")
|
||||
.get()
|
||||
.map((v) => {
|
||||
if ($(v).attr("href") !== "#modal2") {
|
||||
let text = $(v).text().trim().replace(/\s/, " ").replace("arrow_downward", "").toLowerCase()
|
||||
videos[text.includes("hd") ? "video_hd" : text.includes("watermark") ? "video_watermark" : `video${i}`] = $(v).attr("href")
|
||||
i++
|
||||
}
|
||||
})
|
||||
// Result
|
||||
if (images.length !== 0) {
|
||||
// Images or Slide Result
|
||||
resolve({
|
||||
status: "success",
|
||||
result: {
|
||||
type: "image",
|
||||
author: {
|
||||
nickname: $("h2.white-text").text().trim().replace("Download Now: Check out ", "").replace("’s video! #TikTok >If MusicallyDown has helped you, you can help us too", "").replace("Download Now: ", "").replace("If MusicallyDown has helped you, you can help us too", "")
|
||||
},
|
||||
images,
|
||||
music: $("a.download").attr("href")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Video Result
|
||||
const music = await getMusic(request.cookie)
|
||||
resolve({
|
||||
status: "success",
|
||||
result: {
|
||||
type: "video",
|
||||
author: {
|
||||
avatar: $("div.img-area > img").attr("src"),
|
||||
nickname: $("div.row > div > div > h2")
|
||||
.map((_, el) => $(el).text())
|
||||
.get(0)
|
||||
},
|
||||
desc: $("div.row > div > div > h2")
|
||||
.map((_, el) => $(el).text())
|
||||
.get(1),
|
||||
music: music.result,
|
||||
...videos
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((e) => resolve({ status: "error", message: e.message }))
|
||||
})
|
||||
@ -3,6 +3,11 @@ import { load } from "cheerio"
|
||||
import { Author, Statistics, SSSTikFetchTT, SSSTikResult } from "../types/ssstik"
|
||||
import { _ssstikapi, _ssstikurl } from "../api"
|
||||
|
||||
/**
|
||||
* Using API from Website:
|
||||
* BASE URL : https://ssstik.io
|
||||
*/
|
||||
|
||||
const fetchTT = () =>
|
||||
new Promise<SSSTikFetchTT>(async (resolve, reject) => {
|
||||
Axios.get(_ssstikurl, {
|
||||
@ -14,10 +19,10 @@ const fetchTT = () =>
|
||||
const regex = /form\.setAttribute\("include-vals",\s*"([^"]+)"\)/
|
||||
const match = data.match(regex)
|
||||
if (match) {
|
||||
const includeValsValue = match[1]
|
||||
resolve({ status: "success", result: includeValsValue })
|
||||
const value = match[1]
|
||||
resolve({ status: "success", result: value })
|
||||
} else {
|
||||
resolve({ status: "error", message: "Not found" })
|
||||
resolve({ status: "error", message: "Failed to get the request form!" })
|
||||
}
|
||||
})
|
||||
.catch((e) => resolve({ status: "error", message: e.message }))
|
||||
@ -39,7 +44,7 @@ export const SSSTik = (url: string) =>
|
||||
Object.entries({
|
||||
id: url,
|
||||
locale: "en",
|
||||
tt: tt.result as string
|
||||
tt: tt.result
|
||||
})
|
||||
)
|
||||
})
|
||||
@ -49,7 +54,7 @@ export const SSSTik = (url: string) =>
|
||||
// Result
|
||||
const desc = $("p.maintext").text().trim()
|
||||
const author: Author = {
|
||||
avatar: $("img.result_author").attr("src") as string,
|
||||
avatar: $("img.result_author").attr("src"),
|
||||
nickname: $("h2").text().trim()
|
||||
}
|
||||
const statistics: Statistics = {
|
||||
@ -63,7 +68,7 @@ export const SSSTik = (url: string) =>
|
||||
$("ul.splide__list > li")
|
||||
.get()
|
||||
.map((img) => {
|
||||
images.push($(img).find("img").attr("src") as string)
|
||||
images.push($(img).find("img").attr("src"))
|
||||
})
|
||||
|
||||
if (images.length !== 0) {
|
||||
@ -76,7 +81,7 @@ export const SSSTik = (url: string) =>
|
||||
author,
|
||||
statistics,
|
||||
images,
|
||||
music: $("a.music").attr("href") as string
|
||||
music: $("a.music").attr("href")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -89,7 +94,7 @@ export const SSSTik = (url: string) =>
|
||||
author,
|
||||
statistics,
|
||||
video: $("a.without_watermark").attr("href"),
|
||||
music: $("a.music").attr("href") as string
|
||||
music: $("a.music").attr("href")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { MusicalDown } from "./musicaldown"
|
||||
import { SSSTik } from "./ssstik"
|
||||
import { TiktokAPI } from "./tiktokapi"
|
||||
|
||||
export const TiktokDL = (url: string, options: { version: "v1" | "v2" }) =>
|
||||
export const TiktokDL = (url: string, options: { version: "v1" | "v2" | "v3" }) =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
switch (options.version) {
|
||||
case "v1": {
|
||||
@ -10,6 +11,9 @@ export const TiktokDL = (url: string, options: { version: "v1" | "v2" }) =>
|
||||
case "v2": {
|
||||
await SSSTik(url).then(resolve).catch(reject)
|
||||
}
|
||||
case "v3": {
|
||||
await MusicalDown(url).then(resolve).catch(reject)
|
||||
}
|
||||
default: {
|
||||
await TiktokAPI(url).then(resolve).catch(reject)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user