Скачивание и загрузка фото, видео, документов и голосовых сообщений. Работа с миниатюрами.
Ключевая идея: Telegram поддерживает передачу фото, видео, документов, голосовых сообщений и стикеров. Telethon предоставляет удобные методы для скачивания и загрузки любых типов медиа.
Сообщение может содержать различные типы медиа:
msg = await client.get_messages(chat, ids=12345)
# Проверка типа медиа
if msg.photo:
print('Фото')
elif msg.video:
print('Видео')
elif msg.document:
print('Документ')
elif msg.audio:
print('Аудио')
elif msg.voice:
print('Голосовое сообщение')
elif msg.video_note:
print('Видеозаметка (круглое видео)')
elif msg.sticker:
print('Стикер')
elif msg.gif:
print('GIF-анимация')
elif msg.contact:
print('Контакт')
elif msg.geo:
print('Геолокация')Ключевая идея: каждое свойство (photo, video, document и т.д.) содержит объект медиа или None. Проверка через
if msg.photo:— самый надёжный способ определения типа.
# Скачивание фото из сообщения
if msg.photo:
path = await client.download_media(msg.photo, file='downloads/')
print(f'Скачано в: {path}')
# Скачивание в конкретный файл
await client.download_media(msg.photo, file='downloads/photo.jpg')# Фото профиля пользователя
await client.download_profile_photo('username', file='profile.jpg')
# В разных разрешениях
await client.download_profile_photo('username', file='small.jpg', download_big=False)
await client.download_profile_photo('username', file='big.jpg', download_big=True)if msg.video:
path = await client.download_media(msg.video, file='downloads/')
print(f'Видео скачано: {path}')if msg.video:
video = msg.video
print(f'Длительность: {video.duration} сек')
print(f'Размер: {video.size} байт')
print(f'Ширина: {video.w}, Высота: {video.h}')
print(f'MIME-тип: {video.mime_type}')if msg.document:
doc = msg.document
print(f'Имя: {getattr(doc, "file_name", "неизвестно")}')
print(f'Размер: {doc.size} байт')
print(f'MIME: {doc.mime_type}')
path = await client.download_media(doc, file='downloads/')Важно: документы могут быть любого типа — PDF, ZIP, APK и т.д. Telethon сохраняет оригинальное имя файла, если оно доступно.
if msg.voice:
voice = msg.voice
print(f'Длительность: {voice.duration} сек')
print(f'Размер: {voice.size} байт')
path = await client.download_media(voice, file='downloads/voice.ogg')import os
async def download_all_media(chat, folder='downloads/'):
os.makedirs(folder, exist_ok=True)
count = 0
async for msg in client.iter_messages(chat, filter=lambda m: m.media):
if msg.media:
path = await client.download_media(msg.media, file=folder)
count += 1
print(f'Скачано: {count} файлов')
print(f'Всего скачано: {count}')
# Запуск
await download_all_media('chat_username', folder='my_media/')Правило: при массовом скачивании больших объёмов следите за местом на диске и лимитами Telegram.
# Из файла
await client.send_file(chat, file='photo.jpg', caption='Моё фото')
# Из открытого файла
with open('photo.jpg', 'rb') as f:
await client.send_file(chat, file=f, caption='Из файла')await client.send_file(
chat,
file='document.pdf',
caption='Документ',
force_document=True # Отправить как документ, а не фото
)await client.send_file(
chat,
file='video.mp4',
caption='Видео',
# thumb='thumbnail.jpg' # Миниатюра (опционально)
)await client.send_file(
chat,
file='document.pdf',
thumb='thumb.jpg', # Миниатюра для превью
caption='Документ с миниатюрой'
)# Пересылка сообщения с медиа без скачивания на диск
await client.forward_messages(
'destination_chat',
messages=msg_id,
from_peer='source_chat'
)Ключевая идея: пересылка не требует скачивания файла. Telegram пересылает ссылку на существующий файл, что происходит мгновенно.
if msg.document:
size_bytes = msg.document.size
size_mb = size_bytes / (1024 * 1024)
print(f'Размер файла: {size_mb:.2f} MB')
elif msg.video:
size_mb = msg.video.size / (1024 * 1024)
print(f'Размер видео: {size_mb:.2f} MB')import sys
def progress_callback(current, total):
percent = current / total * 100
sys.stdout.write(f'\rПрогресс: {percent:.1f}%')
sys.stdout.flush()
# Использование
await client.download_media(
msg.media,
file='downloads/',
progress_callback=progress_callback
)
print() # Новая строка после завершения# Только фото
async for msg in client.iter_messages(chat, filter=types.MessageMediaPhoto):
await client.download_media(msg.media)
# Только видео
async for msg in client.iter_messages(chat, filter=types.MessageMediaDocument):
if msg.video:
await client.download_media(msg.media)Важно:
filterпринимает тип медиа-объекта. Это эффективнее, чем получать все сообщения и фильтровать вручную.
from telethon.errors import LocationInvalidError
async def safe_download(msg, folder):
try:
path = await client.download_media(msg.media, file=folder)
print(f'Скачано: {path}')
except LocationInvalidError:
print('Файл недоступен (возможно, удалён)')
except Exception as e:
print(f'Ошибка скачивания: {e}')| Тип медиа | Максимальный размер |
|---|---|
| Фото | 10 MB |
| Видео | 2 GB (20 MB для ботов) |
| Документ | 2 GB |
| Голосовое | 20 MB |
| Стикеры | 256 KB |
Правило: Telegram ограничивает размер файлов. Попытка загрузить файл больше лимита вызовет ошибку.
Медиа — это важная часть Telegram, но интерактивность достигается через inline-элементы. Следующая тема — inline-запросы и кнопки — научит вас создавать интерактивные интерфейсы.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.