Загрузить файлы в «/»

Модуль для загрузки из популярный соц сетей видео (tiktok,YouTube,vk,Instagram)
This commit is contained in:
yanistyle
2026-08-31 17:00:14 +03:00
parent 1312cf3d5f
commit c10df870ab
+271
View File
@@ -0,0 +1,271 @@
# meta developer: @origsama
from .. import loader, utils
import requests
import re
import os
import subprocess
import tempfile
import urllib.parse
import json
@loader.tds
class SocialDownloaderMod(loader.Module):
"""Скачивание видео из TikTok, Instagram, YouTube, VK"""
strings = {"name": "SocialDownloader"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"max_size",
50,
"Максимальный размер видео в МБ",
validator=loader.validators.Integer()
)
)
async def dlcmd(self, message):
"""<ссылка> - Скачать видео из TikTok/Instagram/YouTube/VK"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message,
"❌ Укажи ссылку на видео\n\n"
"Поддерживаемые сайты:\n"
"• TikTok: https://vm.tiktok.com/...\n"
"• Instagram: https://www.instagram.com/p/...\n"
"• YouTube: https://youtu.be/...\n"
"• VK: https://vk.com/video...\n"
"• Twitter/X: https://twitter.com/...\n"
"• Reddit: https://reddit.com/..."
)
return
# Определяем источник
source = self.detect_source(args)
if not source:
await utils.answer(message, "❌ Неподдерживаемая ссылка")
return
status = await utils.answer(message, f"📥 Скачиваю с {source}...")
try:
# Скачиваем видео
video_path, info = await self.download_video(args, source)
if not video_path:
await status.edit("❌ Не удалось скачать видео")
return
# Формируем описание
caption = f"<b>📹 Видео с {source}</b>\n\n"
if info.get('title'):
caption += f"📝 {info['title']}\n"
if info.get('author'):
caption += f"👤 {info['author']}\n"
if info.get('duration'):
caption += f"⏱ {info['duration']}\n"
caption += f"\n🔗 <a href='{args}'>Оригинал</a>"
# Отправляем
await status.delete()
await message.client.send_file(
message.chat_id,
video_path,
caption=caption,
reply_to=message.reply_to_msg_id or message.id
)
# Чистим
os.remove(video_path)
except Exception as e:
await status.edit(f"❌ Ошибка: {str(e)}")
def detect_source(self, url):
"""Определяет источник по ссылке"""
url = url.lower()
sources = {
'tiktok': ['tiktok.com', 'vm.tiktok.com'],
'instagram': ['instagram.com', 'instagr.am'],
'youtube': ['youtube.com', 'youtu.be', 'm.youtube.com'],
'vk': ['vk.com', 'vkontakte.ru'],
'twitter': ['twitter.com', 'x.com'],
'reddit': ['reddit.com', 'redd.it'],
'facebook': ['facebook.com', 'fb.com'],
'pinterest': ['pinterest.com', 'pin.it']
}
for source, domains in sources.items():
for domain in domains:
if domain in url:
return source.capitalize()
return None
async def download_video(self, url, source):
"""Скачивает видео через yt-dlp"""
try:
# Создаем временную папку
with tempfile.TemporaryDirectory() as temp_dir:
output_template = os.path.join(temp_dir, '%(title)s.%(ext)s')
# Формируем команду
cmd = [
'yt-dlp',
'-f', 'best[filesize<50M]', # Лучшее качество до 50 МБ
'--max-filesize', f"{self.config['max_size']}M",
'-o', output_template,
url
]
# Добавляем специфичные опции
if source.lower() == 'tiktok':
cmd.extend(['--cookies', 'tiktok_cookies.txt']) # Опционально
elif source.lower() == 'instagram':
cmd.extend(['--cookies', 'instagram_cookies.txt'])
# Запускаем
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
return None, {}
# Ищем скачанный файл
for file in os.listdir(temp_dir):
file_path = os.path.join(temp_dir, file)
if os.path.isfile(file_path):
# Копируем в постоянное место
import shutil
final_path = os.path.join(tempfile.gettempdir(), file)
shutil.copy2(file_path, final_path)
# Получаем информацию
info = await self.get_video_info(url)
return final_path, info
return None, {}
except Exception as e:
print(f"Download error: {e}")
return None, {}
async def get_video_info(self, url):
"""Получает информацию о видео"""
try:
cmd = [
'yt-dlp',
'--dump-json',
'--no-playlist',
url
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
data = json.loads(result.stdout)
duration = data.get('duration', 0)
minutes = duration // 60
seconds = duration % 60
return {
'title': data.get('title', ''),
'author': data.get('uploader', data.get('channel', '')),
'duration': f"{minutes}:{seconds:02d}" if duration else ''
}
return {}
except:
return {}
async def tiktokcmd(self, message):
"""<ссылка> - Скачать видео с TikTok"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, "❌ Укажи ссылку на TikTok")
return
await self.dlcmd(message)
async def instacmd(self, message):
"""<ссылка> - Скачать видео/фото с Instagram"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, "❌ Укажи ссылку на Instagram")
return
await self.dlcmd(message)
async def ytcmd(self, message):
"""<ссылка> [качество] - Скачать видео с YouTube"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, "❌ Укажи ссылку на YouTube")
return
# Разбираем качество если указано
parts = args.split()
url = parts[0]
quality = parts[1] if len(parts) > 1 else 'best'
await utils.answer(message, f"📥 Скачиваю с YouTube ({quality})...")
try:
with tempfile.TemporaryDirectory() as temp_dir:
output_template = os.path.join(temp_dir, '%(title)s.%(ext)s')
cmd = [
'yt-dlp',
'-f', f'best[height<={quality}]' if quality != 'best' else 'best',
'--max-filesize', f"{self.config['max_size']}M",
'-o', output_template,
url
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
await utils.answer(message, "❌ Ошибка скачивания")
return
for file in os.listdir(temp_dir):
file_path = os.path.join(temp_dir, file)
if os.path.isfile(file_path):
import shutil
final_path = os.path.join(tempfile.gettempdir(), file)
shutil.copy2(file_path, final_path)
info = await self.get_video_info(url)
caption = f"<b>🎥 YouTube</b>\n"
if info.get('title'):
caption += f"📝 {info['title']}\n"
if info.get('author'):
caption += f"👤 {info['author']}\n"
if info.get('duration'):
caption += f"⏱ {info['duration']}\n"
caption += f"\n⚙️ {quality}"
await message.client.send_file(
message.chat_id,
final_path,
caption=caption
)
os.remove(final_path)
return
except Exception as e:
await utils.answer(message, f"❌ Ошибка: {str(e)}")
async def vkcmd(self, message):
"""<ссылка> - Скачать видео с VK"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, "❌ Укажи ссылку на VK видео")
return
await self.dlcmd(message)