File indexing completed on 2024-05-12 16:01:54

0001 /*
0002  *  SPDX-License-Identifier: GPL-3.0-or-later
0003  */
0004 
0005 #include "KisSyncedAudioPlayback.h"
0006 
0007 #include "config-qtmultimedia.h"
0008 
0009 #ifdef HAVE_QT_MULTIMEDIA
0010 #include <QtMultimedia/QMediaPlayer>
0011 #else
0012 class QIODevice;
0013 
0014 #include <QUrl>
0015 
0016 namespace {
0017 
0018     class QMediaPlayer : public QObject {
0019         Q_OBJECT
0020     public:
0021 
0022     enum Error
0023     {
0024         NoError,
0025         ResourceError,
0026         FormatError,
0027         NetworkError,
0028         AccessDeniedError,
0029         ServiceMissingError,
0030         MediaIsPlaylist
0031     };
0032 
0033     enum State
0034     {
0035         StoppedState,
0036         PlayingState,
0037         PausedState
0038     };
0039 
0040     State state() const { return StoppedState; }
0041 
0042     void play() {}
0043     void stop() {}
0044 
0045     qint64 position() const { return 0; }
0046     qreal playbackRate() const { return 1.0; }
0047     void setPosition(qint64) {}
0048     void setPlaybackRate(qreal) {}
0049     void setVolume(int) {}
0050     void setMedia(const QUrl&, QIODevice * device = 0) { Q_UNUSED(device);}
0051     QString errorString() const { return QString(); }
0052 
0053     Q_SIGNALS:
0054     void error(Error value);
0055     };
0056 }
0057 #endif
0058 
0059 
0060 
0061 #include <QFileInfo>
0062 
0063 
0064 
0065 struct KisSyncedAudioPlayback::Private
0066 {
0067     QMediaPlayer player;
0068     qint64 tolerance = 200;
0069 };
0070 
0071 
0072 KisSyncedAudioPlayback::KisSyncedAudioPlayback(const QString &fileName)
0073     : QObject(0),
0074       m_d(new Private)
0075 {
0076     QFileInfo fileInfo(fileName);
0077     Q_ASSERT(fileInfo.exists());
0078 
0079     m_d->player.setMedia(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
0080     m_d->player.setVolume(50);
0081 
0082     connect(&m_d->player, SIGNAL(error(QMediaPlayer::Error)), SLOT(slotOnError()));
0083 }
0084 
0085 KisSyncedAudioPlayback::~KisSyncedAudioPlayback()
0086 {
0087 }
0088 
0089 void KisSyncedAudioPlayback::setSoundOffsetTolerance(qint64 value)
0090 {
0091     m_d->tolerance = value;
0092 }
0093 
0094 void KisSyncedAudioPlayback::syncWithVideo(qint64 position)
0095 {
0096     if (qAbs(position - m_d->player.position()) > m_d->tolerance) {
0097         m_d->player.setPosition(position);
0098     }
0099 }
0100 
0101 bool KisSyncedAudioPlayback::isPlaying() const
0102 {
0103     return m_d->player.state() == QMediaPlayer::PlayingState;
0104 }
0105 
0106 qint64 KisSyncedAudioPlayback::position() const
0107 {
0108     return m_d->player.position();
0109 }
0110 
0111 void KisSyncedAudioPlayback::setVolume(qreal value)
0112 {
0113     m_d->player.setVolume(qRound(100.0 * value));
0114 }
0115 
0116 void KisSyncedAudioPlayback::setSpeed(qreal value)
0117 {
0118     if (qFuzzyCompare(value, m_d->player.playbackRate())) return;
0119 
0120     if (m_d->player.state() == QMediaPlayer::PlayingState) {
0121         const qint64 oldPosition = m_d->player.position();
0122 
0123         m_d->player.stop();
0124         m_d->player.setPlaybackRate(value);
0125         m_d->player.setPosition(oldPosition);
0126         m_d->player.play();
0127     } else {
0128         m_d->player.setPlaybackRate(value);
0129     }
0130 }
0131 
0132 void KisSyncedAudioPlayback::play(qint64 startPosition)
0133 {
0134     m_d->player.setPosition(startPosition);
0135     m_d->player.play();
0136 }
0137 
0138 void KisSyncedAudioPlayback::stop()
0139 {
0140     m_d->player.stop();
0141 }
0142 
0143 void KisSyncedAudioPlayback::slotOnError()
0144 {
0145 #ifdef HAVE_QT_MULTIMEDIA
0146 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
0147     emit error(m_d->player.media().request().url().toLocalFile(), m_d->player.errorString());
0148 #else
0149     emit error(m_d->player.media().canonicalUrl().toLocalFile(), m_d->player.errorString());
0150 #endif
0151 #endif
0152 }
0153 
0154 #ifndef HAVE_QT_MULTIMEDIA
0155 #include "KisSyncedAudioPlayback.moc"
0156 #endif