on 4be5ae1 help sign in
unity8/tests/mocks/QtMultimedia/mediaplayer.cpp
304 lines 8.6 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Michael Zanetti <michael.zanetti@canonical.com>
17 */
19#include "mediaplayer.h"
21#include <QDebug>
22#include <QSize>
24class MetaDataObject: public QObject
26 Q_OBJECT
27 Q_PROPERTY(QVariant title READ title NOTIFY metaDataChanged)
28 Q_PROPERTY(QVariant resolution READ resolution NOTIFY metaDataChanged)
29public:
30 MetaDataObject(MediaPlayer* parent = nullptr)
31 : QObject(parent)
32 , m_source(parent)
33 {
34 }
36 QVariant title() const { return getProperty("title"); }
37 QVariant resolution() const { return getProperty("resolution", QSize(640, 640)); }
39 QVariant getProperty(const QString& property, QVariant defaultValue = QVariant()) const {
40 MediaDataSource* sourceData = MediaPlayerDataController::instance()->dataForSource(m_source->source());
41 QVariant metaData = sourceData->metaData();
42 return metaData.toMap().value(property, defaultValue);
43 }
45Q_SIGNALS:
46 void metaDataChanged();
48private:
49 MediaPlayer* m_source;
50};
52MediaPlayer::MediaPlayer(QObject* parent)
53 : QObject(parent)
54 , m_playbackState(StoppedState)
55 , m_status(NoMedia)
56 , m_metaData(new MetaDataObject(this))
58 qsrand(time(nullptr));
59 m_timer.setInterval(100);
60 connect(&m_timer, SIGNAL(timeout()), SLOT(timerEvent()));
62 connect(MediaPlayerDataController::instance(), &MediaPlayerDataController::sourceAboutToBeRemoved,
63 this, [this](const QUrl& source) {
64 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source);
65 if (!dataSource) return;
67 disconnect(dataSource, &MediaDataSource::durationChanged, this, &MediaPlayer::durationChanged);
68 disconnect(dataSource, &MediaDataSource::seekableChanged, this, &MediaPlayer::seekableChanged);
69 disconnect(dataSource, &MediaDataSource::availabilityChanged, this, &MediaPlayer::availabilityChanged);
70 disconnect(dataSource, &MediaDataSource::metaDataChanged, m_metaData, &MetaDataObject::metaDataChanged);
71 });
73 connect(MediaPlayerDataController::instance(), &MediaPlayerDataController::sourceAdded,
74 this, [this](const QUrl& source) {
75 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source);
76 if (!dataSource) return;
78 connect(dataSource, &MediaDataSource::durationChanged, this, &MediaPlayer::durationChanged);
79 connect(dataSource, &MediaDataSource::seekableChanged,this, &MediaPlayer::seekableChanged);
80 connect(dataSource, &MediaDataSource::availabilityChanged,this, &MediaPlayer::availabilityChanged);
81 connect(dataSource, &MediaDataSource::metaDataChanged, m_metaData, &MetaDataObject::metaDataChanged);
82 });
85QUrl MediaPlayer::source() const
87 return m_source;
90void MediaPlayer::setSource(const QUrl &source)
92 if (m_source != source) {
93 m_source = source;
94 Q_EMIT sourceChanged(source);
95 Q_EMIT durationChanged(duration());
96 Q_EMIT seekableChanged(isSeekable());
97 Q_EMIT availabilityChanged(availability());
99 m_position = 0;
100 Q_EMIT positionChanged(m_position);
101 Q_EMIT m_metaData->metaDataChanged();
103 m_status = availability()==Available ? Loaded : InvalidMedia;
104 Q_EMIT statusChanged();
105 }
108MediaPlayer::PlaybackState MediaPlayer::playbackState() const
110 return m_playbackState;
113int MediaPlayer::position() const
115 return m_position;
118int MediaPlayer::duration() const
120 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
121 if (dataSource) return dataSource->duration();
122 return 0;
125MediaPlayer::Error MediaPlayer::error() const
127 return NoError;
130QString MediaPlayer::errorString() const
132 return QString();
135void MediaPlayer::pause()
137 if (m_playbackState == PlayingState) {
138 m_playbackState = PausedState;
139 Q_EMIT playbackStateChanged(m_playbackState);
140 m_timer.stop();
141 }
144void MediaPlayer::play()
146 if (m_playbackState != PlayingState) {
147 m_playbackState = PlayingState;
148 Q_EMIT playbackStateChanged(m_playbackState);
150 m_timer.start();
151 }
154void MediaPlayer::stop()
156 if (m_playbackState != StoppedState) {
157 m_playbackState = StoppedState;
158 Q_EMIT playbackStateChanged(m_playbackState);
159 m_timer.stop();
160 m_position = 0;
161 Q_EMIT positionChanged(m_position);
162 }
165void MediaPlayer::seek(int position)
167 if (status() != Loaded) return;
168 int newPosition = qMin(qMax(0, position), duration());
169 if (newPosition != m_position) {
170 m_position = newPosition;
171 Q_EMIT positionChanged(m_position);
172 }
176void MediaPlayer::timerEvent()
178 if (m_position + m_timer.interval() < duration()) {
179 m_position += m_timer.interval();
180 Q_EMIT positionChanged(m_position);
181 } else {
182 pause();
183 }
186MediaPlayer::AudioRole MediaPlayer::audioRole() const
188 return MediaPlayer::MultimediaRole;
191void MediaPlayer::setAudioRole(MediaPlayer::AudioRole audioRole)
193 Q_UNUSED(audioRole);
196bool MediaPlayer::isSeekable() const
198 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
199 if (dataSource) return dataSource->isSeekable();
200 return true;
203MediaPlayer::Availability MediaPlayer::availability() const
205 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
206 if (dataSource) return dataSource->availability();
207 return Available;
210QObject *MediaPlayer::metaData() const
212 return m_metaData;
216MediaDataSource::MediaDataSource(QObject *parent)
217 : QObject(parent)
218 , m_seekable(true)
219 , m_duration((qrand() % 20000) + 10000)
220 , m_availability(MediaPlayer::Available)
224MediaDataSource::~MediaDataSource()
226 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
229void MediaDataSource::setSource(const QUrl &source)
231 if (m_source != source) {
232 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
234 m_source = source;
236 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->registerDataSource(this);
237 Q_EMIT sourceChanged();
238 }
241void MediaDataSource::setSeekable(bool seekable)
243 if (m_seekable != seekable) {
244 m_seekable = seekable;
245 Q_EMIT seekableChanged(m_seekable);
246 }
249void MediaDataSource::setDuration(int duration)
251 if (m_duration != duration) {
252 m_duration = duration;
253 Q_EMIT durationChanged(m_duration);
254 }
257void MediaDataSource::setAvailability(MediaPlayer::Availability availability)
259 if (m_availability != availability) {
260 m_availability = availability;
261 Q_EMIT availabilityChanged(m_availability);
262 }
265void MediaDataSource::setMetaData(const QVariant& metaData)
267 if (m_metaData != metaData) {
268 m_metaData = metaData;
269 Q_EMIT metaDataChanged();
270 }
273MediaPlayerDataController *MediaPlayerDataController::instance()
275 static MediaPlayerDataController* instance = nullptr;
276 if (!instance) { instance = new MediaPlayerDataController(); }
277 return instance;
280void MediaPlayerDataController::registerDataSource(MediaDataSource *dataSource)
282 m_dataSources[dataSource->source()] = dataSource;
283 Q_EMIT sourceAdded(dataSource->source());
286void MediaPlayerDataController::unregisterDataSource(MediaDataSource *dataSource)
288 QList<QUrl> keys = m_dataSources.keys(dataSource);
289 Q_FOREACH(const QUrl& key, keys) {
290 Q_EMIT sourceAboutToBeRemoved(key);
291 m_dataSources.remove(key);
292 }
295MediaDataSource *MediaPlayerDataController::dataForSource(const QUrl &source)
297 if (!m_dataSources.contains(source)) {
298 static MediaDataSource defaultSource;
299 return &defaultSource;
300 }
301 return m_dataSources[source];
304#include "mediaplayer.moc"