Скачивание медиа из сообщений



Скачивание медиа из группы в Telegram может быть необходимо в различных сценариях, в зависимости от ваших потребностей или целей.

Принцип работы download_media

Определение медиа в сообщении. Сначала функция download_media определяет, какой тип медиа содержится в сообщении. Это может быть фотография, видео, аудио, документ и т.д.

Получение идентификатора файла. Каждое медиа в Telegram хранится с уникальным идентификатором файла. Функция download_media извлекает этот идентификатор, который необходим для запроса файла с серверов Telegram.

"photo": {
            "_": "ChatPhoto",
            "small_file_id": "AQADAgADqacxG7aAEAIAA7aEMDQABB3IcE6wwwvEAAQeBA",
            "small_photo_unique_id": "AgADqaG7aEMDQ",
            "big_file_id": "AQADAgADqacxGMDQAEAMAA7aEMDQABB3IcE6wwwvEAAQeBA",
            "big_photo_unique_id": "AgADqG7aEMDQ"
        }

Скачивание файла. Затем функция инициирует запрос к серверам Telegram для скачивания файла. При этом она использует различные параметры, такие как идентификатор файла и сессионные данные пользователя (ключи авторизации).

Прогресс загрузки. Во время скачивания файла download_media может отслеживать прогресс загрузки. Это особенно полезно для больших файлов, так как пользователь может видеть, сколько данных уже скачано и сколько еще предстоит загрузить(ниже подробнее об этом).

Сохранение файла на устройстве пользователя. После завершения скачивания файла функция сохраняет его на локальное устройство пользователя. Путь к сохранению файла можно указать в параметрах функции.

Обработка ошибок. Если в процессе скачивания возникают ошибки (например, проблемы с соединением или неверный идентификатор файла), download_media обрабатывает эти ошибки соответствующим образом, предоставляя информацию для отладки или повторных попыток загрузки.

app.download_media(message, file_name, in_memory, block, progress, progress_args)

message — это объект сообщения Message, из которого вы хотите скачать медиа. Сообщение может содержать различные типы медиа, такие как фотографии, видео, аудиофайлы и т.д.

available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note", "new_chat_photo")

file_name (str, необязательный) — пользовательское имя файла, которое будет использовано вместо имени, предоставленного Telegram. По умолчанию все файлы загружаются в папку downloads в рабочем каталоге.

Также можно указать путь для загрузки файлов в определённое место: пути, оканчивающиеся на /, считаются директориями. Все несуществующие папки будут созданы автоматически.

file_name=f"media/{message.message_id}.mp4"

in_memory (bool, необязательный) — укажите True, чтобы загрузить медиа в оперативную память. В таком случае будет возвращён бинарный объект, подобный файлу, с установленным атрибутом .name. По умолчанию: False. Это полезно, если вам нужно обработать медиа на лету, не сохраняя его физически.

block (bool, необязательный) — этот аргумент определяет, будет ли функция блокирующей. Если установить True, код будет заблокирован до завершения загрузки файла. По умолчанию: True. Если False, код продолжит выполняться параллельно скачиванию (для асинхронного выполнения кода).

progress (Callable, необязательный) — функция обратного вызова, которая вызывается для отслеживания прогресса скачивания. Эта функция может использоваться для отображения прогресс-бара или для логирования прогресса скачивания.

# Функция для обновления прогресс-бара
def progress(current, total):
    # 'current' - текущее количество скачанных байт,
    # 'total' - общий размер файла
    progress_bar.update(current - progress_bar.n)  # Обновляем прогресс-бар
#...
#Любое количество кода
#...

app.download_media(message..., file_name=..., progress=progress)

progress_args  (tuple, необязательный) — дополнительные аргументы для функции обратного вызова progress. Вы можете передать всё, что нужно для использования в области видимости функции, например, объект Message или экземпляр Client, чтобы обновить статус прогресса.

Другие параметры:

current (int) — количество переданных байтов на текущий момент.
total (int) — общий размер файла.
*args (tuple, необязательный) — дополнительные аргументы, указанные в параметре progress_args. Вы можете оставить *args или добавить все дополнительные аргументы в сигнатуру функции.

