summary refs log tree commit diff
path: root/src/timeline/InputBar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/timeline/InputBar.cpp')
-rw-r--r--src/timeline/InputBar.cpp98
1 files changed, 94 insertions, 4 deletions
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp

index 1b7d6efb..eda4507a 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp
@@ -11,6 +11,8 @@ #include <QFileDialog> #include <QGuiApplication> #include <QInputMethod> +#include <QMediaMetaData> +#include <QMediaPlayer> #include <QMimeData> #include <QMimeDatabase> #include <QStandardPaths> @@ -452,7 +454,8 @@ InputBar::audio(const QString &filename, const std::optional<mtx::crypto::EncryptedFile> &file, const QString &url, const QString &mime, - uint64_t dsize) + uint64_t dsize, + uint64_t duration) { mtx::events::msg::Audio audio; audio.info.mimetype = mime.toStdString(); @@ -460,6 +463,9 @@ InputBar::audio(const QString &filename, audio.body = filename.toStdString(); audio.url = url.toStdString(); + if (duration > 0) + audio.info.duration = duration; + if (file) audio.file = file; else @@ -482,13 +488,22 @@ InputBar::video(const QString &filename, const std::optional<mtx::crypto::EncryptedFile> &file, const QString &url, const QString &mime, - uint64_t dsize) + uint64_t dsize, + uint64_t duration, + const QSize &dimensions) { mtx::events::msg::Video video; video.info.mimetype = mime.toStdString(); video.info.size = dsize; video.body = filename.toStdString(); + if (duration > 0) + video.info.duration = duration; + if (dimensions.isValid()) { + video.info.h = dimensions.height(); + video.info.w = dimensions.width(); + } + if (file) video.file = file; else @@ -645,6 +660,7 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_, source->open(QIODevice::ReadOnly); data = source->readAll(); + source->reset(); if (!data.size()) { nhlog::ui()->warn("Attempted to upload zero-byte file?! Mimetype {}, filename {}", @@ -657,6 +673,8 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_, nhlog::ui()->debug("Mime: {}", mimetype_.toStdString()); if (mimeClass_ == u"image") { QImage img = utils::readImage(data); + setThumbnail(img.scaled( + std::min(800, img.width()), std::min(800, img.height()), Qt::KeepAspectRatioByExpanding)); dimensions_ = img.size(); if (img.height() > 200 && img.width() > 360) @@ -672,6 +690,78 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_, } blurhash_ = QString::fromStdString(blurhash::encode(data_.data(), img.width(), img.height(), 4, 3)); + } else if (mimeClass_ == u"video" || mimeClass_ == u"audio") { + auto mediaPlayer = new QMediaPlayer( + this, + mimeClass_ == u"video" ? QFlags{QMediaPlayer::StreamPlayback, QMediaPlayer::VideoSurface} + : QFlags{QMediaPlayer::StreamPlayback}); + mediaPlayer->setMuted(true); + + if (mimeClass_ == u"video") { + auto newSurface = new InputVideoSurface(this); + connect( + newSurface, &InputVideoSurface::newImage, this, [this, mediaPlayer](QImage img) { + mediaPlayer->stop(); + + nhlog::ui()->debug("Got image {}x{}", img.width(), img.height()); + + this->setThumbnail(img); + + if (!dimensions_.isValid()) + this->dimensions_ = img.size(); + + if (img.height() > 200 && img.width() > 360) + img = img.scaled(360, 200, Qt::KeepAspectRatioByExpanding); + std::vector<unsigned char> data_; + for (int y = 0; y < img.height(); y++) { + for (int x = 0; x < img.width(); x++) { + auto p = img.pixel(x, y); + data_.push_back(static_cast<unsigned char>(qRed(p))); + data_.push_back(static_cast<unsigned char>(qGreen(p))); + data_.push_back(static_cast<unsigned char>(qBlue(p))); + } + } + blurhash_ = QString::fromStdString( + blurhash::encode(data_.data(), img.width(), img.height(), 4, 3)); + }); + mediaPlayer->setVideoOutput(newSurface); + } + + connect(mediaPlayer, + qOverload<QMediaPlayer::Error>(&QMediaPlayer::error), + this, + [this, mediaPlayer](QMediaPlayer::Error error) { + nhlog::ui()->info("Media player error {} and errorStr {}", + error, + mediaPlayer->errorString().toStdString()); + }); + connect(mediaPlayer, + &QMediaPlayer::mediaStatusChanged, + [this, mediaPlayer](QMediaPlayer::MediaStatus status) { + nhlog::ui()->info( + "Media player status {} and error {}", status, mediaPlayer->error()); + }); + connect(mediaPlayer, + qOverload<const QString &, const QVariant &>(&QMediaPlayer::metaDataChanged), + [this, mediaPlayer](QString t, QVariant) { + nhlog::ui()->info("Got metadata {}", t.toStdString()); + + if (mediaPlayer->duration() > 0) + this->duration_ = mediaPlayer->duration(); + + dimensions_ = mediaPlayer->metaData(QMediaMetaData::Resolution).toSize(); + auto orientation = mediaPlayer->metaData(QMediaMetaData::Orientation).toInt(); + if (orientation == 90 || orientation == 270) { + dimensions_.transpose(); + } + }); + connect(mediaPlayer, &QMediaPlayer::durationChanged, [this, mediaPlayer](qint64 duration) { + if (duration > 0) + this->duration_ = mediaPlayer->duration(); + nhlog::ui()->info("Duration changed {}", duration); + }); + mediaPlayer->setMedia(QMediaContent(originalFilename_), source.get()); + mediaPlayer->play(); } } @@ -721,9 +811,9 @@ InputBar::finalizeUpload(MediaUpload *upload, QString url) if (mimeClass == u"image") image(filename, encryptedFile, url, mime, size, upload->dimensions(), upload->blurhash()); else if (mimeClass == u"audio") - audio(filename, encryptedFile, url, mime, size); + audio(filename, encryptedFile, url, mime, size, upload->duration()); else if (mimeClass == u"video") - video(filename, encryptedFile, url, mime, size); + video(filename, encryptedFile, url, mime, size, upload->duration(), upload->dimensions()); else file(filename, encryptedFile, url, mime, size);