on 22fee14 help sign in
unity8/tests/mocks/QtMultimedia/mediaplayer.cpp
291 lines 8.2 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 });
72 connect(MediaPlayerDataController::instance(), &MediaPlayerDataController::sourceAdded,
73 this, [this](const QUrl& source) {
74 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source);
75 if (!dataSource) return;
77 connect(dataSource, &MediaDataSource::durationChanged, this, &MediaPlayer::durationChanged);
78 connect(dataSource, &MediaDataSource::seekableChanged,this, &MediaPlayer::seekableChanged);
79 connect(dataSource, &MediaDataSource::availabilityChanged,this, &MediaPlayer::availabilityChanged);
80 });
83QUrl MediaPlayer::source() const
85 return m_source;
88void MediaPlayer::setSource(const QUrl &source)
90 if (m_source != source) {
91 m_source = source;
92 Q_EMIT sourceChanged(source);
93 Q_EMIT durationChanged(duration());
94 Q_EMIT seekableChanged(isSeekable());
95 Q_EMIT availabilityChanged(availability());
97 m_position = 0;
98 Q_EMIT positionChanged(m_position);
100 m_status = availability()==Available ? Loaded : InvalidMedia;
101 Q_EMIT statusChanged();
102 }
105MediaPlayer::PlaybackState MediaPlayer::playbackState() const
107 return m_playbackState;
110int MediaPlayer::position() const
112 return m_position;
115int MediaPlayer::duration() const
117 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
118 if (dataSource) return dataSource->duration();
119 return 0;
122QString MediaPlayer::errorString() const
124 return QString();
127void MediaPlayer::pause()
129 if (m_playbackState == PlayingState) {
130 m_playbackState = PausedState;
131 Q_EMIT playbackStateChanged(m_playbackState);
132 m_timer.stop();
133 }
136void MediaPlayer::play()
138 if (m_playbackState != PlayingState) {
139 m_playbackState = PlayingState;
140 Q_EMIT playbackStateChanged(m_playbackState);
142 m_timer.start();
143 }
146void MediaPlayer::stop()
148 if (m_playbackState != StoppedState) {
149 m_playbackState = StoppedState;
150 Q_EMIT playbackStateChanged(m_playbackState);
151 m_timer.stop();
152 m_position = 0;
153 Q_EMIT positionChanged(m_position);
154 }
157void MediaPlayer::seek(int position)
159 if (status() != Loaded) return;
160 int newPosition = qMin(qMax(0, position), duration());
161 if (newPosition != m_position) {
162 m_position = newPosition;
163 Q_EMIT positionChanged(m_position);
164 }
168void MediaPlayer::timerEvent()
170 if (m_position + m_timer.interval() < duration()) {
171 m_position += m_timer.interval();
172 Q_EMIT positionChanged(m_position);
173 } else {
174 pause();
175 }
178MediaPlayer::AudioRole MediaPlayer::audioRole() const
180 return MediaPlayer::MultimediaRole;
183void MediaPlayer::setAudioRole(MediaPlayer::AudioRole audioRole)
185 Q_UNUSED(audioRole);
188bool MediaPlayer::isSeekable() const
190 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
191 if (dataSource) return dataSource->isSeekable();
192 return true;
195MediaPlayer::Availability MediaPlayer::availability() const
197 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
198 if (dataSource) return dataSource->availability();
199 return Available;
203MediaDataSource::MediaDataSource(QObject *parent)
204 : QObject(parent)
205 , m_seekable(true)
206 , m_duration((qrand() % 20000) + 10000)
207 , m_availability(MediaPlayer::Available)
211MediaDataSource::~MediaDataSource()
213 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
216void MediaDataSource::setSource(const QUrl &source)
218 if (m_source != source) {
219 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
221 m_source = source;
223 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->registerDataSource(this);
224 Q_EMIT sourceChanged();
225 }
228void MediaDataSource::setSeekable(bool seekable)
230 if (m_seekable != seekable) {
231 m_seekable = seekable;
232 Q_EMIT seekableChanged(m_seekable);
233 }
236void MediaDataSource::setDuration(int duration)
238 if (m_duration != duration) {
239 m_duration = duration;
240 Q_EMIT durationChanged(m_duration);
241 }
244void MediaDataSource::setAvailability(MediaPlayer::Availability availability)
246 if (m_availability != availability) {
247 m_availability = availability;
248 Q_EMIT availabilityChanged(m_availability);
249 }
252void MediaDataSource::setMetaData(const QVariant& metaData)
254 if (m_metaData != metaData) {
255 m_metaData = metaData;
256 Q_EMIT metaDataChanged();
257 }
260MediaPlayerDataController *MediaPlayerDataController::instance()
262 static MediaPlayerDataController* instance = nullptr;
263 if (!instance) { instance = new MediaPlayerDataController(); }
264 return instance;
267void MediaPlayerDataController::registerDataSource(MediaDataSource *dataSource)
269 m_dataSources[dataSource->source()] = dataSource;
270 Q_EMIT sourceAdded(dataSource->source());
273void MediaPlayerDataController::unregisterDataSource(MediaDataSource *dataSource)
275 QList<QUrl> keys = m_dataSources.keys(dataSource);
276 Q_FOREACH(const QUrl& key, keys) {
277 Q_EMIT sourceAboutToBeRemoved(key);
278 m_dataSources.remove(key);
279 }
282MediaDataSource *MediaPlayerDataController::dataForSource(const QUrl &source)
284 if (!m_dataSources.contains(source)) {
285 static MediaDataSource defaultSource;
286 return &defaultSource;
287 }
288 return m_dataSources[source];
291#include "mediaplayer.moc"