Support precise video duration.

This commit is contained in:
levlam 2023-06-05 14:33:00 +03:00
parent dfeeaf8f87
commit 71faaae22f
8 changed files with 44 additions and 16 deletions

View File

@ -4856,8 +4856,8 @@ inputStoryContentPhoto photo:InputFile added_sticker_file_ids:vector<int32> = In
//@description A video story //@description A video story
//@video Video to be sent. The video size must be 720x1280. The video must be stored in MPEG4 format, encoded by x265 codec and must be streamable //@video Video to be sent. The video size must be 720x1280. The video must be stored in MPEG4 format, encoded by x265 codec and must be streamable
//@added_sticker_file_ids File identifiers of the stickers added to the video, if applicable //@added_sticker_file_ids File identifiers of the stickers added to the video, if applicable
//@duration Duration of the video, in seconds; 0-60 //@duration Precise duration of the video, in seconds; 0-60
inputStoryContentVideo video:InputFile added_sticker_file_ids:vector<int32> duration:int32 = InputStoryContent; inputStoryContentVideo video:InputFile added_sticker_file_ids:vector<int32> duration:double = InputStoryContent;
//@description Contains information about interactions with a story //@description Contains information about interactions with a story

View File

@ -121,10 +121,12 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
UNREACHABLE(); UNREACHABLE();
} }
} }
double video_precise_duration = 0.0;
int32 video_duration = 0; int32 video_duration = 0;
int32 video_preload_prefix_size = 0; int32 video_preload_prefix_size = 0;
string video_waveform; string video_waveform;
if (video != nullptr) { if (video != nullptr) {
video_precise_duration = video->duration_;
video_duration = static_cast<int32>(std::ceil(video->duration_)); video_duration = static_cast<int32>(std::ceil(video->duration_));
if (document_subtype == Subtype::Story) { if (document_subtype == Subtype::Story) {
video_preload_prefix_size = video->preload_prefix_size_; video_preload_prefix_size = video->preload_prefix_size_;
@ -536,10 +538,10 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
std::move(custom_emoji), sticker_format, load_data_multipromise_ptr); std::move(custom_emoji), sticker_format, load_data_multipromise_ptr);
break; break;
case Document::Type::Video: case Document::Type::Video:
td_->videos_manager_->create_video(file_id, std::move(minithumbnail), std::move(thumbnail), td_->videos_manager_->create_video(
std::move(animated_thumbnail), has_stickers, vector<FileId>(), file_id, std::move(minithumbnail), std::move(thumbnail), std::move(animated_thumbnail), has_stickers,
std::move(file_name), std::move(mime_type), video_duration, dimensions, vector<FileId>(), std::move(file_name), std::move(mime_type), video_duration, video_precise_duration,
supports_streaming, video_preload_prefix_size, !is_web); dimensions, supports_streaming, video_preload_prefix_size, !is_web);
break; break;
case Document::Type::VideoNote: case Document::Type::VideoNote:
td_->video_notes_manager_->create_video_note(file_id, std::move(minithumbnail), std::move(thumbnail), td_->video_notes_manager_->create_video_note(file_id, std::move(minithumbnail), std::move(thumbnail),

View File

@ -2103,7 +2103,7 @@ static Result<InputMessageContent> create_input_message_content(
bool has_stickers = !sticker_file_ids.empty(); bool has_stickers = !sticker_file_ids.empty();
td->videos_manager_->create_video(file_id, string(), thumbnail, AnimationSize(), has_stickers, td->videos_manager_->create_video(file_id, string(), thumbnail, AnimationSize(), has_stickers,
std::move(sticker_file_ids), std::move(file_name), std::move(mime_type), std::move(sticker_file_ids), std::move(file_name), std::move(mime_type),
input_video->duration_, input_video->duration_, input_video->duration_,
get_dimensions(input_video->width_, input_video->height_, nullptr), get_dimensions(input_video->width_, input_video->height_, nullptr),
input_video->supports_streaming_, 0, false); input_video->supports_streaming_, 0, false);

View File

@ -17,6 +17,8 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include <cmath>
namespace td { namespace td {
class StoryContentPhoto final : public StoryContent { class StoryContentPhoto final : public StoryContent {
@ -159,11 +161,15 @@ Result<unique_ptr<StoryContent>> get_input_story_content(
false, false)); false, false));
file_id = file_id =
td->file_manager_->copy_file_id(file_id, FileType::VideoStory, owner_dialog_id, "get_input_story_content"); td->file_manager_->copy_file_id(file_id, FileType::VideoStory, owner_dialog_id, "get_input_story_content");
if (input_story->duration_ < 0 || input_story->duration_ > 60.0) {
return Status::Error(400, "Invalid video duration specified");
}
auto sticker_file_ids = auto sticker_file_ids =
td->stickers_manager_->get_attached_sticker_file_ids(input_story->added_sticker_file_ids_); td->stickers_manager_->get_attached_sticker_file_ids(input_story->added_sticker_file_ids_);
bool has_stickers = !sticker_file_ids.empty(); bool has_stickers = !sticker_file_ids.empty();
td->videos_manager_->create_video(file_id, string(), PhotoSize(), AnimationSize(), has_stickers, td->videos_manager_->create_video(file_id, string(), PhotoSize(), AnimationSize(), has_stickers,
std::move(sticker_file_ids), "story.mp4", "video/mp4", input_story->duration_, std::move(sticker_file_ids), "story.mp4", "video/mp4",
static_cast<int32>(std::ceil(input_story->duration_)), input_story->duration_,
get_dimensions(720, 1280, nullptr), true, 0, false); get_dimensions(720, 1280, nullptr), true, 0, false);
return make_unique<StoryContentVideo>(file_id, FileId()); return make_unique<StoryContentVideo>(file_id, FileId());

View File

@ -65,11 +65,12 @@ FileId VideosManager::on_get_video(unique_ptr<Video> new_video, bool replace) {
LOG(DEBUG) << "Video " << file_id << " MIME type has changed"; LOG(DEBUG) << "Video " << file_id << " MIME type has changed";
v->mime_type = std::move(new_video->mime_type); v->mime_type = std::move(new_video->mime_type);
} }
if (v->duration != new_video->duration || v->dimensions != new_video->dimensions || if (v->duration != new_video->duration || v->precise_duration != new_video->precise_duration ||
v->supports_streaming != new_video->supports_streaming || v->dimensions != new_video->dimensions || v->supports_streaming != new_video->supports_streaming ||
v->preload_prefix_size != new_video->preload_prefix_size) { v->preload_prefix_size != new_video->preload_prefix_size) {
LOG(DEBUG) << "Video " << file_id << " info has changed"; LOG(DEBUG) << "Video " << file_id << " info has changed";
v->duration = new_video->duration; v->duration = new_video->duration;
v->precise_duration = new_video->precise_duration;
v->dimensions = new_video->dimensions; v->dimensions = new_video->dimensions;
v->supports_streaming = new_video->supports_streaming; v->supports_streaming = new_video->supports_streaming;
v->preload_prefix_size = new_video->preload_prefix_size; v->preload_prefix_size = new_video->preload_prefix_size;
@ -170,13 +171,15 @@ void VideosManager::merge_videos(FileId new_id, FileId old_id) {
void VideosManager::create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail, void VideosManager::create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail,
AnimationSize animated_thumbnail, bool has_stickers, vector<FileId> &&sticker_file_ids, AnimationSize animated_thumbnail, bool has_stickers, vector<FileId> &&sticker_file_ids,
string file_name, string mime_type, int32 duration, Dimensions dimensions, string file_name, string mime_type, int32 duration, double precise_duration,
bool supports_streaming, int32 preload_prefix_size, bool replace) { Dimensions dimensions, bool supports_streaming, int32 preload_prefix_size,
bool replace) {
auto v = make_unique<Video>(); auto v = make_unique<Video>();
v->file_id = file_id; v->file_id = file_id;
v->file_name = std::move(file_name); v->file_name = std::move(file_name);
v->mime_type = std::move(mime_type); v->mime_type = std::move(mime_type);
v->duration = max(duration, 0); v->duration = max(duration, 0);
v->precise_duration = duration == 0 ? 0.0 : clamp(precise_duration, duration - 1.0, duration + 0.0);
v->dimensions = dimensions; v->dimensions = dimensions;
if (!td_->auth_manager_->is_bot()) { if (!td_->auth_manager_->is_bot()) {
v->minithumbnail = std::move(minithumbnail); v->minithumbnail = std::move(minithumbnail);
@ -267,7 +270,7 @@ tl_object_ptr<telegram_api::InputMedia> VideosManager::get_input_media(
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes; vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
attributes.push_back(make_tl_object<telegram_api::documentAttributeVideo>( attributes.push_back(make_tl_object<telegram_api::documentAttributeVideo>(
attribute_flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, video->duration, attribute_flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, video->precise_duration,
video->dimensions.width, video->dimensions.height, 0)); video->dimensions.width, video->dimensions.height, 0));
if (!video->file_name.empty()) { if (!video->file_name.empty()) {
attributes.push_back(make_tl_object<telegram_api::documentAttributeFilename>(video->file_name)); attributes.push_back(make_tl_object<telegram_api::documentAttributeFilename>(video->file_name));

View File

@ -36,8 +36,8 @@ class VideosManager {
void create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail, AnimationSize animated_thumbnail, void create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail, AnimationSize animated_thumbnail,
bool has_stickers, vector<FileId> &&sticker_file_ids, string file_name, string mime_type, bool has_stickers, vector<FileId> &&sticker_file_ids, string file_name, string mime_type,
int32 duration, Dimensions dimensions, bool supports_streaming, int32 preload_prefix_size, int32 duration, double precise_duration, Dimensions dimensions, bool supports_streaming,
bool replace); int32 preload_prefix_size, bool replace);
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id, tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_file,
@ -72,6 +72,7 @@ class VideosManager {
string file_name; string file_name;
string mime_type; string mime_type;
int32 duration = 0; int32 duration = 0;
double precise_duration = 0;
Dimensions dimensions; Dimensions dimensions;
string minithumbnail; string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;

View File

@ -23,11 +23,13 @@ void VideosManager::store_video(FileId file_id, StorerT &storer) const {
CHECK(video != nullptr); CHECK(video != nullptr);
bool has_animated_thumbnail = video->animated_thumbnail.file_id.is_valid(); bool has_animated_thumbnail = video->animated_thumbnail.file_id.is_valid();
bool has_preload_prefix_size = video->preload_prefix_size != 0; bool has_preload_prefix_size = video->preload_prefix_size != 0;
bool has_precise_duration = video->precise_duration != 0 && video->precise_duration != video->duration;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(video->has_stickers); STORE_FLAG(video->has_stickers);
STORE_FLAG(video->supports_streaming); STORE_FLAG(video->supports_streaming);
STORE_FLAG(has_animated_thumbnail); STORE_FLAG(has_animated_thumbnail);
STORE_FLAG(has_preload_prefix_size); STORE_FLAG(has_preload_prefix_size);
STORE_FLAG(has_precise_duration);
END_STORE_FLAGS(); END_STORE_FLAGS();
store(video->file_name, storer); store(video->file_name, storer);
store(video->mime_type, storer); store(video->mime_type, storer);
@ -45,6 +47,9 @@ void VideosManager::store_video(FileId file_id, StorerT &storer) const {
if (has_preload_prefix_size) { if (has_preload_prefix_size) {
store(video->preload_prefix_size, storer); store(video->preload_prefix_size, storer);
} }
if (has_precise_duration) {
store(video->precise_duration, storer);
}
} }
template <class ParserT> template <class ParserT>
@ -52,11 +57,13 @@ FileId VideosManager::parse_video(ParserT &parser) {
auto video = make_unique<Video>(); auto video = make_unique<Video>();
bool has_animated_thumbnail; bool has_animated_thumbnail;
bool has_preload_prefix_size; bool has_preload_prefix_size;
bool has_precise_duration;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(video->has_stickers); PARSE_FLAG(video->has_stickers);
PARSE_FLAG(video->supports_streaming); PARSE_FLAG(video->supports_streaming);
PARSE_FLAG(has_animated_thumbnail); PARSE_FLAG(has_animated_thumbnail);
PARSE_FLAG(has_preload_prefix_size); PARSE_FLAG(has_preload_prefix_size);
PARSE_FLAG(has_precise_duration);
END_PARSE_FLAGS(); END_PARSE_FLAGS();
parse(video->file_name, parser); parse(video->file_name, parser);
parse(video->mime_type, parser); parse(video->mime_type, parser);
@ -76,6 +83,11 @@ FileId VideosManager::parse_video(ParserT &parser) {
if (has_preload_prefix_size) { if (has_preload_prefix_size) {
parse(video->preload_prefix_size, parser); parse(video->preload_prefix_size, parser);
} }
if (has_precise_duration) {
parse(video->precise_duration, parser);
} else {
video->precise_duration = video->duration;
}
if (parser.get_error() != nullptr || !video->file_id.is_valid()) { if (parser.get_error() != nullptr || !video->file_id.is_valid()) {
return FileId(); return FileId();
} }

View File

@ -790,6 +790,10 @@ class CliClient final : public Actor {
arg = to_integer<int64>(args); arg = to_integer<int64>(args);
} }
static void get_args(string &args, double &arg) {
arg = to_double(args);
}
struct ChatId { struct ChatId {
int64 chat_id = 0; int64 chat_id = 0;
@ -3945,7 +3949,7 @@ class CliClient final : public Actor {
string video; string video;
string caption; string caption;
PrivacyRules rules; PrivacyRules rules;
int32 duration; double duration;
string sticker_file_ids; string sticker_file_ids;
get_args(args, video, caption, rules, duration, sticker_file_ids); get_args(args, video, caption, rules, duration, sticker_file_ids);
send_request(td_api::make_object<td_api::sendStory>( send_request(td_api::make_object<td_api::sendStory>(