Fix crash when loading some chats with video.

Detect video availability when building the thumbnail in order to avoid playing all the file while waiting of a frame.
Fix image type detection from Mime (appimage was detected as an image and Qt considered compressed file as a readable image)
This commit is contained in:
Julien Wadel 2023-05-09 11:49:26 +02:00
parent 94b3501c6b
commit 1dd4f4f285
3 changed files with 41 additions and 13 deletions

View file

@ -984,7 +984,7 @@ void ChatRoomModel::initEntries(){
if( e->mType == ChatRoomModel::EntryType::MessageEntry){
connect(e.objectCast<ChatMessageModel>().get(), &ChatMessageModel::remove, this, &ChatRoomModel::removeEntry);
auto model = e.objectCast<ChatMessageModel>().get();
qDebug() << "Adding" << model->getReceivedTimestamp().toString("yyyy/MM/dd hh:mm:ss.zzz") << model->getTimestamp().toString("yyyy/MM/dd hh:mm:ss.zzz") << model->getChatMessage()->getUtf8Text().c_str();
qDebug() << "Adding" << model->getReceivedTimestamp().toString("yyyy/MM/dd hh:mm:ss.zzz") << model->getTimestamp().toString("yyyy/MM/dd hh:mm:ss.zzz") << QString(model->getChatMessage()->getUtf8Text().c_str()).left(5);
}
mList.push_back(e);
}
@ -1149,7 +1149,7 @@ QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::s
if(mIsInitialized && !exists(message)){
model = ChatMessageModel::create(message);
if(model){
qDebug() << "Adding at end" << model->getReceivedTimestamp().toString("hh:mm:ss.zzz") << model->getTimestamp().toString("hh:mm:ss.zzz") << message->getUtf8Text().c_str();
qDebug() << "Adding at end" << model->getReceivedTimestamp().toString("hh:mm:ss.zzz") << model->getTimestamp().toString("hh:mm:ss.zzz") << QString(message->getUtf8Text().c_str()).left(5);
connect(model.get(), &ChatMessageModel::remove, this, &ChatRoomModel::removeEntry);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
add(model);

View file

@ -160,19 +160,45 @@ QImage ImageModel::createThumbnail(const QString& path){
originalImage = QImage(path, format);
else if(Utils::isVideo(path)){
QObject context;
int mediaStep = 0;
QMediaPlayer player(&context);
player.setMedia(QUrl::fromLocalFile(path));
player.setPosition(player.duration() / 2);
VideoFrameGrabber grabber(&context);
player.setVideoOutput(&grabber);
// Media connections
QObject::connect(&player, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error), &context, [&context, &mediaStep, path](QMediaPlayer::Error error) mutable{
mediaStep = -1;
});
QObject::connect(&player, &QMediaPlayer::mediaStatusChanged, &context, [&context, &player, &mediaStep](QMediaPlayer::MediaStatus status) mutable{
switch(status){
case QMediaPlayer::LoadedMedia : if(mediaStep == 0){
if( player.isVideoAvailable() )
mediaStep = 1;
else
mediaStep = -1;
}
break;
case QMediaPlayer::UnknownMediaStatus:
case QMediaPlayer::InvalidMedia:
case QMediaPlayer::EndOfMedia:
mediaStep = -1;
break;
default:{}
}
});
QObject::connect(&grabber, &VideoFrameGrabber::frameAvailable, &context, [&context,&originalImage, &player](QImage frame) mutable{
originalImage = frame.copy();
player.stop();
}, Qt::DirectConnection);
player.play();
// Processing
player.setVideoOutput(&grabber);
player.setMedia(QUrl::fromLocalFile(path));
do{
qApp->processEvents();
}while(player.state() != QMediaPlayer::State::StoppedState);
if(mediaStep == 1){
mediaStep = 2;
player.setPosition(player.duration() / 2);
player.play();
}
}while(mediaStep >= 0 );
}
}
if (!originalImage.isNull()){

View file

@ -624,25 +624,27 @@ bool Utils::isMe(const std::shared_ptr<const linphone::Address>& address){
bool Utils::isAnimatedImage(const QString& path){
if(path.isEmpty()) return false;
QFileInfo info(path);
if( !info.exists())
if( !info.exists() || !QMimeDatabase().mimeTypeForFile(info).name().contains("image/"))
return false;
QImageReader reader(path);
return reader.supportsAnimation() && reader.imageCount() > 1;
return reader.canRead() && reader.supportsAnimation() && reader.imageCount() > 1;
}
bool Utils::isImage(const QString& path){
if(path.isEmpty()) return false;
QFileInfo info(path);
if( !info.exists()){
return QMimeDatabase().mimeTypeForFile(info, QMimeDatabase::MatchExtension).name().contains("image");
}
return QMimeDatabase().mimeTypeForFile(info, QMimeDatabase::MatchExtension).name().contains("image/");
}else if(!QMimeDatabase().mimeTypeForFile(info).name().contains("image/"))
return false;
QImageReader reader(path);
return reader.imageCount() == 1;
qWarning() << reader.imageCount();
return reader.canRead() && reader.imageCount() == 1;
}
bool Utils::isVideo(const QString& path){
if(path.isEmpty()) return false;
return QMimeDatabase().mimeTypeForFile(path).name().contains("video");
return QMimeDatabase().mimeTypeForFile(path).name().contains("video/");
}
bool Utils::isPdf(const QString& path){