api.3 / app /tik_dl.py
Celeskry's picture
Update app/tik_dl.py
c80ab79 verified
# app/tik_dl.py
import httpx
import re
import asyncio
from datetime import datetime
class TiktokDl:
def __init__(self):
self.api_url = "https://tikwm.com/api/"
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
}
self.meta_info = {
"powered_by": "devily",
"version": "0.6.0",
"support": "https://t.me/Dev_Celeste"
}
def _format_size(self, size_bytes):
if not size_bytes: return "0 MB"
return f"{round(size_bytes / (1024 * 1024), 2)} MB"
def _estimate_audio_size(self, duration, audio_type="mp3"):
if not duration: return "0 MB"
if audio_type == "mp3":
size_bytes = duration * 192 * 1024 / 8
else:
size_bytes = duration * 44100 * 2 * 2
return self._format_size(size_bytes)
async def fetch_video(self, tiktok_url: str, tik_direct, hd: int = 1):
try:
params = {"url": tiktok_url, "hd": hd}
async with httpx.AsyncClient(timeout=15.0, headers=self.headers) as client:
response = await client.get(self.api_url, params=params)
if response.status_code != 200:
return {"ok": False, "error": "TikWM Connection Error"}
raw = response.json()
if raw.get("code") != 0:
return {"ok": False, "error": raw.get("msg")}
d = raw["data"]
duration = d.get("duration", 0)
source_video_url = d.get("hdplay") or d.get("play")
token_video = tik_direct.create_instant_token(source_video_url, "mp4")
token_audio_mp3 = tik_direct.create_instant_token(source_video_url, "mp3_convert")
token_audio_wav = tik_direct.create_instant_token(source_video_url, "wav_convert")
token_cover = tik_direct.create_instant_token(d.get("cover"), "jpg")
token_dynamic_cover = tik_direct.create_instant_token(d.get("ai_dynamic_cover"), "jpg")
token_avatar = tik_direct.create_instant_token(d.get("author", {}).get("avatar"), "jpg")
return {
"ok": True,
"status": "success",
"processed_at": datetime.now().isoformat(),
"meta": self.meta_info,
"video_info": {
"id": d.get("id"),
"region": d.get("region"),
"title": d.get("title", ""),
"cover": token_cover,
"dynamic_cover": token_dynamic_cover,
"duration": duration,
"created_at": datetime.fromtimestamp(d.get("create_time")).strftime('%Y-%m-%d %H:%M:%S') if d.get("create_time") else None,
"is_ad": d.get("is_ad", False)
},
"download_links": {
"video": token_video,
"audio_mp3": token_audio_mp3,
"audio_wav": token_audio_wav,
"direct_cover": token_cover,
"note": "CaC"
},
"music_info": {
"id": d.get("music_info", {}).get("id"),
"title": d.get("music_info", {}).get("title"),
"author": d.get("music_info", {}).get("author"),
"duration": d.get("music_info", {}).get("duration")
},
"stats": {
"likes": d.get("digg_count"),
"views": d.get("play_count"),
"shares": d.get("share_count"),
"comments": d.get("comment_count"),
"collects": d.get("collect_count")
},
"author": {
"unique_id": d.get("author", {}).get("unique_id"),
"nickname": d.get("author", {}).get("nickname"),
"avatar": token_avatar,
"verified": d.get("author", {}).get("verified", False)
},
"assets_info": {
"mp4_size": self._format_size(d.get("hd_size")),
"mp3_size": self._estimate_audio_size(duration, "mp3"),
"wav_size": self._estimate_audio_size(duration, "wav")
}
}
except Exception as e:
return {"ok": False, "error": f"Internal Error: {str(e)}"}