mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Fix lag when media messages are shown and fix media controls
This commit is contained in:
parent
87c063b112
commit
eed23cdf11
4 changed files with 67 additions and 34 deletions
|
@ -24,23 +24,24 @@ Item {
|
||||||
property int tempWidth: originalWidth < 1? 400: originalWidth
|
property int tempWidth: originalWidth < 1? 400: originalWidth
|
||||||
implicitWidth: type == MtxEvent.VideoMessage ? Math.round(tempWidth*Math.min((timelineView.height/divisor)/(tempWidth*proportionalHeight), 1)) : 500
|
implicitWidth: type == MtxEvent.VideoMessage ? Math.round(tempWidth*Math.min((timelineView.height/divisor)/(tempWidth*proportionalHeight), 1)) : 500
|
||||||
width: Math.min(parent?.width ?? implicitWidth, implicitWidth)
|
width: Math.min(parent?.width ?? implicitWidth, implicitWidth)
|
||||||
height: (type == MtxEvent.VideoMessage ? width*proportionalHeight : 80) + fileInfoLabel.height
|
height: (type == MtxEvent.VideoMessage ? width*proportionalHeight : mediaControls.height) + fileInfoLabel.height
|
||||||
//implicitHeight: height
|
//implicitHeight: height
|
||||||
|
|
||||||
property int metadataWidth
|
property int metadataWidth
|
||||||
property bool fitsMetadata: (parent.width - fileInfoLabel.width) > metadataWidth+4
|
property bool fitsMetadata: parent != null ? ((parent.width - fileInfoLabel.width) > metadataWidth+4) : false
|
||||||
|
|
||||||
|
Component.onCompleted: mxcmedia.startDownload(true)
|
||||||
|
|
||||||
MxcMedia {
|
MxcMedia {
|
||||||
id: mxcmedia
|
id: mxcmedia
|
||||||
|
|
||||||
// TODO: Show error in overlay or so?
|
// TODO: Show error in overlay or so?
|
||||||
roomm: room
|
roomm: room
|
||||||
// FIXME: This takes 500ms on my device, why and how can we avoid that?
|
eventId: content.eventId
|
||||||
audioOutput: AudioOutput {
|
|
||||||
muted: mediaControls.muted
|
|
||||||
volume: mediaControls.desiredVolume
|
|
||||||
}
|
|
||||||
videoOutput: videoOutput
|
videoOutput: videoOutput
|
||||||
|
|
||||||
|
muted: mediaControls.muted
|
||||||
|
volume: mediaControls.desiredVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -56,6 +57,7 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
visible: content.type == MtxEvent.VideoMessage
|
||||||
source: content.thumbnailUrl ? thumbnailUrl.replace("mxc://", "image://MxcImage/") + "?scale" : "image://colorimage/:/icons/icons/ui/video-file.svg?" + palette.windowText
|
source: content.thumbnailUrl ? thumbnailUrl.replace("mxc://", "image://MxcImage/") + "?scale" : "image://colorimage/:/icons/icons/ui/video-file.svg?" + palette.windowText
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
|
@ -85,7 +87,7 @@ Item {
|
||||||
mediaState: mxcmedia.playbackState
|
mediaState: mxcmedia.playbackState
|
||||||
onPositionChanged: mxcmedia.position = position
|
onPositionChanged: mxcmedia.position = position
|
||||||
onPlayPauseActivated: mxcmedia.playbackState == MediaPlayer.PlayingState ? mxcmedia.pause() : mxcmedia.play()
|
onPlayPauseActivated: mxcmedia.playbackState == MediaPlayer.PlayingState ? mxcmedia.pause() : mxcmedia.play()
|
||||||
onLoadActivated: mxcmedia.eventId = eventId
|
onLoadActivated: mxcmedia.startDownload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ Rectangle {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
anchors.bottom: control.bottom
|
anchors.bottom: control.bottom
|
||||||
anchors.left: control.left
|
anchors.left: control.left
|
||||||
anchors.right: control.right
|
width: Math.max(implicitWidth, control.width)
|
||||||
|
|
||||||
NhekoSlider {
|
NhekoSlider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -134,8 +134,9 @@ Rectangle {
|
||||||
|
|
||||||
state: ""
|
state: ""
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
Layout.preferredWidth: 0
|
Layout.preferredWidth: 100
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
enabled: false
|
||||||
orientation: Qt.Horizontal
|
orientation: Qt.Horizontal
|
||||||
value: 1
|
value: 1
|
||||||
onDesiredVolumeChanged: {
|
onDesiredVolumeChanged: {
|
||||||
|
@ -158,12 +159,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
properties: "Layout.preferredWidth"
|
|
||||||
duration: 150
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
Transition {
|
Transition {
|
||||||
from: "shown"
|
from: "shown"
|
||||||
|
@ -181,10 +176,6 @@ Rectangle {
|
||||||
easing.type: Easing.InQuad
|
easing.type: Easing.InQuad
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
properties: "Layout.preferredWidth"
|
|
||||||
duration: 150
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,28 +188,25 @@ Rectangle {
|
||||||
name: "shown"
|
name: "shown"
|
||||||
when: Settings.mobileMode || volumeButton.hovered || volumeSlider.hovered || volumeSlider.pressed
|
when: Settings.mobileMode || volumeButton.hovered || volumeSlider.hovered || volumeSlider.pressed
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
volumeSlider.implicitWidth: 100
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
volumeSlider.opacity: 1
|
volumeSlider.opacity: 1
|
||||||
|
volumeSlider.enabled: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
text: (!control.mediaLoaded ? "-- " : durationToString(control.positionValue)) + " / " + durationToString(control.duration)
|
text: (!control.mediaLoaded ? "-- " : durationToString(control.positionValue)) + " / " + durationToString(control.duration)
|
||||||
color: palette.text
|
color: palette.text
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
MxcMediaProxy::MxcMediaProxy(QObject *parent)
|
MxcMediaProxy::MxcMediaProxy(QObject *parent)
|
||||||
: QMediaPlayer(parent)
|
: QMediaPlayer(parent)
|
||||||
{
|
{
|
||||||
connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload);
|
|
||||||
connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload);
|
|
||||||
connect(
|
connect(
|
||||||
this, &QMediaPlayer::errorOccurred, this, [](QMediaPlayer::Error error, QString errorString) {
|
this, &QMediaPlayer::errorOccurred, this, [](QMediaPlayer::Error error, QString errorString) {
|
||||||
nhlog::ui()->debug("Media player error {} and errorStr {}",
|
nhlog::ui()->debug("Media player error {} and errorStr {}",
|
||||||
|
@ -36,6 +34,17 @@ MxcMediaProxy::MxcMediaProxy(QObject *parent)
|
||||||
static_cast<int>(status),
|
static_cast<int>(status),
|
||||||
static_cast<int>(this->error()));
|
static_cast<int>(this->error()));
|
||||||
});
|
});
|
||||||
|
connect(this, &MxcMediaProxy::playbackStateChanged, [this](QMediaPlayer::PlaybackState status) {
|
||||||
|
// We only set the output when starting the playback because otherwise the audio device
|
||||||
|
// lookup takes about 500ms, which causes a lot of stutter...
|
||||||
|
if (status == QMediaPlayer::PlayingState && !audioOutput()) {
|
||||||
|
nhlog::ui()->debug("Set audio output");
|
||||||
|
auto newOut = new QAudioOutput(this);
|
||||||
|
newOut->setMuted(muted_);
|
||||||
|
newOut->setVolume(volume_);
|
||||||
|
setAudioOutput(newOut);
|
||||||
|
}
|
||||||
|
});
|
||||||
connect(this, &MxcMediaProxy::metaDataChanged, [this]() { emit orientationChanged(); });
|
connect(this, &MxcMediaProxy::metaDataChanged, [this]() { emit orientationChanged(); });
|
||||||
|
|
||||||
connect(ChatPage::instance()->timelineManager()->rooms(),
|
connect(ChatPage::instance()->timelineManager()->rooms(),
|
||||||
|
@ -55,7 +64,7 @@ MxcMediaProxy::orientation() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MxcMediaProxy::startDownload()
|
MxcMediaProxy::startDownload(bool onlyCached)
|
||||||
{
|
{
|
||||||
if (!room_)
|
if (!room_)
|
||||||
return;
|
return;
|
||||||
|
@ -126,6 +135,9 @@ MxcMediaProxy::startDownload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (onlyCached)
|
||||||
|
return;
|
||||||
|
|
||||||
http::client()->download(url,
|
http::client()->download(url,
|
||||||
[filename, url, processBuffer](const std::string &data,
|
[filename, url, processBuffer](const std::string &data,
|
||||||
const std::string &,
|
const std::string &,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAudioOutput>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QMediaPlayer>
|
#include <QMediaPlayer>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
@ -26,9 +27,16 @@ class MxcMediaProxy : public QMediaPlayer
|
||||||
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
|
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
|
||||||
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
|
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
|
||||||
Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged)
|
Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged)
|
||||||
|
Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||||
|
Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MxcMediaProxy(QObject *parent = nullptr);
|
MxcMediaProxy(QObject *parent = nullptr);
|
||||||
|
~MxcMediaProxy()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
this->setSourceDevice(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
bool loaded() const { return buffer.size() > 0; }
|
bool loaded() const { return buffer.size() > 0; }
|
||||||
QString eventId() const { return eventId_; }
|
QString eventId() const { return eventId_; }
|
||||||
|
@ -45,6 +53,25 @@ public:
|
||||||
}
|
}
|
||||||
int orientation() const;
|
int orientation() const;
|
||||||
|
|
||||||
|
float volume() const { return volume_; }
|
||||||
|
bool muted() const { return muted_; }
|
||||||
|
void setVolume(float val)
|
||||||
|
{
|
||||||
|
volume_ = val;
|
||||||
|
if (auto output = audioOutput()) {
|
||||||
|
output->setVolume(val);
|
||||||
|
}
|
||||||
|
emit volumeChanged();
|
||||||
|
}
|
||||||
|
void setMuted(bool val)
|
||||||
|
{
|
||||||
|
muted_ = val;
|
||||||
|
if (auto output = audioOutput()) {
|
||||||
|
output->setMuted(val);
|
||||||
|
}
|
||||||
|
emit mutedChanged();
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void roomChanged();
|
void roomChanged();
|
||||||
void eventIdChanged();
|
void eventIdChanged();
|
||||||
|
@ -52,10 +79,12 @@ signals:
|
||||||
void newBuffer(QUrl, QIODevice *buf);
|
void newBuffer(QUrl, QIODevice *buf);
|
||||||
|
|
||||||
void orientationChanged();
|
void orientationChanged();
|
||||||
void videoSurfaceChanged();
|
|
||||||
|
|
||||||
private slots:
|
void volumeChanged();
|
||||||
void startDownload();
|
void mutedChanged();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void startDownload(bool onlyCached = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TimelineModel *room_ = nullptr;
|
TimelineModel *room_ = nullptr;
|
||||||
|
@ -63,4 +92,6 @@ private:
|
||||||
QString filename_;
|
QString filename_;
|
||||||
QBuffer buffer;
|
QBuffer buffer;
|
||||||
QObject *m_surface = nullptr;
|
QObject *m_surface = nullptr;
|
||||||
|
float volume_ = 1.f;
|
||||||
|
bool muted_ = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue