исправление бага при отправке плейлиста

This commit is contained in:
2026-01-05 21:39:26 +07:00
parent c1fa52fa33
commit 493bc0baeb
2 changed files with 62 additions and 28 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -4,6 +4,7 @@ import os
import logging
import subprocess
import json
import shutil # Импортируем shutil глобально
from typing import List, Optional
logger = logging.getLogger(__name__)
@@ -46,8 +47,8 @@ def download_video(
"tiktok": {"skip_impersonation": True},
"instagram": {"skip_impersonation": True},
},
"writedescription": True, # Сохраняем описание
"writeinfojson": True, # Сохраняем информацию в JSON
"writedescription": True,
"writeinfojson": True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
@@ -55,9 +56,11 @@ def download_video(
# Сохраняем информацию о видео рядом с файлом
info_file = out_path.replace('.mp4', '.info.json')
if os.path.exists(info_file):
try:
with open(info_file, 'w', encoding='utf-8') as f:
json.dump(info, f, ensure_ascii=False, indent=2)
except:
pass
# ---------------- ORIGINAL QUALITY ----------------
@@ -71,7 +74,7 @@ def download_original_quality(
):
"""Скачивает видео в оригинальном качестве"""
ydl_opts = {
"format": "best", # Лучшее качество доступное
"format": "best",
"outtmpl": out_path,
"merge_output_format": "mp4",
"cookiefile": cookies,
@@ -92,9 +95,11 @@ def download_original_quality(
# Сохраняем информацию о видео
info_file = out_path.replace('.mp4', '.info.json')
if os.path.exists(info_file):
try:
with open(info_file, 'w', encoding='utf-8') as f:
json.dump(info, f, ensure_ascii=False, indent=2)
except:
pass
# ---------------- TIKTOK MUSIC ONLY ----------------
@@ -106,7 +111,7 @@ def download_tiktok_music(
cancel_event: threading.Event,
progress_cb,
):
"""Скачивает только звук из TikTok (оригинальную музыку)"""
"""Скачивает только звук из TikTok"""
ydl_opts = {
"format": "bestaudio/best",
"outtmpl": out_path.replace('.mp3', ''),
@@ -125,13 +130,10 @@ def download_tiktok_music(
"extractor_args": {
"tiktok": {
"skip_impersonation": True,
"music": True, # Специальный флаг для музыки TikTok
},
},
"writethumbnail": True,
"writeinfojson": True,
# Для TikTok стараемся получить оригинальный звук
"extract_flat": False,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
@@ -139,9 +141,11 @@ def download_tiktok_music(
# Сохраняем информацию о звуке
info_file = out_path.replace('.mp3', '.info.json')
if os.path.exists(info_file):
try:
with open(info_file, 'w', encoding='utf-8') as f:
json.dump(info, f, ensure_ascii=False, indent=2)
except:
pass
# ---------------- ADD METADATA TO VIDEO/AUDIO ----------------
@@ -159,7 +163,6 @@ def add_metadata_to_video(
if not (is_video or is_audio):
# Если не поддерживаемый формат, просто копируем файл
import shutil
shutil.copy2(input_path, output_path)
return
@@ -190,7 +193,7 @@ def add_metadata_to_video(
cmd = [
'ffmpeg',
'-i', input_path,
'-c', 'copy', # Копируем без перекодировки
'-c', 'copy',
'-movflags', '+faststart',
'-y',
*metadata_args,
@@ -218,16 +221,14 @@ def add_metadata_to_video(
if result.returncode != 0:
logger.error(f"FFmpeg metadata error: {result.stderr}")
# Если не удалось добавить метаданные, копируем файл как есть
import shutil
shutil.copy2(input_path, output_path)
except Exception as e:
logger.error(f"Error adding metadata: {e}")
import shutil
shutil.copy2(input_path, output_path)
# ---------------- PLAYLIST DOWNLOAD ----------------
# ---------------- PLAYLIST DOWNLOAD (ИСПРАВЛЕННАЯ ВЕРСИЯ) ----------------
def download_playlist_videos(
playlist_info: dict,
@@ -236,12 +237,13 @@ def download_playlist_videos(
cancel_event: threading.Event,
progress_cb,
) -> List[str]:
"""Скачивает все видео из плейлиста"""
"""Скачивает все видео из плейлиста - ИСПРАВЛЕННАЯ ВЕРСИЯ"""
downloaded_files = []
# Создаем yt-dlp объект для загрузки каждого видео отдельно
ydl_opts = {
"format": "best[height<=1080]/best",
"outtmpl": os.path.join(output_dir, "%(title)s.%(ext)s"),
"outtmpl": os.path.join(output_dir, "%(title)s [%(id)s].%(ext)s"), # Добавляем ID для уникальности
"merge_output_format": "mp4",
"cookiefile": cookies,
"progress_hooks": [_progress_hook(cancel_event, progress_cb)],
@@ -251,31 +253,61 @@ def download_playlist_videos(
"extract_flat": False,
"writedescription": True,
"writeinfojson": True,
"nooverwrites": True, # Не перезаписывать существующие файлы
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
for entry in playlist_info.get('entries', []):
entries = playlist_info.get('entries', [])
total_videos = len(entries)
logger.info(f"Starting playlist download with {total_videos} videos")
for i, entry in enumerate(entries, 1):
if cancel_event.is_set():
raise DownloadCancelled("Cancelled by user")
if not entry.get('url'):
logger.warning(f"Entry {i} has no URL, skipping")
continue
video_url = entry['url']
video_title = entry.get('title', f'Video {i}')
logger.info(f"Downloading video {i}/{total_videos}: {video_title}")
try:
ydl.download([entry['url']])
# Загружаем видео
info = ydl.extract_info(video_url, download=True)
# Ищем скачанный файл
for filename in os.listdir(output_dir):
if filename.endswith(('.mp4', '.mkv', '.webm')):
file_path = os.path.join(output_dir, filename)
downloaded_files.append(file_path)
break
if not info:
logger.error(f"Failed to extract info for video {i}")
continue
# Получаем имя фактически созданного файла
filename = ydl.prepare_filename(info)
# Проверяем существование файла
if os.path.exists(filename):
downloaded_files.append(filename)
logger.info(f"Successfully downloaded: {os.path.basename(filename)}")
else:
# Ищем файл с другим расширением
base_name = filename.rsplit('.', 1)[0]
for ext in ['.mp4', '.mkv', '.webm', '.flv']:
alt_path = base_name + ext
if os.path.exists(alt_path):
downloaded_files.append(alt_path)
logger.info(f"Found file with extension {ext}: {os.path.basename(alt_path)}")
break
else:
logger.error(f"File not found for video {i}")
except Exception as e:
logger.error(f"Error downloading video {entry.get('title')}: {e}")
logger.error(f"Error downloading video {i} ({video_title}): {e}")
continue
logger.info(f"Playlist download complete. Downloaded {len(downloaded_files)} files")
return downloaded_files
except Exception as e:
@@ -322,6 +354,8 @@ def download_audio(
# Сохраняем информацию о аудио
info_file = out_path.replace('.mp3', '.info.json')
if os.path.exists(info_file):
try:
with open(info_file, 'w', encoding='utf-8') as f:
json.dump(info, f, ensure_ascii=False, indent=2)
except:
pass