diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 4a9b09fa2..cdf9f42a2 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -4107,7 +4107,16 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 
 	switch (update.type()) {
 	case mtpc_updateNewMessage: {
-		const auto &d(update.c_updateNewMessage());
+		auto &d = update.c_updateNewMessage();
+
+		DataIsLoadedResult isDataLoaded = allDataLoadedForMessage(d.vmessage);
+		if (!requestingDifference() && isDataLoaded != DataIsLoadedResult::Ok) {
+			MTP_LOG(0, ("getDifference { good - after not all data loaded in updateNewMessage }%1").arg(cTestMode() ? " TESTMODE" : ""));
+
+			// This can be if this update was created by grouping
+			// some short message update into an updates vector.
+			return getDifference();
+		}
 
 		if (!ptsUpdated(d.vpts.v, d.vpts_count.v, update)) {
 			return;
@@ -4462,7 +4471,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 	} break;
 
 	case mtpc_updateNewChannelMessage: {
-		const auto &d(update.c_updateNewChannelMessage());
+		auto &d = update.c_updateNewChannelMessage();
 		ChannelData *channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage)));
 		DataIsLoadedResult isDataLoaded = allDataLoadedForMessage(d.vmessage);
 		if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) {
diff --git a/Telegram/SourceFiles/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp
index 799c3511a..71558181c 100644
--- a/Telegram/SourceFiles/media/media_audio.cpp
+++ b/Telegram/SourceFiles/media/media_audio.cpp
@@ -1765,8 +1765,8 @@ public:
 	FFMpegAttributesReader(const FileLocation &file, const QByteArray &data) : AbstractFFMpegLoader(file, data) {
 	}
 
-	bool open(qint64 position = 0) override {
-		if (!AbstractFFMpegLoader::open()) {
+	bool open(qint64 &position) override {
+		if (!AbstractFFMpegLoader::open(position)) {
 			return false;
 		}
 
@@ -1862,7 +1862,8 @@ private:
 
 MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat) {
 	FFMpegAttributesReader reader(FileLocation(StorageFilePartial, fname), data);
-	if (reader.open()) {
+	qint64 position = 0;
+	if (reader.open(position)) {
 		int32 duration = reader.duration() / reader.frequency();
 		if (reader.duration() > 0) {
 			cover = reader.cover();
@@ -1880,7 +1881,7 @@ public:
 	FFMpegWaveformCounter(const FileLocation &file, const QByteArray &data) : FFMpegLoader(file, data) {
 	}
 
-	bool open(qint64 position = 0) override {
+	bool open(qint64 &position) override {
 		if (!FFMpegLoader::open(position)) {
 			return false;
 		}
@@ -1976,7 +1977,8 @@ private:
 
 VoiceWaveform audioCountWaveform(const FileLocation &file, const QByteArray &data) {
 	FFMpegWaveformCounter counter(file, data);
-	if (counter.open()) {
+	qint64 position = 0;
+	if (counter.open(position)) {
 		return counter.waveform();
 	}
 	return VoiceWaveform();
diff --git a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp
index 69bd99cd2..b9ef7e020 100644
--- a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp
+++ b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp
@@ -25,7 +25,7 @@ constexpr AVSampleFormat AudioToFormat = AV_SAMPLE_FMT_S16;
 constexpr int64_t AudioToChannelLayout = AV_CH_LAYOUT_STEREO;
 constexpr int32 AudioToChannels = 2;
 
-bool AbstractFFMpegLoader::open(qint64 position) {
+bool AbstractFFMpegLoader::open(qint64 &position) {
 	if (!AudioPlayerLoader::openFile()) {
 		return false;
 	}
@@ -137,7 +137,7 @@ FFMpegLoader::FFMpegLoader(const FileLocation &file, const QByteArray &data) : A
 	frame = av_frame_alloc();
 }
 
-bool FFMpegLoader::open(qint64 position) {
+bool FFMpegLoader::open(qint64 &position) {
 	if (!AbstractFFMpegLoader::open(position)) {
 		return false;
 	}
@@ -210,6 +210,7 @@ bool FFMpegLoader::open(qint64 position) {
 		sampleSize = AudioToChannels * sizeof(short);
 		freq = dstRate;
 		len = av_rescale_rnd(len, dstRate, srcRate, AV_ROUND_UP);
+		position = av_rescale_rnd(position, dstRate, srcRate, AV_ROUND_DOWN);
 		fmt = AL_FORMAT_STEREO16;
 
 		maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
diff --git a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h
index 02ff3d3a3..c856be631 100644
--- a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h
+++ b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h
@@ -36,7 +36,7 @@ public:
 	AbstractFFMpegLoader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data) {
 	}
 
-	bool open(qint64 position = 0) override;
+	bool open(qint64 &position) override;
 
 	int64 duration() override {
 		return len;
@@ -72,7 +72,7 @@ class FFMpegLoader : public AbstractFFMpegLoader {
 public:
 	FFMpegLoader(const FileLocation &file, const QByteArray &data);
 
-	bool open(qint64 position = 0) override;
+	bool open(qint64 &position) override;
 
 	int32 format() override {
 		return fmt;
diff --git a/Telegram/SourceFiles/media/media_audio_loader.h b/Telegram/SourceFiles/media/media_audio_loader.h
index 74a749043..5e8a55012 100644
--- a/Telegram/SourceFiles/media/media_audio_loader.h
+++ b/Telegram/SourceFiles/media/media_audio_loader.h
@@ -27,7 +27,7 @@ public:
 
 	virtual bool check(const FileLocation &file, const QByteArray &data);
 
-	virtual bool open(qint64 position = 0) = 0;
+	virtual bool open(qint64 &position) = 0;
 	virtual int64 duration() = 0;
 	virtual int32 frequency() = 0;
 	virtual int32 format() = 0;
diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp
index 5b1805b93..491eb8cda 100644
--- a/Telegram/SourceFiles/media/media_audio_loaders.cpp
+++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp
@@ -321,7 +321,7 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) {
 	}
 }
 
-AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position) {
+AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, SetupError &err, qint64 &position) {
 	err = SetupErrorAtStart;
 	QMutexLocker lock(internal::audioPlayerMutex());
 	AudioPlayer *voice = audioPlayer();
diff --git a/Telegram/SourceFiles/media/media_audio_loaders.h b/Telegram/SourceFiles/media/media_audio_loaders.h
index 50a282b59..6e190ae95 100644
--- a/Telegram/SourceFiles/media/media_audio_loaders.h
+++ b/Telegram/SourceFiles/media/media_audio_loaders.h
@@ -73,7 +73,7 @@ private:
 		SetupNoErrorStarted = 3,
 	};
 	void loadData(AudioMsgId audio, qint64 position);
-	AudioPlayerLoader *setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position);
+	AudioPlayerLoader *setupLoader(const AudioMsgId &audio, SetupError &err, qint64 &position);
 	AudioPlayer::AudioMsg *checkLoader(AudioMsgId::Type type);
 
 };
diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp
index 5016b1b4f..143f9f1c6 100644
--- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp
+++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp
@@ -39,7 +39,7 @@ ChildFFMpegLoader::ChildFFMpegLoader(uint64 videoPlayId, std_::unique_ptr<VideoS
 	_frame = av_frame_alloc();
 }
 
-bool ChildFFMpegLoader::open(qint64 position) {
+bool ChildFFMpegLoader::open(qint64 &position) {
 	int res = 0;
 	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
 
@@ -100,6 +100,7 @@ bool ChildFFMpegLoader::open(qint64 position) {
 		_sampleSize = AudioToChannels * sizeof(short);
 		_parentData->frequency = _dstRate;
 		_parentData->length = av_rescale_rnd(_parentData->length, _dstRate, _srcRate, AV_ROUND_UP);
+		position = av_rescale_rnd(position, _dstRate, _srcRate, AV_ROUND_DOWN);
 		_format = AL_FORMAT_STEREO16;
 
 		_maxResampleSamples = av_rescale_rnd(AVBlockSize / _sampleSize, _dstRate, _srcRate, AV_ROUND_UP);
diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h
index 69926bfb8..ad92459ab 100644
--- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h
+++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h
@@ -83,7 +83,7 @@ class ChildFFMpegLoader : public AudioPlayerLoader {
 public:
 	ChildFFMpegLoader(uint64 videoPlayId, std_::unique_ptr<VideoSoundData> &&data);
 
-	bool open(qint64 position = 0) override;
+	bool open(qint64 &position) override;
 
 	bool check(const FileLocation &file, const QByteArray &data) override {
 		return true;
diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp
index 8e321eb16..3104c4d9f 100644
--- a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp
+++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp
@@ -96,7 +96,10 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() {
 			_currentFrameDelay = _nextFrameDelay;
 			if (_frameMs + _currentFrameDelay < frameMs) {
 				_currentFrameDelay = int32(frameMs - _frameMs);
+			} else if (frameMs < _frameMs + _currentFrameDelay) {
+				frameMs = _frameMs + _currentFrameDelay;
 			}
+
 			if (duration == AV_NOPTS_VALUE) {
 				_nextFrameDelay = 0;
 			} else {
@@ -129,7 +132,7 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() {
 			avcodec_flush_buffers(_codecContext);
 			_hadFrame = false;
 			_frameMs = 0;
-			_lastReadPacketMs = 0;
+			_lastReadVideoMs = _lastReadAudioMs = 0;
 		}
 	}
 
@@ -154,7 +157,6 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readFramesTill(int6
 
 	// sync by audio stream
 	auto correctMs = (frameMs >= 0) ? audioPlayer()->getVideoCorrectedTime(_playId, frameMs, systemMs) : frameMs;
-
 	if (!_frameRead) {
 		auto readResult = readNextFrame();
 		if (readResult != ReadResult::Success) {
@@ -237,7 +239,8 @@ bool FFMpegReaderImplementation::renderFrame(QImage &to, bool &hasAlpha, const Q
 
 	// Read some future packets for audio stream.
 	if (_audioStreamId >= 0) {
-		while (_frameMs + 5000 > _lastReadPacketMs) {
+		while (_frameMs + 5000 > _lastReadAudioMs
+			&& _frameMs + 15000 > _lastReadVideoMs) {
 			auto packetResult = readAndProcessPacket();
 			if (packetResult != PacketResult::Ok) {
 				break;
@@ -327,16 +330,16 @@ bool FFMpegReaderImplementation::start(Mode mode, int64 &positionMs) {
 		if ((res = avcodec_open2(audioContext, audioCodec, 0)) < 0) {
 			avcodec_free_context(&audioContext);
 			LOG(("Gif Error: Unable to avcodec_open2 %1, error %2, %3").arg(logData()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
-			return false;
-		}
-
-		soundData = std_::make_unique<VideoSoundData>();
-		soundData->context = audioContext;
-		soundData->frequency = audioContextOriginal->sample_rate;
-		if (_fmtContext->streams[_audioStreamId]->duration == AV_NOPTS_VALUE) {
-			soundData->length = (_fmtContext->duration * soundData->frequency) / AV_TIME_BASE;
+			_audioStreamId = -1;
 		} else {
-			soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den;
+			soundData = std_::make_unique<VideoSoundData>();
+			soundData->context = audioContext;
+			soundData->frequency = audioContextOriginal->sample_rate;
+			if (_fmtContext->streams[_audioStreamId]->duration == AV_NOPTS_VALUE) {
+				soundData->length = (_fmtContext->duration * soundData->frequency) / AV_TIME_BASE;
+			} else {
+				soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den;
+			}
 		}
 	}
 
@@ -425,11 +428,13 @@ void FFMpegReaderImplementation::processPacket(AVPacket *packet) {
 	bool videoPacket = (packet->stream_index == _streamId);
 	bool audioPacket = (_audioStreamId >= 0 && packet->stream_index == _audioStreamId);
 	if (audioPacket || videoPacket) {
-		_lastReadPacketMs = countPacketMs(packet);
-
 		if (videoPacket) {
+			_lastReadVideoMs = countPacketMs(packet);
+
 			_packetQueue.enqueue(FFMpeg::dataWrapFromPacket(*packet));
 		} else if (audioPacket) {
+			_lastReadAudioMs = countPacketMs(packet);
+
 			// queue packet to audio player
 			VideoSoundPart part;
 			part.packet = packet;
diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.h b/Telegram/SourceFiles/media/media_clip_ffmpeg.h
index c73fdc8ac..e9cf5074c 100644
--- a/Telegram/SourceFiles/media/media_clip_ffmpeg.h
+++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.h
@@ -92,7 +92,8 @@ private:
 
 	int _audioStreamId = 0;
 	uint64 _playId = 0;
-	int64 _lastReadPacketMs = 0;
+	int64 _lastReadVideoMs = 0;
+	int64 _lastReadAudioMs = 0;
 
 	QQueue<FFMpeg::AVPacketDataWrap> _packetQueue;
 	AVPacket _packetNull; // for final decoding
diff --git a/Telegram/SourceFiles/media/media_clip_reader.cpp b/Telegram/SourceFiles/media/media_clip_reader.cpp
index 0795ada90..ffb5cca8a 100644
--- a/Telegram/SourceFiles/media/media_clip_reader.cpp
+++ b/Telegram/SourceFiles/media/media_clip_reader.cpp
@@ -489,7 +489,6 @@ public:
 		int64 delta = static_cast<int64>(ms) - static_cast<int64>(_videoPausedAtMs);
 		_animationStarted += delta;
 		_nextFrameWhen += delta;
-		LOG(("RESUME VIDEO: next when: %1, started: %2, delta: %3").arg(_nextFrameWhen).arg(_animationStarted).arg(delta));
 
 		_videoPausedAtMs = 0;
 		_implementation->resumeAudio();