fix: sync danmaku and buffer updates with mpv
This commit is contained in:
@@ -217,6 +217,7 @@ bool MpvController::init() {
|
|||||||
observeProperty("eof-reached", MPV_FORMAT_FLAG);
|
observeProperty("eof-reached", MPV_FORMAT_FLAG);
|
||||||
|
|
||||||
observeProperty("cache-speed", MPV_FORMAT_INT64);
|
observeProperty("cache-speed", MPV_FORMAT_INT64);
|
||||||
|
observeProperty("demuxer-cache-time", MPV_FORMAT_DOUBLE);
|
||||||
observeProperty("volume", MPV_FORMAT_DOUBLE);
|
observeProperty("volume", MPV_FORMAT_DOUBLE);
|
||||||
observeProperty("mute", MPV_FORMAT_FLAG);
|
observeProperty("mute", MPV_FORMAT_FLAG);
|
||||||
observeProperty("speed", MPV_FORMAT_DOUBLE);
|
observeProperty("speed", MPV_FORMAT_DOUBLE);
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ void MpvWidget::onMpvRenderUpdate(void *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MpvWidget::maybeUpdate() {
|
void MpvWidget::maybeUpdate() {
|
||||||
|
Q_EMIT renderUpdateRequested();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ signals:
|
|||||||
void playbackStateChanged(bool isPaused);
|
void playbackStateChanged(bool isPaused);
|
||||||
void networkSpeedChanged(qint64 bytesPerSecond);
|
void networkSpeedChanged(qint64 bytesPerSecond);
|
||||||
void relayActiveChanged(bool active);
|
void relayActiveChanged(bool active);
|
||||||
|
void renderUpdateRequested();
|
||||||
void errorOccurred(const QString &errorMsg);
|
void errorOccurred(const QString &errorMsg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -155,16 +155,8 @@ NativeDanmakuOverlay::NativeDanmakuOverlay(MpvController *controller,
|
|||||||
m_frameTimer = new QTimer(this);
|
m_frameTimer = new QTimer(this);
|
||||||
m_frameTimer->setTimerType(Qt::PreciseTimer);
|
m_frameTimer->setTimerType(Qt::PreciseTimer);
|
||||||
m_frameTimer->setInterval(kFallbackFrameIntervalMs);
|
m_frameTimer->setInterval(kFallbackFrameIntervalMs);
|
||||||
connect(m_frameTimer, &QTimer::timeout, this, [this]() {
|
connect(m_frameTimer, &QTimer::timeout, this,
|
||||||
const qint64 positionMs = currentPositionMs();
|
&NativeDanmakuOverlay::advanceFrame);
|
||||||
if (m_lastResolvedPositionMs < 0 || positionMs < m_lastResolvedPositionMs ||
|
|
||||||
positionMs - m_lastResolvedPositionMs > 1500) {
|
|
||||||
rebuildActiveItems(positionMs);
|
|
||||||
} else {
|
|
||||||
updateActiveItems(positionMs);
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_scheduleRebuildTimer = new QTimer(this);
|
m_scheduleRebuildTimer = new QTimer(this);
|
||||||
m_scheduleRebuildTimer->setSingleShot(true);
|
m_scheduleRebuildTimer->setSingleShot(true);
|
||||||
@@ -279,6 +271,32 @@ void NativeDanmakuOverlay::setBottomSubtitleProtected(bool enabled)
|
|||||||
requestScheduleRebuild(false, false);
|
requestScheduleRebuild(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeDanmakuOverlay::setExternalFrameClockEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (m_externalFrameClockEnabled == enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_externalFrameClockEnabled = enabled;
|
||||||
|
syncFrameTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeDanmakuOverlay::advanceFrame()
|
||||||
|
{
|
||||||
|
if (!shouldAdvanceFrames()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const qint64 positionMs = currentPositionMs();
|
||||||
|
if (m_lastResolvedPositionMs < 0 || positionMs < m_lastResolvedPositionMs ||
|
||||||
|
positionMs - m_lastResolvedPositionMs > 1500) {
|
||||||
|
rebuildActiveItems(positionMs);
|
||||||
|
} else {
|
||||||
|
updateActiveItems(positionMs);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void NativeDanmakuOverlay::paintEvent(QPaintEvent *event)
|
void NativeDanmakuOverlay::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
@@ -649,15 +667,17 @@ void NativeDanmakuOverlay::clearScheduledState(bool clearSpriteCache)
|
|||||||
|
|
||||||
void NativeDanmakuOverlay::syncFrameTimer()
|
void NativeDanmakuOverlay::syncFrameTimer()
|
||||||
{
|
{
|
||||||
|
if (m_externalFrameClockEnabled) {
|
||||||
|
m_frameTimer->stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int targetInterval = targetFrameIntervalMs();
|
const int targetInterval = targetFrameIntervalMs();
|
||||||
if (m_frameTimer->interval() != targetInterval) {
|
if (m_frameTimer->interval() != targetInterval) {
|
||||||
m_frameTimer->setInterval(targetInterval);
|
m_frameTimer->setInterval(targetInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool shouldRun =
|
if (shouldAdvanceFrames()) {
|
||||||
m_visibleRequested && isVisible() && !m_schedule.isEmpty() &&
|
|
||||||
!m_playbackPaused;
|
|
||||||
if (shouldRun) {
|
|
||||||
if (!m_frameTimer->isActive()) {
|
if (!m_frameTimer->isActive()) {
|
||||||
m_frameTimer->start();
|
m_frameTimer->start();
|
||||||
}
|
}
|
||||||
@@ -667,6 +687,12 @@ void NativeDanmakuOverlay::syncFrameTimer()
|
|||||||
m_frameTimer->stop();
|
m_frameTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeDanmakuOverlay::shouldAdvanceFrames() const
|
||||||
|
{
|
||||||
|
return m_visibleRequested && isVisible() && !m_schedule.isEmpty() &&
|
||||||
|
!m_playbackPaused;
|
||||||
|
}
|
||||||
|
|
||||||
int NativeDanmakuOverlay::targetFrameIntervalMs() const
|
int NativeDanmakuOverlay::targetFrameIntervalMs() const
|
||||||
{
|
{
|
||||||
const QScreen *screen = targetScreen();
|
const QScreen *screen = targetScreen();
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public:
|
|||||||
|
|
||||||
void setDanmakuVisible(bool visible);
|
void setDanmakuVisible(bool visible);
|
||||||
void setBottomSubtitleProtected(bool enabled);
|
void setBottomSubtitleProtected(bool enabled);
|
||||||
|
void setExternalFrameClockEnabled(bool enabled);
|
||||||
|
void advanceFrame();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
@@ -70,6 +72,7 @@ private:
|
|||||||
void updateActiveItems(qint64 positionMs);
|
void updateActiveItems(qint64 positionMs);
|
||||||
void clearScheduledState(bool clearSpriteCache = false);
|
void clearScheduledState(bool clearSpriteCache = false);
|
||||||
void syncFrameTimer();
|
void syncFrameTimer();
|
||||||
|
bool shouldAdvanceFrames() const;
|
||||||
int targetFrameIntervalMs() const;
|
int targetFrameIntervalMs() const;
|
||||||
QScreen *targetScreen() const;
|
QScreen *targetScreen() const;
|
||||||
void updateScreenRefreshBinding();
|
void updateScreenRefreshBinding();
|
||||||
@@ -125,6 +128,7 @@ private:
|
|||||||
bool m_bottomSubtitleProtected = false;
|
bool m_bottomSubtitleProtected = false;
|
||||||
bool m_scheduleDirty = false;
|
bool m_scheduleDirty = false;
|
||||||
bool m_clearSpriteCacheOnNextRebuild = false;
|
bool m_clearSpriteCacheOnNextRebuild = false;
|
||||||
|
bool m_externalFrameClockEnabled = false;
|
||||||
mutable bool m_surfaceRectDirty = true;
|
mutable bool m_surfaceRectDirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -384,93 +384,19 @@ PlayerView::PlayerView(QEmbyCore *core, QWidget *parent)
|
|||||||
|
|
||||||
|
|
||||||
m_bufferTimer = new QTimer(this);
|
m_bufferTimer = new QTimer(this);
|
||||||
m_bufferTimer->setInterval(500);
|
m_bufferTimer->setInterval(250);
|
||||||
connect(m_bufferTimer, &QTimer::timeout, this,
|
connect(m_bufferTimer, &QTimer::timeout, this,
|
||||||
[this]()
|
[this]()
|
||||||
{
|
{
|
||||||
if (m_totalDuration > 0 && m_mpvWidget && m_mpvWidget->controller())
|
updateBufferProgress();
|
||||||
{
|
|
||||||
double bufferedPos = m_currentPosition;
|
|
||||||
|
|
||||||
|
|
||||||
QVariant stateVar = m_mpvWidget->controller()->getProperty("demuxer-cache-state");
|
|
||||||
if (stateVar.isValid() && stateVar.metaType().id() == QMetaType::QVariantMap)
|
|
||||||
{
|
|
||||||
auto ranges = stateVar.toMap()["seekable-ranges"].toList();
|
|
||||||
if (!ranges.isEmpty())
|
|
||||||
{
|
|
||||||
|
|
||||||
bufferedPos = ranges.last().toMap()["end"].toDouble();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
double cacheDuration =
|
|
||||||
m_mpvWidget->controller()->getProperty("demuxer-cache-duration").toDouble();
|
|
||||||
if (cacheDuration > 0)
|
|
||||||
{
|
|
||||||
bufferedPos = m_currentPosition + cacheDuration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bufferedPos > m_totalDuration)
|
|
||||||
{
|
|
||||||
bufferedPos = m_totalDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_progressSlider->setBufferValue(static_cast<int>(bufferedPos));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_showStatisticsOverlay && m_statisticsOverlay)
|
if (m_showStatisticsOverlay && m_statisticsOverlay)
|
||||||
{
|
{
|
||||||
updateStatisticsDisplay();
|
m_bufferTimerTick = (m_bufferTimerTick + 1) % 2;
|
||||||
}
|
if (m_bufferTimerTick == 0)
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
m_mousePollTimer = new QTimer(this);
|
|
||||||
m_mousePollTimer->setInterval(100);
|
|
||||||
connect(m_mousePollTimer, &QTimer::timeout, this,
|
|
||||||
[this]()
|
|
||||||
{
|
|
||||||
if (!m_isPlaying)
|
|
||||||
{
|
|
||||||
if (m_topOpacity->opacity() < 1.0)
|
|
||||||
{
|
{
|
||||||
showControls();
|
updateStatisticsDisplay();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (areControlsFullyVisible() && this->cursor().shape() != Qt::BlankCursor &&
|
|
||||||
(!m_mpvWidget || m_mpvWidget->cursor().shape() != Qt::BlankCursor))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint currentPos = QCursor::pos();
|
|
||||||
if (currentPos == m_lastMousePos)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lastMousePos = currentPos;
|
|
||||||
|
|
||||||
|
|
||||||
if (this->window()->isMinimized() || !this->isVisible())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint localPos = this->mapFromGlobal(currentPos);
|
|
||||||
bool isMouseInside = this->rect().contains(localPos);
|
|
||||||
|
|
||||||
|
|
||||||
if (isMouseInside)
|
|
||||||
{
|
|
||||||
handlePointerActivity(currentPos);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1118,6 +1044,9 @@ void PlayerView::setupUi()
|
|||||||
m_mpvWidget->installEventFilter(this);
|
m_mpvWidget->installEventFilter(this);
|
||||||
m_mpvWidget->setMouseTracking(true);
|
m_mpvWidget->setMouseTracking(true);
|
||||||
m_nativeDanmakuOverlay = new NativeDanmakuOverlay(m_mpvWidget->controller(), this);
|
m_nativeDanmakuOverlay = new NativeDanmakuOverlay(m_mpvWidget->controller(), this);
|
||||||
|
m_nativeDanmakuOverlay->setExternalFrameClockEnabled(true);
|
||||||
|
connect(m_mpvWidget, &MpvWidget::renderUpdateRequested, m_nativeDanmakuOverlay,
|
||||||
|
&NativeDanmakuOverlay::advanceFrame);
|
||||||
m_danmakuController = new PlayerDanmakuController(m_core, m_mpvWidget, m_nativeDanmakuOverlay, this);
|
m_danmakuController = new PlayerDanmakuController(m_core, m_mpvWidget, m_nativeDanmakuOverlay, this);
|
||||||
connect(m_danmakuController, &PlayerDanmakuController::toastRequested, this,
|
connect(m_danmakuController, &PlayerDanmakuController::toastRequested, this,
|
||||||
[this](const QString &message) { showToast(message); });
|
[this](const QString &message) { showToast(message); });
|
||||||
@@ -2419,8 +2348,6 @@ void PlayerView::stopAndReport()
|
|||||||
|
|
||||||
if (m_reportTimer)
|
if (m_reportTimer)
|
||||||
m_reportTimer->stop();
|
m_reportTimer->stop();
|
||||||
if (m_mousePollTimer)
|
|
||||||
m_mousePollTimer->stop();
|
|
||||||
m_longPressHandler->stopKeyLongPress(false);
|
m_longPressHandler->stopKeyLongPress(false);
|
||||||
m_longPressHandler->stopMouseEdgeLongPress();
|
m_longPressHandler->stopMouseEdgeLongPress();
|
||||||
if (m_bufferTimer)
|
if (m_bufferTimer)
|
||||||
@@ -2512,8 +2439,6 @@ void PlayerView::beginViewTeardown()
|
|||||||
|
|
||||||
if (m_reportTimer)
|
if (m_reportTimer)
|
||||||
m_reportTimer->stop();
|
m_reportTimer->stop();
|
||||||
if (m_mousePollTimer)
|
|
||||||
m_mousePollTimer->stop();
|
|
||||||
if (m_bufferTimer)
|
if (m_bufferTimer)
|
||||||
m_bufferTimer->stop();
|
m_bufferTimer->stop();
|
||||||
if (m_hideTimer)
|
if (m_hideTimer)
|
||||||
@@ -2974,8 +2899,7 @@ bool PlayerView::eventFilter(QObject *watched, QEvent *event)
|
|||||||
else if (event->type() == QEvent::MouseMove)
|
else if (event->type() == QEvent::MouseMove)
|
||||||
{
|
{
|
||||||
auto *me = static_cast<QMouseEvent *>(event);
|
auto *me = static_cast<QMouseEvent *>(event);
|
||||||
m_lastMousePos = me->globalPosition().toPoint();
|
handlePointerActivity(me->globalPosition().toPoint());
|
||||||
handlePointerActivity(m_lastMousePos);
|
|
||||||
const QPoint localPos = this->mapFromGlobal(me->globalPosition().toPoint());
|
const QPoint localPos = this->mapFromGlobal(me->globalPosition().toPoint());
|
||||||
const bool isOnHud = m_topHUD->geometry().contains(localPos) || m_bottomHUD->geometry().contains(localPos);
|
const bool isOnHud = m_topHUD->geometry().contains(localPos) || m_bottomHUD->geometry().contains(localPos);
|
||||||
const bool movedEnough =
|
const bool movedEnough =
|
||||||
@@ -3044,6 +2968,10 @@ bool PlayerView::eventFilter(QObject *watched, QEvent *event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->type() == QEvent::Enter)
|
||||||
|
{
|
||||||
|
handlePointerActivity(QCursor::pos());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3121,6 +3049,30 @@ void PlayerView::handlePointerActivity(const QPoint &globalPos)
|
|||||||
showControls();
|
showControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerView::updateBufferProgress()
|
||||||
|
{
|
||||||
|
if (!m_progressSlider || m_totalDuration <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double bufferedPos = m_bufferedPosition;
|
||||||
|
if (std::isnan(bufferedPos) || std::isinf(bufferedPos) || bufferedPos <= 0.0)
|
||||||
|
{
|
||||||
|
bufferedPos = m_currentPosition;
|
||||||
|
}
|
||||||
|
if (bufferedPos < m_currentPosition)
|
||||||
|
{
|
||||||
|
bufferedPos = m_currentPosition;
|
||||||
|
}
|
||||||
|
if (bufferedPos > m_totalDuration)
|
||||||
|
{
|
||||||
|
bufferedPos = m_totalDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_progressSlider->setBufferValue(static_cast<int>(bufferedPos));
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerView::setCursorHidden(bool hidden)
|
void PlayerView::setCursorHidden(bool hidden)
|
||||||
{
|
{
|
||||||
const auto targetShape = hidden ? Qt::BlankCursor : Qt::ArrowCursor;
|
const auto targetShape = hidden ? Qt::BlankCursor : Qt::ArrowCursor;
|
||||||
@@ -3363,8 +3315,22 @@ void PlayerView::onMpvPropertyChanged(const QString &property, const QVariant &v
|
|||||||
else if (property == "seeking")
|
else if (property == "seeking")
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const bool wasSeeking = m_isSeeking;
|
||||||
m_isSeeking = value.toBool();
|
m_isSeeking = value.toBool();
|
||||||
updateLoadingState();
|
updateLoadingState();
|
||||||
|
if (wasSeeking && !m_isSeeking)
|
||||||
|
{
|
||||||
|
QTimer::singleShot(0, this, [this]() { reportProgressToServer(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (property == "demuxer-cache-time")
|
||||||
|
{
|
||||||
|
const double cacheTime = value.toDouble();
|
||||||
|
if (!std::isnan(cacheTime) && !std::isinf(cacheTime) && cacheTime >= 0.0)
|
||||||
|
{
|
||||||
|
m_bufferedPosition = cacheTime;
|
||||||
|
updateBufferProgress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (property == "eof-reached")
|
else if (property == "eof-reached")
|
||||||
{
|
{
|
||||||
@@ -4686,6 +4652,8 @@ void PlayerView::playMedia(const QString &mediaId, const QString &title, const Q
|
|||||||
m_hasReportedStop = false;
|
m_hasReportedStop = false;
|
||||||
m_isPlaybackFinished = false;
|
m_isPlaybackFinished = false;
|
||||||
m_autoPlayAdvanceInProgress = false;
|
m_autoPlayAdvanceInProgress = false;
|
||||||
|
m_bufferedPosition = 0.0;
|
||||||
|
m_bufferTimerTick = 0;
|
||||||
m_currentMediaId = mediaId;
|
m_currentMediaId = mediaId;
|
||||||
m_currentMediaSourceId = mediaId;
|
m_currentMediaSourceId = mediaId;
|
||||||
m_currentPlaySessionId.clear();
|
m_currentPlaySessionId.clear();
|
||||||
@@ -4776,6 +4744,7 @@ void PlayerView::playMedia(const QString &mediaId, const QString &title, const Q
|
|||||||
|
|
||||||
m_currentPosition = m_pendingSeekSeconds;
|
m_currentPosition = m_pendingSeekSeconds;
|
||||||
m_totalDuration = 0.0;
|
m_totalDuration = 0.0;
|
||||||
|
updateBufferProgress();
|
||||||
|
|
||||||
if (m_statisticsOverlay)
|
if (m_statisticsOverlay)
|
||||||
{
|
{
|
||||||
@@ -5109,7 +5078,6 @@ void PlayerView::playMedia(const QString &mediaId, const QString &title, const Q
|
|||||||
startPositionTicks);
|
startPositionTicks);
|
||||||
|
|
||||||
m_reportTimer->start();
|
m_reportTimer->start();
|
||||||
m_mousePollTimer->start();
|
|
||||||
m_bufferTimer->start();
|
m_bufferTimer->start();
|
||||||
showControls();
|
showControls();
|
||||||
}
|
}
|
||||||
@@ -5141,7 +5109,15 @@ void PlayerView::onBackClicked()
|
|||||||
|
|
||||||
|
|
||||||
prepareForStackLeave();
|
prepareForStackLeave();
|
||||||
Q_EMIT navigateBack();
|
QTimer::singleShot(0, this,
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
if (!m_hasReportedStop)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_EMIT navigateBack();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ private:
|
|||||||
void setCursorHidden(bool hidden);
|
void setCursorHidden(bool hidden);
|
||||||
bool areControlsFullyVisible() const;
|
bool areControlsFullyVisible() const;
|
||||||
void setPlayerChromeVisible(bool visible);
|
void setPlayerChromeVisible(bool visible);
|
||||||
|
void updateBufferProgress();
|
||||||
|
|
||||||
void stopTransientUiAnimations(bool immediate = false);
|
void stopTransientUiAnimations(bool immediate = false);
|
||||||
void beginViewTeardown();
|
void beginViewTeardown();
|
||||||
@@ -261,10 +262,10 @@ private:
|
|||||||
QParallelAnimationGroup *m_fadeGroup;
|
QParallelAnimationGroup *m_fadeGroup;
|
||||||
QTimer *m_hideTimer;
|
QTimer *m_hideTimer;
|
||||||
QTimer *m_reportTimer;
|
QTimer *m_reportTimer;
|
||||||
QTimer *m_mousePollTimer;
|
|
||||||
|
|
||||||
|
|
||||||
QTimer *m_bufferTimer;
|
QTimer *m_bufferTimer;
|
||||||
|
int m_bufferTimerTick = 0;
|
||||||
|
|
||||||
QString m_currentMediaId;
|
QString m_currentMediaId;
|
||||||
QString m_currentMediaSourceId;
|
QString m_currentMediaSourceId;
|
||||||
@@ -283,6 +284,7 @@ private:
|
|||||||
|
|
||||||
double m_currentPosition;
|
double m_currentPosition;
|
||||||
double m_totalDuration = 0.0;
|
double m_totalDuration = 0.0;
|
||||||
|
double m_bufferedPosition = 0.0;
|
||||||
double m_pendingSeekSeconds = 0.0;
|
double m_pendingSeekSeconds = 0.0;
|
||||||
double m_osdSeekPreviewPosition = -1.0;
|
double m_osdSeekPreviewPosition = -1.0;
|
||||||
|
|
||||||
@@ -333,7 +335,6 @@ private:
|
|||||||
QRect m_originalGeometry;
|
QRect m_originalGeometry;
|
||||||
bool m_wasMaximized = false;
|
bool m_wasMaximized = false;
|
||||||
QPoint m_dragPos;
|
QPoint m_dragPos;
|
||||||
QPoint m_lastMousePos;
|
|
||||||
bool m_didDrag = false;
|
bool m_didDrag = false;
|
||||||
QTimer *m_singleClickTimer = nullptr;
|
QTimer *m_singleClickTimer = nullptr;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user