2 * Copyright (C) 2013-2016 Canonical, Ltd.
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.
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.
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/>.
16 * Author: Michael Zanetti <michael.zanetti@canonical.com>
19#include "mediaplayer.h"
24class MetaDataObject: public QObject
27 Q_PROPERTY(QVariant title READ title NOTIFY metaDataChanged)
28 Q_PROPERTY(QVariant resolution READ resolution NOTIFY metaDataChanged)
30 MetaDataObject(MediaPlayer* parent = nullptr)
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);
46 void metaDataChanged();
49 MediaPlayer* m_source;
52MediaPlayer::MediaPlayer(QObject* parent)
54 , m_playbackState(StoppedState)
56 , m_metaData(new MetaDataObject(this))
59 qsrand(time(nullptr));
60 m_timer.setInterval(100);
61 connect(&m_timer, &QTimer::timeout, this, &MediaPlayer::timerEvent);
63 connect(MediaPlayerDataController::instance(), &MediaPlayerDataController::sourceAboutToBeRemoved,
64 this, [this](const QUrl& source) {
65 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source);
66 if (!dataSource) return;
68 disconnect(dataSource, &MediaDataSource::durationChanged, this, &MediaPlayer::durationChanged);
69 disconnect(dataSource, &MediaDataSource::seekableChanged, this, &MediaPlayer::seekableChanged);
70 disconnect(dataSource, &MediaDataSource::availabilityChanged, this, &MediaPlayer::availabilityChanged);
71 disconnect(dataSource, &MediaDataSource::metaDataChanged, m_metaData, &MetaDataObject::metaDataChanged);
74 connect(MediaPlayerDataController::instance(), &MediaPlayerDataController::sourceAdded,
75 this, [this](const QUrl& source) {
76 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source);
77 if (!dataSource) return;
79 connect(dataSource, &MediaDataSource::durationChanged, this, &MediaPlayer::durationChanged);
80 connect(dataSource, &MediaDataSource::seekableChanged,this, &MediaPlayer::seekableChanged);
81 connect(dataSource, &MediaDataSource::availabilityChanged,this, &MediaPlayer::availabilityChanged);
82 connect(dataSource, &MediaDataSource::metaDataChanged, m_metaData, &MetaDataObject::metaDataChanged);
86QUrl MediaPlayer::source() const
91void MediaPlayer::setSource(const QUrl &source)
93 if (m_source != source) {
95 Q_EMIT sourceChanged(source);
96 Q_EMIT durationChanged(duration());
97 Q_EMIT seekableChanged(isSeekable());
98 Q_EMIT availabilityChanged(availability());
101 Q_EMIT positionChanged(m_position);
102 Q_EMIT m_metaData->metaDataChanged();
104 m_status = availability()==Available ? Loaded : InvalidMedia;
105 Q_EMIT statusChanged();
109DeclarativePlaylist *MediaPlayer::playlist() const
114void MediaPlayer::setPlaylist(DeclarativePlaylist *playlist)
116 if (playlist == m_playlist)
119 m_playlist = playlist;
120 Q_EMIT playlistChanged();
123MediaPlayer::PlaybackState MediaPlayer::playbackState() const
125 return m_playbackState;
128int MediaPlayer::position() const
133int MediaPlayer::duration() const
135 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
136 if (dataSource) return dataSource->duration();
140MediaPlayer::Error MediaPlayer::error() const
145QString MediaPlayer::errorString() const
150void MediaPlayer::pause()
152 if (m_playbackState == PlayingState) {
153 m_playbackState = PausedState;
154 Q_EMIT playbackStateChanged(m_playbackState);
159void MediaPlayer::play()
161 if (m_playbackState != PlayingState) {
162 m_playbackState = PlayingState;
163 Q_EMIT playbackStateChanged(m_playbackState);
169void MediaPlayer::stop()
171 if (m_playbackState != StoppedState) {
172 m_playbackState = StoppedState;
173 Q_EMIT playbackStateChanged(m_playbackState);
176 Q_EMIT positionChanged(m_position);
180void MediaPlayer::seek(int position)
182 if (status() != Loaded) return;
183 int newPosition = qMin(qMax(0, position), duration());
184 if (newPosition != m_position) {
185 m_position = newPosition;
186 Q_EMIT positionChanged(m_position);
190void MediaPlayer::timerEvent()
192 if (m_position + m_timer.interval() < duration()) {
193 m_position += m_timer.interval();
194 Q_EMIT positionChanged(m_position);
200MediaPlayer::AudioRole MediaPlayer::audioRole() const
202 return MediaPlayer::MusicRole;
205void MediaPlayer::setAudioRole(MediaPlayer::AudioRole audioRole)
210bool MediaPlayer::isSeekable() const
212 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
213 if (dataSource) return dataSource->isSeekable();
217MediaPlayer::Availability MediaPlayer::availability() const
219 MediaDataSource* dataSource = MediaPlayerDataController::instance()->dataForSource(source());
220 if (dataSource) return dataSource->availability();
224QObject *MediaPlayer::metaData() const
230MediaDataSource::MediaDataSource(QObject *parent)
233 , m_duration((qrand() % 20000) + 10000)
234 , m_availability(MediaPlayer::Available)
238MediaDataSource::~MediaDataSource()
240 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
243void MediaDataSource::setSource(const QUrl &source)
245 if (m_source != source) {
246 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->unregisterDataSource(this);
250 if (!m_source.isEmpty()) MediaPlayerDataController::instance()->registerDataSource(this);
251 Q_EMIT sourceChanged();
255void MediaDataSource::setSeekable(bool seekable)
257 if (m_seekable != seekable) {
258 m_seekable = seekable;
259 Q_EMIT seekableChanged(m_seekable);
263void MediaDataSource::setDuration(int duration)
265 if (m_duration != duration) {
266 m_duration = duration;
267 Q_EMIT durationChanged(m_duration);
271void MediaDataSource::setAvailability(MediaPlayer::Availability availability)
273 if (m_availability != availability) {
274 m_availability = availability;
275 Q_EMIT availabilityChanged(m_availability);
279void MediaDataSource::setMetaData(const QVariant& metaData)
281 if (m_metaData != metaData) {
282 m_metaData = metaData;
283 Q_EMIT metaDataChanged();
287MediaPlayerDataController *MediaPlayerDataController::instance()
289 static MediaPlayerDataController* instance = nullptr;
290 if (!instance) { instance = new MediaPlayerDataController(); }
294void MediaPlayerDataController::registerDataSource(MediaDataSource *dataSource)
296 m_dataSources[dataSource->source()] = dataSource;
297 Q_EMIT sourceAdded(dataSource->source());
300void MediaPlayerDataController::unregisterDataSource(MediaDataSource *dataSource)
302 QList<QUrl> keys = m_dataSources.keys(dataSource);
303 Q_FOREACH(const QUrl& key, keys) {
304 Q_EMIT sourceAboutToBeRemoved(key);
305 m_dataSources.remove(key);
309MediaDataSource *MediaPlayerDataController::dataForSource(const QUrl &source)
311 if (!m_dataSources.contains(source)) {
312 static MediaDataSource defaultSource;
313 return &defaultSource;
315 return m_dataSources[source];
318#include "mediaplayer.moc"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list