diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index 6884af1c2..7f61a9716 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -1621,11 +1621,14 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
 	}
 
 	_owner->cache().copyIfEmpty(local->cacheKey(), cacheKey());
-	const auto localMedia = local->activeMediaView();
-	if (!localMedia->bytes().isEmpty()) {
-		if (const auto media = activeMediaView()) {
-			media->setBytes(localMedia->bytes());
-		}
+	if (const auto localMedia = local->activeMediaView()) {
+		const auto media = createMediaView();
+		media->collectLocalData(localMedia.get());
+
+		// Keep DocumentMedia alive for some more time.
+		// NB! This allows DocumentMedia to outlive Main::Session!
+		// In case this is a problem this code should be rewritten.
+		crl::on_main(&session(), [media] {});
 	}
 	if (!local->_location.inMediaCache() && !local->_location.isEmpty()) {
 		_location = local->_location;
diff --git a/Telegram/SourceFiles/data/data_document_media.cpp b/Telegram/SourceFiles/data/data_document_media.cpp
index d31aa607b..61dd9a06d 100644
--- a/Telegram/SourceFiles/data/data_document_media.cpp
+++ b/Telegram/SourceFiles/data/data_document_media.cpp
@@ -139,6 +139,9 @@ DocumentMedia::DocumentMedia(not_null<DocumentData*> owner)
 : _owner(owner) {
 }
 
+// NB! Right now DocumentMedia can outlive Main::Session!
+// In DocumentData::collectLocalData a shared_ptr is sent on_main.
+// In case this is a problem the ~Gif code should be rewritten.
 DocumentMedia::~DocumentMedia() = default;
 
 not_null<DocumentData*> DocumentMedia::owner() const {
@@ -291,6 +294,28 @@ void DocumentMedia::automaticLoad(
 		true);
 }
 
+void DocumentMedia::collectLocalData(not_null<DocumentMedia*> local) {
+	if (const auto image = local->_goodThumbnail.get()) {
+		_goodThumbnail = std::make_unique<Image>(
+			std::make_unique<Images::ImageSource>(image->original(), "PNG"));
+	}
+	if (const auto image = local->_inlineThumbnail.get()) {
+		_inlineThumbnail = std::make_unique<Image>(
+			std::make_unique<Images::ImageSource>(image->original(), "PNG"));
+	}
+	if (const auto image = local->_thumbnail.get()) {
+		_thumbnail = std::make_unique<Image>(
+			std::make_unique<Images::ImageSource>(image->original(), "PNG"));
+	}
+	if (const auto image = local->_sticker.get()) {
+		_sticker = std::make_unique<Image>(
+			std::make_unique<Images::ImageSource>(image->original(), "PNG"));
+	}
+	_bytes = local->_bytes;
+	_videoThumbnailBytes = local->_videoThumbnailBytes;
+	_flags = local->_flags;
+}
+
 void DocumentMedia::setBytes(const QByteArray &bytes) {
 	if (!bytes.isEmpty()) {
 		_bytes = bytes;
diff --git a/Telegram/SourceFiles/data/data_document_media.h b/Telegram/SourceFiles/data/data_document_media.h
index 4682fba6b..1fd8af8ce 100644
--- a/Telegram/SourceFiles/data/data_document_media.h
+++ b/Telegram/SourceFiles/data/data_document_media.h
@@ -76,6 +76,8 @@ public:
 
 	void automaticLoad(Data::FileOrigin origin, const HistoryItem *item);
 
+	void collectLocalData(not_null<DocumentMedia*> local);
+
 	// For DocumentData.
 	static void CheckGoodThumbnail(not_null<DocumentData*> document);
 
@@ -93,6 +95,9 @@ private:
 
 	[[nodiscard]] bool thumbnailEnoughForSticker() const;
 
+	// NB! Right now DocumentMedia can outlive Main::Session!
+	// In DocumentData::collectLocalData a shared_ptr is sent on_main.
+	// In case this is a problem the ~Gif code should be rewritten.
 	const not_null<DocumentData*> _owner;
 	std::unique_ptr<Image> _goodThumbnail;
 	mutable std::unique_ptr<Image> _inlineThumbnail;
diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp
index b8a4e6e10..7084be9f9 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp
@@ -85,7 +85,14 @@ Gif::Gif(
 	setStatusSize(FileStatusSizeReady);
 
 	refreshCaption();
-	_data->loadThumbnail(realParent->fullId());
+	if ((_dataMedia = _data->activeMediaView())) {
+		dataMediaCreated();
+	} else {
+		_data->loadThumbnail(realParent->fullId());
+		if (!autoplayEnabled()) {
+			_data->loadVideoThumbnail(realParent->fullId());
+		}
+	}
 }
 
 Gif::~Gif() {
@@ -427,7 +434,10 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
 				}
 			} else {
 				_data->loadThumbnail(_realParent->fullId());
-				if (const auto blurred = _dataMedia->thumbnailInline()) {
+				validateVideoThumbnail();
+				if (_videoThumbnailFrame) {
+					p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
+				} else if (const auto blurred = _dataMedia->thumbnailInline()) {
 					p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
 				} else if (!isRound) {
 					const auto roundTop = (roundCorners & RectPart::TopLeft);
@@ -632,6 +642,20 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
 	}
 }
 
+void Gif::validateVideoThumbnail() const {
+	const auto content = _dataMedia->videoThumbnailContent();
+	if (_videoThumbnailFrame || content.isEmpty()) {
+		return;
+	}
+	auto info = ::Media::Clip::PrepareForSending(QString(), content);
+	_videoThumbnailFrame = std::make_unique<Image>(
+		std::make_unique<Images::ImageSource>(
+			(info.thumbnail.isNull()
+				? Image::BlankMedia()->original()
+				: info.thumbnail),
+			"PNG"));
+}
+
 void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
 	if (!needCornerStatusDisplay()) {
 		return;
@@ -1086,8 +1110,17 @@ void Gif::ensureDataMediaCreated() const {
 		return;
 	}
 	_dataMedia = _data->createMediaView();
+	dataMediaCreated();
+}
+
+void Gif::dataMediaCreated() const {
+	Expects(_dataMedia != nullptr);
+
 	_dataMedia->goodThumbnailWanted();
 	_dataMedia->thumbnailWanted(_realParent->fullId());
+	if (!autoplayEnabled()) {
+		_dataMedia->videoThumbnailWanted(_realParent->fullId());
+	}
 	history()->owner().registerHeavyViewPart(_parent);
 }
 
diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h
index 44a9b69f5..d71b9941b 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_gif.h
+++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h
@@ -112,11 +112,14 @@ public:
 private:
 	struct Streamed;
 
+	void validateVideoThumbnail() const;
+
 	float64 dataProgress() const override;
 	bool dataFinished() const override;
 	bool dataLoaded() const override;
 
 	void ensureDataMediaCreated() const;
+	void dataMediaCreated() const;
 	void refreshCaption();
 
 	[[nodiscard]] bool autoplayEnabled() const;
@@ -171,6 +174,7 @@ private:
 	Ui::Text::String _caption;
 	std::unique_ptr<Streamed> _streamed;
 	mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
+	mutable std::unique_ptr<Image> _videoThumbnailFrame;
 
 	QString _downloadSize;