1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qmedianetworkplaylistprovider_p.h"
41#include "qmediaplaylistprovider_p.h"
42#include "qmediacontent.h"
43#include "qmediaobject_p.h"
44#include "qplaylistfileparser_p.h"
45#include "qrandom.h"
46
47QT_BEGIN_NAMESPACE
48
49class QMediaNetworkPlaylistProviderPrivate: public QMediaPlaylistProviderPrivate
50{
51 Q_DECLARE_NON_CONST_PUBLIC(QMediaNetworkPlaylistProvider)
52public:
53 bool load(const QNetworkRequest &request);
54
55 QPlaylistFileParser parser;
56 QList<QMediaContent> resources;
57
58 void _q_handleParserError(QPlaylistFileParser::ParserError err, const QString &);
59 void _q_handleNewItem(const QVariant& content);
60
61 QMediaNetworkPlaylistProvider *q_ptr;
62};
63
64bool QMediaNetworkPlaylistProviderPrivate::load(const QNetworkRequest &request)
65{
66 parser.abort();
67 parser.start(request);
68
69 return true;
70}
71
72void QMediaNetworkPlaylistProviderPrivate::_q_handleParserError(QPlaylistFileParser::ParserError err, const QString &errorMessage)
73{
74 Q_Q(QMediaNetworkPlaylistProvider);
75
76 QMediaPlaylist::Error playlistError = QMediaPlaylist::NoError;
77
78 switch (err) {
79 case QPlaylistFileParser::NoError:
80 return;
81 case QPlaylistFileParser::FormatError:
82 playlistError = QMediaPlaylist::FormatError;
83 break;
84 case QPlaylistFileParser::FormatNotSupportedError:
85 playlistError = QMediaPlaylist::FormatNotSupportedError;
86 break;
87 case QPlaylistFileParser::ResourceError:
88 // fall through
89 case QPlaylistFileParser::NetworkError:
90 playlistError = QMediaPlaylist::NetworkError;
91 break;
92 }
93
94 parser.abort();
95
96 emit q->loadFailed(playlistError, errorMessage);
97}
98
99void QMediaNetworkPlaylistProviderPrivate::_q_handleNewItem(const QVariant& content)
100{
101 Q_Q(QMediaNetworkPlaylistProvider);
102
103 QUrl url;
104 if (content.type() == QVariant::Url) {
105 url = content.toUrl();
106 } else if (content.type() == QVariant::Map) {
107 url = content.toMap()[QLatin1String("url")].toUrl();
108 } else {
109 return;
110 }
111
112 q->addMedia(content: QMediaContent(url));
113}
114
115QMediaNetworkPlaylistProvider::QMediaNetworkPlaylistProvider(QObject *parent)
116 :QMediaPlaylistProvider(*new QMediaNetworkPlaylistProviderPrivate, parent)
117{
118 d_func()->q_ptr = this;
119 connect(sender: &d_func()->parser, SIGNAL(newItem(QVariant)),
120 receiver: this, SLOT(_q_handleNewItem(QVariant)));
121 connect(sender: &d_func()->parser, SIGNAL(finished()), receiver: this, SIGNAL(loaded()));
122 connect(sender: &d_func()->parser, SIGNAL(error(QPlaylistFileParser::ParserError,QString)),
123 receiver: this, SLOT(_q_handleParserError(QPlaylistFileParser::ParserError,QString)));
124}
125
126QMediaNetworkPlaylistProvider::~QMediaNetworkPlaylistProvider()
127{
128}
129
130bool QMediaNetworkPlaylistProvider::isReadOnly() const
131{
132 return false;
133}
134
135bool QMediaNetworkPlaylistProvider::load(const QNetworkRequest &request, const char *format)
136{
137 Q_UNUSED(format);
138 return d_func()->load(request);
139}
140
141int QMediaNetworkPlaylistProvider::mediaCount() const
142{
143 return d_func()->resources.size();
144}
145
146QMediaContent QMediaNetworkPlaylistProvider::media(int pos) const
147{
148 return d_func()->resources.value(i: pos);
149}
150
151bool QMediaNetworkPlaylistProvider::addMedia(const QMediaContent &content)
152{
153 Q_D(QMediaNetworkPlaylistProvider);
154
155 int pos = d->resources.count();
156
157 emit mediaAboutToBeInserted(start: pos, end: pos);
158 d->resources.append(t: content);
159 emit mediaInserted(start: pos, end: pos);
160
161 return true;
162}
163
164bool QMediaNetworkPlaylistProvider::addMedia(const QList<QMediaContent> &items)
165{
166 Q_D(QMediaNetworkPlaylistProvider);
167
168 if (items.isEmpty())
169 return true;
170
171 int pos = d->resources.count();
172 int end = pos+items.count()-1;
173
174 emit mediaAboutToBeInserted(start: pos, end);
175 d->resources.append(t: items);
176 emit mediaInserted(start: pos, end);
177
178 return true;
179}
180
181
182bool QMediaNetworkPlaylistProvider::insertMedia(int pos, const QMediaContent &content)
183{
184 Q_D(QMediaNetworkPlaylistProvider);
185
186 emit mediaAboutToBeInserted(start: pos, end: pos);
187 d->resources.insert(i: pos, t: content);
188 emit mediaInserted(start: pos,end: pos);
189
190 return true;
191}
192
193bool QMediaNetworkPlaylistProvider::insertMedia(int pos, const QList<QMediaContent> &items)
194{
195 Q_D(QMediaNetworkPlaylistProvider);
196
197 if (items.isEmpty())
198 return true;
199
200 const int last = pos+items.count()-1;
201
202 emit mediaAboutToBeInserted(start: pos, end: last);
203 for (int i=0; i<items.count(); i++)
204 d->resources.insert(i: pos+i, t: items.at(i));
205 emit mediaInserted(start: pos, end: last);
206
207 return true;
208}
209
210bool QMediaNetworkPlaylistProvider::moveMedia(int from, int to)
211{
212 Q_D(QMediaNetworkPlaylistProvider);
213
214 Q_ASSERT(from >= 0 && from < mediaCount());
215 Q_ASSERT(to >= 0 && to < mediaCount());
216
217 if (from == to)
218 return false;
219
220 const QMediaContent media = d->resources.at(i: from);
221 return removeMedia(start: from, end: from) && insertMedia(pos: to, content: media);
222}
223
224bool QMediaNetworkPlaylistProvider::removeMedia(int fromPos, int toPos)
225{
226 Q_D(QMediaNetworkPlaylistProvider);
227
228 Q_ASSERT(fromPos >= 0);
229 Q_ASSERT(fromPos <= toPos);
230 Q_ASSERT(toPos < mediaCount());
231
232 emit mediaAboutToBeRemoved(start: fromPos, end: toPos);
233 d->resources.erase(first: d->resources.begin()+fromPos, last: d->resources.begin()+toPos+1);
234 emit mediaRemoved(start: fromPos, end: toPos);
235
236 return true;
237}
238
239bool QMediaNetworkPlaylistProvider::removeMedia(int pos)
240{
241 Q_D(QMediaNetworkPlaylistProvider);
242
243 emit mediaAboutToBeRemoved(start: pos, end: pos);
244 d->resources.removeAt(i: pos);
245 emit mediaRemoved(start: pos, end: pos);
246
247 return true;
248}
249
250bool QMediaNetworkPlaylistProvider::clear()
251{
252 Q_D(QMediaNetworkPlaylistProvider);
253 if (!d->resources.isEmpty()) {
254 int lastPos = mediaCount()-1;
255 emit mediaAboutToBeRemoved(start: 0, end: lastPos);
256 d->resources.clear();
257 emit mediaRemoved(start: 0, end: lastPos);
258 }
259
260 return true;
261}
262
263void QMediaNetworkPlaylistProvider::shuffle()
264{
265 Q_D(QMediaNetworkPlaylistProvider);
266 if (!d->resources.isEmpty()) {
267 QList<QMediaContent> resources;
268
269 while (!d->resources.isEmpty()) {
270 resources.append(t: d->resources.takeAt(i: QRandomGenerator::global()->bounded(highest: d->resources.size())));
271 }
272
273 d->resources = resources;
274 emit mediaChanged(start: 0, end: mediaCount()-1);
275 }
276
277}
278
279QT_END_NAMESPACE
280
281#include "moc_qmedianetworkplaylistprovider_p.cpp"
282

source code of qtmultimedia/src/multimedia/playback/qmedianetworkplaylistprovider.cpp