diff --git a/pyrogram/methods/messages/send_video.py b/pyrogram/methods/messages/send_video.py index b7880d1f..af2a539d 100644 --- a/pyrogram/methods/messages/send_video.py +++ b/pyrogram/methods/messages/send_video.py @@ -23,10 +23,7 @@ from datetime import datetime from typing import Union, BinaryIO, List, Optional, Callable import pyrogram -from pyrogram import StopTransmission, enums -from pyrogram import raw -from pyrogram import types -from pyrogram import utils +from pyrogram import StopTransmission, enums, raw, types, utils from pyrogram.errors import FilePartMissing from pyrogram.file_id import FileType @@ -55,7 +52,7 @@ class SendVideo: reply_to_chat_id: Union[int, str] = None, quote_text: str = None, quote_entities: List["types.MessageEntity"] = None, - cover: Optional[Union[str, "io.BytesIO"]] = None, + cover: Union[str, BinaryIO] = None, start_timestamp: int = None, schedule_date: datetime = None, protect_content: bool = None, @@ -161,8 +158,12 @@ class SendVideo: List of special entities that appear in quote_text, which can be specified instead of *parse_mode*. for reply_to_message only. - cover (``str`` | :obj:`io.BytesIO`, *optional*): - Cover of the video; pass None to skip cover uploading. + cover (``str`` | ``BinaryIO``, *optional*): + Video cover. + Pass a file_id as string to attach a photo that exists on the Telegram servers, + pass a HTTP URL as a string for Telegram to get a video from the Internet, + pass a file path as string to upload a new photo civer that exists on your local machine, or + pass a binary file-like object with its attribute ".name" set for in-memory uploads. start_timestamp (``int``, *optional*): Timestamp from which the video playing must start, in seconds. @@ -224,6 +225,9 @@ class SendVideo: # Send self-destructing video await app.send_video("me", "video.mp4", ttl_seconds=10) + # Add video_cover to the video + await app.send_video(channel_id, "video.mp4", video_cover="coverku.jpg") + # Keep track of the progress while uploading async def progress(current, total): print(f"{current * 100 / total:.1f}%") @@ -231,6 +235,9 @@ class SendVideo: await app.send_video("me", "video.mp4", progress=progress) """ file = None + vidcover_file = None + vidcover_media = None + peer = await self.resolve_peer(chat_id) reply_to = await utils.get_reply_to( client=self, @@ -245,6 +252,45 @@ class SendVideo: ) try: + if cover is not None: + if isinstance(cover, str): + if os.path.isfile(cover): + vidcover_media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=peer, + media=raw.types.InputMediaUploadedPhoto( + file=await self.save_file(cover) + ) + ) + ) + elif re.match("^https?://", cover): + vidcover_media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=peer, + media=raw.types.InputMediaPhotoExternal( + url=cover + ) + ) + ) + else: + vidcover_file = utils.get_input_media_from_file_id(cover, FileType.PHOTO).id + else: + vidcover_media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=peer, + media=raw.types.InputMediaUploadedPhoto( + file=await self.save_file(cover) + ) + ) + ) + + if vidcover_media: + vidcover_file = raw.types.InputPhoto( + id=vidcover_media.photo.id, + access_hash=vidcover_media.photo.access_hash, + file_reference=vidcover_media.photo.file_reference + ) + if isinstance(video, str): if os.path.isfile(video): thumb = await self.save_file(thumb) @@ -264,7 +310,7 @@ class SendVideo: ), raw.types.DocumentAttributeFilename(file_name=file_name or os.path.basename(video)) ], - video_cover=await self.save_file(cover) if cover else None, + video_cover=vidcover_file, video_timestamp=start_timestamp ) elif re.match("^https?://", video): @@ -272,7 +318,7 @@ class SendVideo: url=video, ttl_seconds=ttl_seconds, spoiler=has_spoiler, - video_cover=await self.save_file(cover) if cover else None, + video_cover=vidcover_file, video_timestamp=start_timestamp ) else: @@ -296,14 +342,14 @@ class SendVideo: ), raw.types.DocumentAttributeFilename(file_name=file_name or video.name) ], - video_cover=await self.save_file(cover) if cover else None, + video_cover=vidcover_file, video_timestamp=start_timestamp ) while True: try: rpc = raw.functions.messages.SendMedia( - peer=await self.resolve_peer(chat_id), + peer=peer, media=media, silent=disable_notification or None, reply_to=reply_to, diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index d69c7a8e..774055f0 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -23,9 +23,7 @@ from functools import partial from typing import List, Match, Union, BinaryIO, Optional, Callable import pyrogram -from pyrogram import raw, enums -from pyrogram import types -from pyrogram import utils +from pyrogram import enums, raw, types, utils from pyrogram.errors import ChannelPrivate, MessageIdsEmpty, PeerIdInvalid from pyrogram.parser import utils as parser_utils, Parser from ..object import Object @@ -1115,7 +1113,7 @@ class Message(Object, Update): video_note = types.VideoNote._parse(client, doc, video_attributes) media_type = enums.MessageMediaType.VIDEO_NOTE else: - video = types.Video._parse(client, doc, video_attributes, file_name, media.ttl_seconds) + video = types.Video._parse(client, doc, video_attributes, file_name, media.ttl_seconds, media.video_cover, media.video_timestamp) media_type = enums.MessageMediaType.VIDEO has_media_spoiler = media.spoiler @@ -3600,7 +3598,7 @@ class Message(Object, Update): quote_entities: List["types.MessageEntity"] = None, allow_paid_broadcast: bool = None, message_effect_id: int = None, - cover: Optional[Union[str, "io.BytesIO"]] = None, + cover: Union[str, BinaryIO] = None, start_timestamp: int = None, schedule_date: datetime = None, invert_media: bool = None, @@ -3707,8 +3705,12 @@ class Message(Object, Update): allow_paid_broadcast (``bool``, *optional*): Pass True to allow the message to ignore regular broadcast limits for a small fee; for bots. - cover (``str`` | :obj:`io.BytesIO`, *optional*): - Cover of the video; pass None to skip cover uploading. + cover (``str`` | ``BinaryIO``, *optional*): + Video cover. + Pass a file_id as string to attach a photo that exists on the Telegram servers, + pass a HTTP URL as a string for Telegram to get a video from the Internet, + pass a file path as string to upload a new photo civer that exists on your local machine, or + pass a binary file-like object with its attribute ".name" set for in-memory uploads. start_timestamp (``int``, *optional*): Timestamp from which the video playing must start, in seconds. diff --git a/pyrogram/types/messages_and_media/video.py b/pyrogram/types/messages_and_media/video.py index 3d0b6161..1b6861da 100644 --- a/pyrogram/types/messages_and_media/video.py +++ b/pyrogram/types/messages_and_media/video.py @@ -21,8 +21,7 @@ from datetime import datetime from typing import List import pyrogram -from pyrogram import raw, utils -from pyrogram import types +from pyrogram import raw, types, utils from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource from ..object import Object @@ -67,6 +66,12 @@ class Video(Object): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): Video thumbnails. + + cover (:obj:`~pyrogram.types.Photo`, *optional*): + Video cover. + + start_timestamp (``int``, *optional*): + Video startpoint, in seconds. """ def __init__( @@ -84,7 +89,9 @@ class Video(Object): supports_streaming: bool = None, ttl_seconds: int = None, date: datetime = None, - thumbs: List["types.Thumbnail"] = None + thumbs: List["types.Thumbnail"] = None, + cover: "types.Photo" = None, + start_timestamp: int = None, ): super().__init__(client) @@ -100,6 +107,8 @@ class Video(Object): self.ttl_seconds = ttl_seconds self.date = date self.thumbs = thumbs + self.cover = cover + self.start_timestamp = start_timestamp @staticmethod def _parse( @@ -107,7 +116,9 @@ class Video(Object): video: "raw.types.Document", video_attributes: "raw.types.DocumentAttributeVideo", file_name: str, - ttl_seconds: int = None + ttl_seconds: int = None, + cover = None, + start_timestamp: int = None ) -> "Video": return Video( file_id=FileId( @@ -131,5 +142,7 @@ class Video(Object): date=utils.timestamp_to_datetime(video.date), ttl_seconds=ttl_seconds, thumbs=types.Thumbnail._parse(client, video), + cover=types.Photo._parse(client, cover), + start_timestamp=start_timestamp, client=client )