diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index ab45b4e..57f4701 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -110,27 +110,30 @@ namespace WTelegram
/// Helper function to send a media message more easily
/// Destination of message (chat group, channel, user chat, etc..)
/// Caption for the media (in plain text) or
- /// Media file already uploaded to TG (see UploadFileAsync)
- /// for automatic detection, "photo" for an inline photo, or a MIME type to send as a document
+ /// Media file already uploaded to TG (see UploadFileAsync)
+ /// for automatic detection, "photo" for an inline photo, "video" for a streamable MP4 video, or a MIME type to send as a document
/// Your message is a reply to an existing message with this ID, in the same chat
/// Text formatting entities for the caption. You can use MarkdownToEntities to create these
/// UTC timestamp when the message should be sent
/// The transmitted message confirmed by Telegram
- public Task SendMediaAsync(InputPeer peer, string caption, InputFileBase mediaFile, string mimeType = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default)
+ public Task SendMediaAsync(InputPeer peer, string caption, InputFileBase uploadedFile, string mimeType = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default)
{
- mimeType ??= Path.GetExtension(mediaFile.Name)?.ToLowerInvariant() switch
+ mimeType ??= Path.GetExtension(uploadedFile.Name)?.ToLowerInvariant() switch
{
".jpg" or ".jpeg" or ".png" or ".bmp" => "photo",
+ ".mp4" => "video",
".gif" => "image/gif",
".webp" => "image/webp",
- ".mp4" => "video/mp4",
".mp3" => "audio/mpeg",
".wav" => "audio/x-wav",
_ => "", // send as generic document with undefined MIME type
};
if (mimeType == "photo")
- return SendMessageAsync(peer, caption, new InputMediaUploadedPhoto { file = mediaFile }, reply_to_msg_id, entities, schedule_date);
- return SendMessageAsync(peer, caption, new InputMediaUploadedDocument(mediaFile, mimeType), reply_to_msg_id, entities, schedule_date);
+ return SendMessageAsync(peer, caption, new InputMediaUploadedPhoto { file = uploadedFile }, reply_to_msg_id, entities, schedule_date);
+ else if (mimeType == "video")
+ return SendMessageAsync(peer, caption, new InputMediaUploadedDocument(uploadedFile, "video/mp4", new DocumentAttributeVideo { flags = DocumentAttributeVideo.Flags.supports_streaming }), reply_to_msg_id, entities, schedule_date);
+ else
+ return SendMessageAsync(peer, caption, new InputMediaUploadedDocument(uploadedFile, mimeType), reply_to_msg_id, entities, schedule_date);
}
public enum LinkPreview { Disabled = 0, BelowText = 1, AboveText = 2 };
@@ -184,6 +187,7 @@ namespace WTelegram
/// Your message is a reply to an existing message with this ID, in the same chat
/// Text formatting entities for the caption. You can use MarkdownToEntities to create these
/// UTC timestamp when the message should be sent
+ /// Any URL pointing to a video should be considered as non-streamable
/// The last of the media group messages, confirmed by Telegram
///
/// * The caption/entities are set on the last media
@@ -191,7 +195,7 @@ namespace WTelegram
/// WTelegramClient proxy settings don't apply to HttpClient
/// * You may run into errors if you mix, in the same album, photos and file documents having no thumbnails/video attributes
///
- public async Task SendAlbumAsync(InputPeer peer, ICollection medias, string caption = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default)
+ public async Task SendAlbumAsync(InputPeer peer, ICollection medias, string caption = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default, bool videoUrlAsFile = false)
{
System.Net.Http.HttpClient httpClient = null;
int i = 0, length = medias.Count;
@@ -215,7 +219,10 @@ namespace WTelegram
case InputMediaDocumentExternal imde:
string mimeType = null;
var inputFile = await UploadFromUrl(imde.url);
- ism.media = new InputMediaUploadedDocument(inputFile, mimeType);
+ if (mimeType?.StartsWith("video/") == true)
+ ism.media = new InputMediaUploadedDocument(inputFile, mimeType, new DocumentAttributeVideo { flags = DocumentAttributeVideo.Flags.supports_streaming });
+ else
+ ism.media = new InputMediaUploadedDocument(inputFile, mimeType);
goto retry;
case InputMediaPhotoExternal impe:
inputFile = await UploadFromUrl(impe.url);
@@ -226,18 +233,14 @@ namespace WTelegram
{
var filename = Path.GetFileName(new Uri(url).LocalPath);
httpClient ??= new();
- var response = await httpClient.GetAsync(url);
+ using var response = await httpClient.GetAsync(url, System.Net.Http.HttpCompletionOption.ResponseHeadersRead);
+ response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
mimeType = response.Content.Headers.ContentType?.MediaType;
if (response.Content.Headers.ContentLength is long length)
return await UploadFileAsync(new Helpers.IndirectStream(stream) { ContentLength = length }, filename);
else
- {
- using var ms = new MemoryStream();
- await stream.CopyToAsync(ms);
- ms.Position = 0;
- return await UploadFileAsync(ms, filename);
- }
+ return await UploadFileAsync(stream, filename);
}
}
}
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 746a734..8d2636c 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -107,6 +107,15 @@ namespace TL
mime_type = mimeType;
if (inputFile.Name is string filename) attributes = new[] { new DocumentAttributeFilename { file_name = filename } };
}
+ public InputMediaUploadedDocument(InputFileBase inputFile, string mimeType, params DocumentAttribute[] attribs)
+ {
+ file = inputFile;
+ mime_type = mimeType;
+ if (inputFile.Name is string filename && !attribs.Any(a => a is DocumentAttributeFilename))
+ attributes = attribs.Append(new DocumentAttributeFilename { file_name = filename }).ToArray();
+ else
+ attributes = attribs;
+ }
}
partial class InputPhoto