1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
/*
Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KPLAYOBJECT_H
#define KPLAYOBJECT_H
#include "kmedia2.h"
#include "soundserver.h"
#include <kurl.h>
#include <qobject.h>
class KDE_EXPORT KPlayObject : public QObject
{
Q_OBJECT
public:
KPlayObject();
KPlayObject(Arts::PlayObject playobject, bool isStream);
~KPlayObject();
/**
* Sets the internal Arts::PlayObject
* to @a playObject
*/
void setObject(Arts::PlayObject playObject);
/**
* Returns the internal Arts::PlayObject
*/
Arts::PlayObject object();
/**
* return true if both this != 0, and object.isNull()
*
* in essence, ((KPlayObject*)0)->isNull() will not
* crash
**/
bool isNull();
/**
* returns true if the internally playobject
* is used to play a stream
*/
bool stream();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
void play();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
void seek(Arts::poTime newTime);
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
void pause();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
void halt();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
QString description();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poTime currentTime();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poTime overallTime();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poCapabilities capabilities();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
QString mediaName();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poState state();
private:
Arts::PlayObject m_playObject;
bool m_isStream;
};
namespace KDE {
class PlayObjectFactory;
/**
* This class acts as a general interface to the KDE multimedia framework.
* You basically point the Playobject to an URL and say "play", and it will
* automatically decode and play and / or display the file or stream.
* For non-local media, it will make extensive use of KIOInputStream to
* directly play the content from the remote location without having to
* download it to a temporary local file first.
*
* A KDE::PlayObject is never created directly with new, but only through
* a KDE::PlayObjectFactory.
*
* Basically, it is used like this:
* \code
* KArtsDispatcher dispatcher;
* KArtsServer server;
* KDE::PlayObjectFactory factory( server.server() );
* KDE::PlayObject* playobj = factory.createPlayObject( someURL, true );
* playobj->play();
* \endcode
*
* Internally, the KDE::PlayObject acts as a wrapper for an Arts::PlayObject.
*
* Special care needs to be taken for non-local media. In general, you
* cannot safely figure out the mimetype of the remote media content, by
* looking at the URL alone. You need to download some data to analyze
* the content. Since KDE::PlayObject is only a wrapper for an
* Arts::PlayObject, and an Arts::PlayObject needs to know the mimetype
* of the data it plays in order to pick the correct decoder, one cannot
* directly create an Arts::PlayObject and attach it to a stream. Therefore,
* the following approach is used.
*
* Whenever a the factory creates a KDE::PlayObject for a non-local content,
* it first generates a so called "Proxy" Playobject. This is a
* KDE::PlayObject that does not contain a real Arts::PlayObject yet.
* As soon as you invoke the play() method, a connection to the media
* source is made, and as soon as the mimetype is known, the appropriate
* Arts::PlayObject is created.
*
* This has some side effects that developers need to be aware of:
* Until the real Arts::PlayObject got created,
* - the capabilities() method returns "zero" capabilities,
* - description() and mediaName() will return a null QString,
* - currentTime() and overallTime() will return "zero",
* - despite the fact that isNull() returns "false", object().isNull()
* will return "true". If you need to directly access methods of the
* internal Arts::PlayObject, be sure to use object().isNull() to guard
* your access.
*
* A KDE::PlayObject will emit the signal playObjectCreated()
* as soon as the real internal Arts::PlayObject got created. This is also
* true for local media files. So you can generally connect to this signal
* and act on it if your application needs to know about the real capabilities
* of the Arts::PlayObject.
*
* However, KDE::PlayObject will try to act reasonable on calls to play(),
* halt(), pause() and state(). If you call play() and then pause()
* before the connection to the media source was established, it will
* not start playing once the connection got established. Calling halt()
* will cancel the connection process. KDE::PlayObject will maintain
* an internal state variable, and calling state() will return this
* internal state until the real Arts::PlayObject got created, afterwards
* the state of the Arts::PlayObject will be returned.
*/
class KDE_EXPORT PlayObject : public QObject
{
Q_OBJECT
public:
~PlayObject();
/**
* Returns the internal Arts::PlayObject
*/
Arts::PlayObject object();
/**
* return true if this != 0.
*
* in essence, ((KDE::PlayObject*)0)->isNull() will not
* crash
**/
bool isNull();
/**
* returns "true" if the content to play is delivered as a stream.
*/
bool stream();
/**
* causes the PlayObject to start the play back.
*/
void play();
/**
* causes the PlayObject to skip to the time @p newTime.
* You don't need to stop or restart the play back after calling seek.
*/
void seek(Arts::poTime newTime);
/**
* causes the PlayObject to pause play back immediately. It will not
* restart until you call play(). This also works on streams, the
* connection to the media source will be maintained while the
* PlayObject is paused.
*/
void pause();
/**
* immediately stops the play back and resets the media to the
* start of the content. If playing from a stream, halt() causes
* the connection to be canceled.
*/
void halt();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
QString description();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poTime currentTime();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
Arts::poTime overallTime();
/**
* returns the capabilities of the PlayObject. The return value is
* a binary OR of Arts::capSeek and Arts::capPause, or 0.
*/
Arts::poCapabilities capabilities();
/**
* Reimplemented (Arts::PlayObject Wrapper)
*/
QString mediaName();
/**
* returns the internal state of the PlayObject. The state can be
* either Arts::posIdle, Arts::posPaused or Arts::posPlaying. A
* PlayObject in state Arts::posIdle is stopped. Once you call
* play(), the state changes to Arts::posPlaying. pause() causes
* the PlayObject to change to Arts::posPaused.
*/
Arts::poState state();
signals:
/**
* this signal is emitted as soon as the internal Arts::PlayObject
* is created and ready to play. It is granted that the Arts::PlayObject
* has not started playing, but KDE::PlayObject will call
* object().play() immediately after emitting this signal, so you
* need not do it yourself.
*/
void playObjectCreated();
private slots:
void attachPlayObject( Arts::PlayObject );
private:
Arts::PlayObject m_playObject;
bool m_isStream;
struct PrivateData;
PrivateData* d;
/* private constructors, to prevent instantiation and copying */
PlayObject();
PlayObject( const PlayObject& ) : QObject() {};
PlayObject(Arts::PlayObject playobject, bool isStream);
PlayObject( Arts::SoundServerV2 server, const KURL& url, bool isStream, bool createBUS );
friend class KDE::PlayObjectFactory;
};
}
#endif
|