288 lines
8 KiB
C++
288 lines
8 KiB
C++
// For license of this file, see <project-root-folder>/LICENSE.md.
|
|
|
|
#include "gui/mediaplayer/qtmultimedia/qtmultimediabackend.h"
|
|
|
|
#if QT_VERSION_MAJOR == 6
|
|
#include <QAudioOutput>
|
|
#include <QWindow>
|
|
#endif
|
|
|
|
#include <QLayout>
|
|
#include <QVideoWidget>
|
|
|
|
QtMultimediaBackend::QtMultimediaBackend(QWidget* parent)
|
|
: PlayerBackend(parent),
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_audio(new QAudioOutput(this)),
|
|
#endif
|
|
m_player(new QMediaPlayer(this)),
|
|
|
|
m_video(new QVideoWidget(this)) {
|
|
layout()->addWidget(m_video);
|
|
|
|
m_player->setVideoOutput(m_video);
|
|
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->setAudioOutput(m_audio);
|
|
#endif
|
|
|
|
connect(m_player, &QMediaPlayer::durationChanged, this, &QtMultimediaBackend::onDurationChanged);
|
|
|
|
#if QT_VERSION_MAJOR == 6
|
|
connect(m_player, &QMediaPlayer::errorOccurred, this, &QtMultimediaBackend::onErrorOccurred);
|
|
#else
|
|
connect(m_player, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error), this, [this](QMediaPlayer::Error error) {
|
|
onErrorOccurred(error);
|
|
});
|
|
#endif
|
|
|
|
#if QT_VERSION_MAJOR == 6
|
|
connect(m_player, &QMediaPlayer::hasAudioChanged, this, &QtMultimediaBackend::onAudioAvailable);
|
|
connect(m_player, &QMediaPlayer::hasVideoChanged, this, &QtMultimediaBackend::onVideoAvailable);
|
|
connect(m_player, &QMediaPlayer::playbackStateChanged, this, &QtMultimediaBackend::onPlaybackStateChanged);
|
|
#else
|
|
connect(m_player, &QMediaPlayer::audioAvailableChanged, this, &QtMultimediaBackend::onAudioAvailable);
|
|
connect(m_player, &QMediaPlayer::videoAvailableChanged, this, &QtMultimediaBackend::onVideoAvailable);
|
|
connect(m_player, &QMediaPlayer::stateChanged, this, &QtMultimediaBackend::onPlaybackStateChanged);
|
|
#endif
|
|
|
|
connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &QtMultimediaBackend::onMediaStatusChanged);
|
|
connect(m_player, &QMediaPlayer::positionChanged, this, &QtMultimediaBackend::onPositionChanged);
|
|
connect(m_player, &QMediaPlayer::seekableChanged, this, &QtMultimediaBackend::onSeekableChanged);
|
|
connect(m_player, &QMediaPlayer::playbackRateChanged, this, &QtMultimediaBackend::onPlaybackRateChanged);
|
|
}
|
|
|
|
int QtMultimediaBackend::convertToSliderProgress(qint64 player_progress) const {
|
|
return player_progress / 1000;
|
|
}
|
|
|
|
int QtMultimediaBackend::convertDuration(qint64 duration) const {
|
|
return duration / 1000;
|
|
}
|
|
|
|
qreal QtMultimediaBackend::convertSpeed(int speed) const {
|
|
return speed / 100.0;
|
|
}
|
|
|
|
int QtMultimediaBackend::convertSpinSpeed(qreal speed) const {
|
|
return speed * 100;
|
|
}
|
|
|
|
float QtMultimediaBackend::convertSliderVolume(int slider_volume) const {
|
|
return slider_volume / 100.0f;
|
|
}
|
|
|
|
qint64 QtMultimediaBackend::convertSliderProgress(int slider_progress) const {
|
|
return qint64(slider_progress) * qint64(1000);
|
|
}
|
|
|
|
QString QtMultimediaBackend::mediaStatusToString(QMediaPlayer::MediaStatus status) const {
|
|
switch (status) {
|
|
case QMediaPlayer::NoMedia:
|
|
return tr("No media");
|
|
|
|
case QMediaPlayer::LoadingMedia:
|
|
return tr("Loading...");
|
|
|
|
case QMediaPlayer::LoadedMedia:
|
|
return tr("Media loaded");
|
|
|
|
case QMediaPlayer::StalledMedia:
|
|
return tr("Media stalled");
|
|
|
|
case QMediaPlayer::BufferingMedia:
|
|
return tr("Buffering...");
|
|
|
|
case QMediaPlayer::BufferedMedia:
|
|
return tr("Loaded");
|
|
|
|
case QMediaPlayer::EndOfMedia:
|
|
return tr("Ended");
|
|
|
|
case QMediaPlayer::InvalidMedia:
|
|
return tr("Media is invalid");
|
|
|
|
default:
|
|
return tr("Unknown");
|
|
}
|
|
}
|
|
|
|
QString QtMultimediaBackend::errorToString(QMediaPlayer::Error error) const {
|
|
switch (error) {
|
|
case QMediaPlayer::ResourceError:
|
|
return tr("Cannot load media (missing codecs)");
|
|
|
|
case QMediaPlayer::FormatError:
|
|
return tr("Unrecognized format");
|
|
|
|
case QMediaPlayer::NetworkError:
|
|
return tr("Network problem");
|
|
|
|
case QMediaPlayer::AccessDeniedError:
|
|
return tr("Access denied");
|
|
|
|
#if QT_VERSION_MAJOR == 5
|
|
case QMediaPlayer::ServiceMissingError:
|
|
return tr("Service is missing");
|
|
|
|
case QMediaPlayer::MediaIsPlaylist:
|
|
return tr("This is playlist");
|
|
#endif
|
|
|
|
case QMediaPlayer::NoError:
|
|
return tr("No errors");
|
|
|
|
default:
|
|
return tr("Unknown error");
|
|
}
|
|
}
|
|
|
|
void QtMultimediaBackend::playUrl(const QUrl& url) {
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->setSource(url);
|
|
#else
|
|
m_player->setMedia(QUrl(url));
|
|
#endif
|
|
|
|
m_player->play();
|
|
}
|
|
|
|
void QtMultimediaBackend::playPause() {
|
|
if (m_player->PLAYBACK_STATE_METHOD() != QMediaPlayer::PLAYBACK_STATE::PlayingState) {
|
|
m_player->play();
|
|
}
|
|
else {
|
|
m_player->pause();
|
|
}
|
|
}
|
|
|
|
void QtMultimediaBackend::pause() {
|
|
m_player->pause();
|
|
}
|
|
|
|
void QtMultimediaBackend::stop() {
|
|
m_player->stop();
|
|
}
|
|
|
|
void QtMultimediaBackend::setPlaybackSpeed(int speed) {
|
|
m_player->setPlaybackRate(convertSpeed(speed));
|
|
}
|
|
|
|
void QtMultimediaBackend::setVolume(int volume) {
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->audioOutput()->setVolume(convertSliderVolume(volume));
|
|
#else
|
|
m_player->setVolume(volume);
|
|
#endif
|
|
|
|
emit volumeChanged(volume);
|
|
}
|
|
|
|
void QtMultimediaBackend::setPosition(int position) {
|
|
m_player->setPosition(convertSliderProgress(position));
|
|
}
|
|
|
|
void QtMultimediaBackend::setFullscreen(bool fullscreen) {
|
|
Q_UNUSED(fullscreen)
|
|
// No extra work needed here.
|
|
}
|
|
|
|
void QtMultimediaBackend::setMuted(bool muted) {
|
|
// This backend audio class does not support muting on Qt 5, so we emulate
|
|
// muting by seting volume to 0;
|
|
if (muted) {
|
|
// Remember volume and mute.
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_volume = convertToSliderVolume(m_player->audioOutput()->volume());
|
|
#else
|
|
m_volume = m_player->volume();
|
|
#endif
|
|
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->audioOutput()->setVolume(convertSliderVolume(0));
|
|
#else
|
|
m_player->setVolume(0);
|
|
#endif
|
|
}
|
|
else {
|
|
// Unmute.
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->audioOutput()->setVolume(convertSliderVolume(m_volume));
|
|
#else
|
|
m_player->setVolume(m_volume);
|
|
#endif
|
|
}
|
|
|
|
emit mutedChanged(muted);
|
|
}
|
|
|
|
QUrl QtMultimediaBackend::url() const {
|
|
return
|
|
#if QT_VERSION_MAJOR == 6
|
|
m_player->source();
|
|
#else
|
|
m_player->media().request().url();
|
|
#endif
|
|
}
|
|
|
|
int QtMultimediaBackend::position() const {
|
|
return convertToSliderProgress(m_player->position());
|
|
}
|
|
|
|
int QtMultimediaBackend::duration() const {
|
|
return convertDuration(m_player->duration());
|
|
}
|
|
|
|
void QtMultimediaBackend::onPositionChanged(qint64 position) {
|
|
emit positionChanged(convertToSliderProgress(position));
|
|
}
|
|
|
|
void QtMultimediaBackend::onPlaybackRateChanged(qreal speed) {
|
|
emit speedChanged(convertSpinSpeed(speed));
|
|
}
|
|
|
|
void QtMultimediaBackend::onDurationChanged(qint64 duration) {
|
|
emit durationChanged(convertDuration(duration));
|
|
}
|
|
|
|
void QtMultimediaBackend::onErrorOccurred(QMediaPlayer::Error error, const QString& error_string) {
|
|
QString err = error_string.isEmpty() ? errorToString(error) : error_string;
|
|
emit errorOccurred(err);
|
|
}
|
|
|
|
void QtMultimediaBackend::onAudioAvailable(bool available) {
|
|
emit audioAvailable(available);
|
|
}
|
|
|
|
void QtMultimediaBackend::onVideoAvailable(bool available) {
|
|
emit videoAvailable(available);
|
|
}
|
|
|
|
void QtMultimediaBackend::onMediaStatusChanged(QMediaPlayer::MediaStatus status) {
|
|
QString st = mediaStatusToString(status);
|
|
emit statusChanged(st);
|
|
}
|
|
|
|
void QtMultimediaBackend::onPlaybackStateChanged(QMediaPlayer::PLAYBACK_STATE state) {
|
|
switch (state) {
|
|
case QMediaPlayer::PLAYBACK_STATE::StoppedState:
|
|
emit playbackStateChanged(PlayerBackend::PlaybackState::StoppedState);
|
|
break;
|
|
|
|
case QMediaPlayer::PLAYBACK_STATE::PlayingState:
|
|
emit playbackStateChanged(PlayerBackend::PlaybackState::PlayingState);
|
|
break;
|
|
|
|
case QMediaPlayer::PLAYBACK_STATE::PausedState:
|
|
emit playbackStateChanged(PlayerBackend::PlaybackState::PausedState);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void QtMultimediaBackend::onSeekableChanged(bool seekable) {
|
|
emit seekableChanged(seekable);
|
|
}
|
|
|
|
int QtMultimediaBackend::convertToSliderVolume(float volume) const {
|
|
return volume * 100;
|
|
}
|