Возвращаемое значение: (str | None | BinaryIO):

  • В случае успеха возвращается абсолютный путь к загруженному файлу.
  • Если загрузка не удалась или была намеренно остановлена с помощью stop_transmission(), возвращается None.
  • Если указано in_memory=True, возвращается бинарный объект, подобный файлу, с установленным атрибутом .name.

Исключения: ValueError

  • Выбрасывается, если сообщение не содержит медиафайлов, доступных для загрузки.

audio. Аудиофайлы или музыкальные треки.

# Проверка наличия аудио в сообщении
if message.audio:
    # Скачиваем аудио
    app.download_media(message.audio, file_name=f"audio/{message.message_id}.mp3")

document. Документы, такие как PDF, Word или любые другие файлы, которые не подпадают под другие медиа-категории.

# Проверка наличия документа в сообщении
if message.document:
    # Скачиваем документ
    app.download_media(message.document, file_name=f"documents/{message.message_id}_{message.document.file_name}")

photo. Фотографии или изображения.

# Проверка наличия фотографии в сообщении
if message.photo:
    # Скачиваем фотографию
    app.download_media(message.photo, file_name=f"photos/{message.message_id}.jpg")

sticker. Стикеры, используемые в Telegram для выражения эмоций или реакций.

# Проверка наличия стикера в сообщении
if message.sticker:
    # Скачиваем стикер
    app.download_media(message.sticker, file_name=f"stickers/{message.message_id}.webp")

animation. Гифки или анимированные изображения.

# Проверка наличия анимации (гифки) в сообщении
if message.animation:
    # Скачиваем анимацию
    app.download_media(message.animation, file_name=f"animations/{message.message_id}.mp4")

video. Видеофайлы.

# Проверка наличия видео в сообщении
if message.video:
    # Скачиваем видео
    app.download_media(message.video, file_name=f"videos/{message.message_id}.mp4")

voice. Голосовые сообщения.

# Проверка наличия голосового сообщения
if message.voice:
    # Скачиваем голосовое сообщение
    app.download_media(message.voice, file_name=f"voice/{message.message_id}.ogg")

video_note. Круглые видео сообщения, которые обычно короткие и записываются через камеру фронтального вида.

# Проверка наличия видеосообщения
if message.video_note:
    # Скачиваем
    app.download_media(message.video_note, file_name=f"video_notes/{message.message_id}.mp4")

new_chat_photo. Фотографии, которые установлены как новые изображения профиля чата.

# Проверка наличия новой фотографии чата в сообщении
if message.new_chat_photo:
    # Скачиваем новую фотографию чата
    app.download_media(message.new_chat_photo, file_name=f"chat_photos/{message.message_id}.jpg")

Вот код, который реализует эту функциональность:

from pyrogram import Client

api_id = 1111
api_hash = ""
app = Client("my_session", api_id=api_id, api_hash=api_hash)
group_url = "test"  # URL группы

def main():
    with app:
        for message in app.get_chat_history(group_url):
            # Проверяем, содержит ли сообщение изображение
            if message.photo:
                # Скачиваем изображение
                app.download_media(message.photo, file_name=f"images/{message.from_user.id}_{message.id}.jpg")

main()

В этом коде мы итерируемся по всем сообщениям в истории чата app.get_chat_history(group_url), и если сообщение содержит фото (if message.photo), то мы скачиваем его. Изображения сохраняются в папке images с именем файла, основанным на {message.from_user.id}_{message.id}.jpg. Убедитесь, что папка images существует в вашей рабочей директории или измените путь сохранения в соответствии с вашей структурой.

Код ниже автоматически обрабатывает историю чата и скачивает различные типы медиа файлов (фото, видео, аудио и др.), отображая прогресс загрузки каждого файла.

Вы можете спокойно запустить этот код, указав свои api_hash и api_id, он скачает все медиа находящиеся в группе.

from pyrogram import Client
from tqdm import tqdm

api_id = 1111
api_hash = ""
app = Client("my_session", api_id=api_id, api_hash=api_hash)
group_url = "test"  # URL группы

def progress(current, total, progress_bar):
    # Обновляем прогресс-бар
    progress_bar.update(current - progress_bar.n)

