It's version 0.4
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
def register(dp, state, bot):
|
||||
from . import handlers
|
||||
|
||||
handlers.register_handlers(dp, state, bot)
|
||||
|
||||
|
||||
def unregister(dp):
|
||||
# Здесь можно удалить хендлеры, если нужно
|
||||
dp.message_handlers.handlers.clear()
|
||||
|
||||
@@ -12,8 +12,8 @@ import uuid
|
||||
from config import Config
|
||||
|
||||
# Настройка кодировки для всего приложения
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -24,13 +24,15 @@ LIMIT = 2 * 1024 * 1024 * 1024 # 2 ГБ
|
||||
async def safe_filename(name: str) -> str:
|
||||
"""Создает безопасное имя файла"""
|
||||
# Нормализуем Unicode символы
|
||||
normalized = unicodedata.normalize('NFKD', name)
|
||||
normalized = unicodedata.normalize("NFKD", name)
|
||||
# Убираем акценты и специальные символы, оставляем только ASCII
|
||||
ascii_name = normalized.encode('ascii', 'ignore').decode('ascii')
|
||||
ascii_name = normalized.encode("ascii", "ignore").decode("ascii")
|
||||
# Заменяем проблемные символы
|
||||
safe_name = "".join(c if c.isalnum() or c in (' ', '-', '_', '.') else '_' for c in ascii_name)
|
||||
safe_name = "".join(
|
||||
c if c.isalnum() or c in (" ", "-", "_", ".") else "_" for c in ascii_name
|
||||
)
|
||||
# Убираем множественные подчеркивания и обрезаем длину
|
||||
safe_name = '_'.join(filter(None, safe_name.split('_')))
|
||||
safe_name = "_".join(filter(None, safe_name.split("_")))
|
||||
return safe_name[:100] or f"video_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
|
||||
@@ -38,21 +40,23 @@ async def get_video_info(url: str) -> dict:
|
||||
"""Получает информацию о видео через yt-dlp"""
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
'yt-dlp',
|
||||
'--dump-json',
|
||||
'--no-playlist',
|
||||
"yt-dlp",
|
||||
"--dump-json",
|
||||
"--no-playlist",
|
||||
url,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
stdout, stderr = await process.communicate()
|
||||
|
||||
if process.returncode == 0:
|
||||
result = json.loads(stdout.decode('utf-8', errors='ignore'))
|
||||
logger.info(f"Информация о видео получена: {result.get('title', 'Unknown')}")
|
||||
result = json.loads(stdout.decode("utf-8", errors="ignore"))
|
||||
logger.info(
|
||||
f"Информация о видео получена: {result.get('title', 'Unknown')}"
|
||||
)
|
||||
return result
|
||||
else:
|
||||
error_msg = stderr.decode('utf-8', errors='ignore')
|
||||
error_msg = stderr.decode("utf-8", errors="ignore")
|
||||
logger.warning(f"yt-dlp ошибка: {error_msg}")
|
||||
|
||||
except Exception as e:
|
||||
@@ -75,38 +79,54 @@ async def download_mp4_to_dropbox(url: str) -> tuple[str, dict]:
|
||||
duration = 0
|
||||
|
||||
if video_info:
|
||||
title = await safe_filename(video_info.get('title', 'Unknown_Title'))
|
||||
uploader = await safe_filename(video_info.get('uploader', 'Unknown_Uploader'))
|
||||
duration = video_info.get('duration', 0)
|
||||
title = await safe_filename(video_info.get("title", "Unknown_Title"))
|
||||
uploader = await safe_filename(
|
||||
video_info.get("uploader", "Unknown_Uploader")
|
||||
)
|
||||
duration = video_info.get("duration", 0)
|
||||
logger.info(f"Обработано видео: {title}")
|
||||
|
||||
# ОПТИМИЗИРОВАННЫЕ НАСТРОЙКИ ДЛЯ СКОРОСТИ
|
||||
download_process = await asyncio.create_subprocess_exec(
|
||||
'yt-dlp',
|
||||
'-f', 'bestvideo[height<=720][filesize<800M]+bestaudio/best[height<=720][filesize<800M]',
|
||||
'--no-playlist',
|
||||
'-o', output_template,
|
||||
'--ignore-errors',
|
||||
'--no-warnings',
|
||||
'--format-sort', 'quality,res:720,size:800M',
|
||||
'--concurrent-fragments', '4',
|
||||
"yt-dlp",
|
||||
"-f",
|
||||
"bestvideo[height<=720][filesize<800M]+bestaudio/best[height<=720][filesize<800M]",
|
||||
"--no-playlist",
|
||||
"-o",
|
||||
output_template,
|
||||
"--ignore-errors",
|
||||
"--no-warnings",
|
||||
"--format-sort",
|
||||
"quality,res:720,size:800M",
|
||||
"--concurrent-fragments",
|
||||
"4",
|
||||
url,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
|
||||
stdout, stderr = await asyncio.wait_for(download_process.communicate(), timeout=600) # Уменьшил таймаут
|
||||
stdout, stderr = await asyncio.wait_for(
|
||||
download_process.communicate(), timeout=600
|
||||
) # Уменьшил таймаут
|
||||
|
||||
# Остальной код без изменений...
|
||||
if download_process.returncode != 0:
|
||||
error_msg = stderr.decode('utf-8', errors='ignore') if stderr else "Unknown error"
|
||||
error_msg = (
|
||||
stderr.decode("utf-8", errors="ignore")
|
||||
if stderr
|
||||
else "Unknown error"
|
||||
)
|
||||
logger.error(f"Ошибка скачивания: {error_msg}")
|
||||
raise Exception(f"Ошибка скачивания: {error_msg}")
|
||||
|
||||
mp4_files = glob.glob(os.path.join(temp_dir, "*.mp4"))
|
||||
if not mp4_files:
|
||||
video_files = glob.glob(os.path.join(temp_dir, "*.*"))
|
||||
video_files = [f for f in video_files if f.lower().endswith(('.mp4', '.mkv', '.avi', '.mov', '.webm'))]
|
||||
video_files = [
|
||||
f
|
||||
for f in video_files
|
||||
if f.lower().endswith((".mp4", ".mkv", ".avi", ".mov", ".webm"))
|
||||
]
|
||||
if video_files:
|
||||
mp4_files = [video_files[0]]
|
||||
|
||||
@@ -123,25 +143,27 @@ async def download_mp4_to_dropbox(url: str) -> tuple[str, dict]:
|
||||
dbx = dropbox.Dropbox(DROPBOX_TOKEN)
|
||||
dropbox_path = f"/{final_filename}"
|
||||
|
||||
logger.info(f"Загружаем файл в Dropbox: {dropbox_path} (размер: {size / (1024 * 1024):.1f} MB)")
|
||||
logger.info(
|
||||
f"Загружаем файл в Dropbox: {dropbox_path} (размер: {size / (1024 * 1024):.1f} MB)"
|
||||
)
|
||||
|
||||
with open(actual_file, "rb") as f:
|
||||
file_data = f.read()
|
||||
dbx.files_upload(
|
||||
file_data,
|
||||
dropbox_path,
|
||||
mode=dropbox.files.WriteMode("overwrite")
|
||||
mode=dropbox.files.WriteMode("overwrite"),
|
||||
)
|
||||
|
||||
shared_link = dbx.sharing_create_shared_link_with_settings(dropbox_path)
|
||||
link = shared_link.url.replace("?dl=0", "?dl=1")
|
||||
|
||||
metadata = {
|
||||
'title': title,
|
||||
'uploader': uploader,
|
||||
'duration': duration,
|
||||
'filesize': size,
|
||||
'quality': 'optimized for speed'
|
||||
"title": title,
|
||||
"uploader": uploader,
|
||||
"duration": duration,
|
||||
"filesize": size,
|
||||
"quality": "optimized for speed",
|
||||
}
|
||||
|
||||
logger.info(f"Успешно загружено в Dropbox: {link}")
|
||||
@@ -154,5 +176,3 @@ async def download_mp4_to_dropbox(url: str) -> tuple[str, dict]:
|
||||
except Exception as e:
|
||||
logger.error(f"Общая ошибка: {e}")
|
||||
raise e
|
||||
|
||||
|
||||
|
||||
@@ -2,18 +2,16 @@ import logging
|
||||
from aiogram import Dispatcher, Bot
|
||||
from aiogram.filters import Command
|
||||
from models.state import BotState
|
||||
from utils.antispam import admin_required
|
||||
|
||||
from .dowmp4 import download_mp4_to_dropbox
|
||||
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||
@dp.message(Command("dowmp4"))
|
||||
#@admin_required(4)
|
||||
# @admin_required(4)
|
||||
async def dowmp4_handler(message):
|
||||
"""Обработчик команды /dowmp4"""
|
||||
try:
|
||||
@@ -22,7 +20,9 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||
await message.answer("Пожалуйста, укажите URL видео после команды /dowmp4")
|
||||
return
|
||||
|
||||
processing_msg = await message.answer("⏳ Начинаю обработку видео... Это может занять несколько минут.")
|
||||
processing_msg = await message.answer(
|
||||
"⏳ Начинаю обработку видео... Это может занять несколько минут."
|
||||
)
|
||||
|
||||
try:
|
||||
# Скачиваем и загружаем в Dropbox
|
||||
@@ -44,12 +44,13 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||
await message.answer(
|
||||
f"✅ **Видео успешно обработано!**\n\n{caption}",
|
||||
parse_mode="Markdown",
|
||||
disable_web_page_preview=True
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при обработке /dowmp4: {e}", exc_info=True)
|
||||
await message.answer("❌ Произошла ошибка при обработке видео. Попробуйте позже.")
|
||||
|
||||
await message.answer(
|
||||
"❌ Произошла ошибка при обработке видео. Попробуйте позже."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user