def main():
    with app:
        for message in app.get_chat_history(group_url):
            if message.media:
                file_name = f"media/{message.id}"
                file_size = None
                # Определение расширения файла и размера в зависимости от типа медиа
                if message.photo:
                    file_name += ".jpg"
                    file_size = message.photo.file_size
                elif message.video:
                    file_name += ".mp4"
                    file_size = message.video.file_size
                elif message.audio:
                    file_name += ".mp3"
                    file_size = message.audio.file_size
                elif message.document:
                    file_name += f".{message.document.mime_type.split('/')[-1]}"
                    file_size = message.document.file_size
                elif message.voice:
                    file_name += ".ogg"
                    file_size = message.voice.file_size
                elif message.video_note:
                    file_name += ".mp4"
                    file_size = message.video_note.file_size
                elif message.sticker:
                    file_name += ".webp"
                    file_size = message.sticker.file_size
                elif message.animation:
                    file_name += ".mp4"
                    file_size = message.animation.file_size
                # Создание прогресс-бара для каждого файла
                # Если размер файла определен, создаем прогресс-бар и начинаем загрузку
                if file_size:
                    with tqdm(total=file_size, unit='B', unit_scale=True, desc="Скачивание") as progress_bar:
                        app.download_media(message, file_name=file_name, progress=progress, progress_args=(progress_bar,))

main()

Этот код теперь обрабатывает различные типы медиа, которые могут быть в сообщении, и создает индивидуальный прогресс-бар для каждого скачиваемого файла. Убедитесь, что у вас создана папка media в директории, где выполняется ваш скрипт, чтобы избежать ошибок при сохранении файлов.

Вывод:

Скачивание: 100%|██████████| 23.2k/23.2k [00:00<00:00, 29.1kB/s]
Скачивание: 100%|██████████| 23.0k/23.0k [00:00<00:00, 30.9kB/s]
Скачивание: 100%|██████████| 177k/177k [00:01<00:00, 175kB/s]
Скачивание: 100%|██████████| 10.4k/10.4k [00:00<00:00, 14.3kB/s]
Скачивание: 100%|██████████| 23.1k/23.1k [00:00<00:00, 25.2kB/s]
Скачивание: 100%|██████████| 43.6k/43.6k [00:00<00:00, 50.3kB/s]
...
...
...
Скачивание: 100%|██████████| 97.5k/97.5k [00:00<00:00, 107kB/s]
Скачивание: 100%|██████████| 79.3k/79.3k [00:00<00:00, 88.1kB/s]
Скачивание: 100%|██████████| 55.1k/55.1k [00:00<00:00, 60.9kB/s]
Скачивание: 100%|██████████| 4.14k/4.14k [00:00<00:00, 6.47kB/s]
Скачивание: 100%|██████████| 19.8k/19.8k [00:00<00:00, 26.2kB/s]
Скачивание: 100%|██████████| 79.0k/79.0k [00:00<00:00, 84.0kB/s]
Скачивание: 100%|██████████| 71.0k/71.0k [00:00<00:00, 80.5kB/s]

Пояснения по работе кода с progress_bar

В этом фрагменте кода используется библиотека tqdm, которая представляет собой инструмент для создания текстовых индикаторов выполнения (прогресс-баров) в командной строке при выполнении итераций в циклах или при обработке данных.

from tqdm import tqdm
def progress(current, total, progress_bar):
    # Обновляем прогресс-бар
    progress_bar.update(current - progress_bar.n)

В данном контексте функция progress предназначена для обновления прогресс-бара tqdm во время загрузки файла с помощью pyrogram. Вот что означают аргументы этой функции:

current. Текущее количество байт, которое было загружено на данный момент. Это значение передаётся Pyrogram во время загрузки медиафайла.

total. Общий размер файла в байтах, который предстоит загрузить. Это значение также предоставляется Pyrogram и используется для определения общего прогресса загрузки.

progress_bar. Экземпляр tqdm, который представляет собой индикатор прогресса. Он используется для визуализации текущего состояния загрузки в виде прогресс-бара.

Функция progress вызывается Pyrogram при каждом обновлении загрузки.

В этой функции метод progress_bar.update(current — progress_bar.n) используется для обновления прогресс-бара на значение, насколько изменился прогресс с последнего вызова.

progress_bar.n хранит текущее значение прогресс-бара до вызова update, и вычитая его из current, вы передаёте в update то количество байт, которое было загружено с момента последнего обновления прогресс-бара.



Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: