Phonon

mediaobject.h
1/* This file is part of the KDE project
2 Copyright (C) 2005 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), Nokia Corporation
10 (or its successors, if any) and the KDE Free Qt Foundation, which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library. If not, see <http://www.gnu.org/licenses/>.
20
21*/
22#ifndef Phonon_MEDIAOBJECT_H
23#define Phonon_MEDIAOBJECT_H
24
25#include "medianode.h"
26#include "mediasource.h"
27#include "phonon_export.h"
28#include "phonondefs.h"
29#include "phononnamespace.h"
30
31
32namespace Phonon
33{
34 class MediaObjectPrivate;
35
36 /** \class MediaObject mediaobject.h phonon/MediaObject
37 * \short Interface for media playback of a given URL.
38 *
39 * This class is the most important class in %Phonon. Use it to open a media
40 * file at an arbitrary location, a CD or DVD or to stream media data from
41 * the application to the backend.
42 *
43 * This class controls the state (play, pause, stop, seek)
44 * and you can use it to get a lot of information about the media data.
45 *
46 * Notice that most functions of this class are asynchronous.
47 * That means if you call play() the object only starts playing when the
48 * stateChanged() signal tells you that the object changed into PlayingState.
49 * The states you can expect are documented for those methods.
50 *
51 * A common usage example is the following:
52 * \code
53 * media = new MediaObject(this);
54 * connect(media, SIGNAL(finished()), SLOT(slotFinished());
55 * media->setCurrentSource("/home/username/music/filename.ogg");
56 * media->play();
57 * \endcode
58 *
59 * If you want to play more than one media file (one after another) you can
60 * either tell MediaObject about all those files
61 * \code
62 * media->setCurrentSource(":/sounds/startsound.ogg");
63 * media->enqueue("/home/username/music/song.mp3");
64 * media->enqueue(":/sounds/endsound.ogg");
65 * \endcode
66 * or provide the next file just in time:
67 * \code
68 * media->setCurrentSource(":/sounds/startsound.ogg");
69 * connect(media, SIGNAL(aboutToFinish()), SLOT(enqueueNextSource()));
70 * }
71 *
72 * void enqueueNextSource()
73 * {
74 * media->enqueue("/home/username/music/song.mp3");
75 * }
76 * \endcode
77 *
78 * This integration is opt-in only and can be enabled by setting the
79 * PlaybackTracking property to true:
80 * \code
81 * media->setProperty("PlaybackTracking", true);
82 * \endcode
83 *
84 * This kind of information is normally used to provide a universal history
85 * view to the user, such as what songs were played when, regardless of the
86 * media player. This is in addition to any emails read, IM conversations,
87 * websites viewed, etc.
88 *
89 * \ingroup Playback
90 * \ingroup Recording
91 * \author Matthias Kretz <kretz@kde.org>
92 */
93 class PHONON_EXPORT MediaObject : public QObject, public MediaNode
94 {
95 friend class FrontendInterfacePrivate;
96 Q_OBJECT
97 P_DECLARE_PRIVATE(MediaObject)
98 PHONON_OBJECT(MediaObject)
99 /**
100 * \brief Defines the time between media sources.
101 *
102 * A positive transition time defines a gap of silence between queued
103 * media sources.
104 *
105 * A transition time of 0 ms requests gapless playback (sample precise
106 * queueing of the next source).
107 *
108 * A negative transition time defines a crossfade between the queued
109 * media sources.
110 *
111 * Defaults to 0 (gapless playback).
112 *
113 * \warning This feature might not work reliably on every platform.
114 */
115 Q_PROPERTY(qint32 transitionTime READ transitionTime WRITE setTransitionTime)
116
117 /**
118 * \brief Get a signal before playback finishes.
119 *
120 * This property specifies the time in milliseconds the
121 * prefinishMarkReached signal is
122 * emitted before the playback finishes. A value of \c 0 disables the
123 * signal.
124 *
125 * Defaults to \c 0 (disabled).
126 *
127 * \warning For some media data the total time cannot be determined
128 * accurately, therefore the accuracy of the prefinishMarkReached signal
129 * can be bad sometimes. Still, it is better to use this method than to
130 * look at totalTime() and currentTime() to emulate the behaviour
131 * because the backend might have more information available than your
132 * application does through totalTime and currentTime.
133 *
134 * \see prefinishMarkReached
135 */
136 Q_PROPERTY(qint32 prefinishMark READ prefinishMark WRITE setPrefinishMark)
137
138 /**
139 * \brief The time interval in milliseconds between two ticks.
140 *
141 * The %tick interval is the time that elapses between the emission of two tick signals.
142 * If you set the interval to \c 0 the tick signal gets disabled.
143 *
144 * Defaults to \c 0 (disabled).
145 *
146 * \warning The back-end is free to choose a different tick interval close
147 * to what you asked for. This means that the following code \em may \em fail:
148 * \code
149 * int x = 200;
150 * media->setTickInterval(x);
151 * Q_ASSERT(x == producer->tickInterval());
152 * \endcode
153 * On the other hand the following is guaranteed:
154 * \code
155 * int x = 200;
156 * media->setTickInterval(x);
157 * Q_ASSERT(x >= producer->tickInterval() &&
158 * x <= 2 * producer->tickInterval());
159 * \endcode
160 *
161 * \see tick
162 */
163 Q_PROPERTY(qint32 tickInterval READ tickInterval WRITE setTickInterval)
164 public:
165 /**
166 * Destroys the MediaObject.
167 */
168 ~MediaObject() override;
169
170 /**
171 * Get the current state.
172 *
173 * @return The state of the object.
174 *
175 * @see State
176 * \see stateChanged
177 */
178 State state() const;
179
180 /**
181 * Check whether the media data includes a video stream.
182 *
183 * \warning This information cannot be known immediately. It is best
184 * to also listen to the hasVideoChanged signal.
185 *
186 * \code
187 * connect(media, SIGNAL(hasVideoChanged(bool)), hasVideoChanged(bool));
188 * media->setCurrentSource("somevideo.avi");
189 * media->hasVideo(); // returns false;
190 * }
191 *
192 * void hasVideoChanged(bool b)
193 * {
194 * // b == true
195 * media->hasVideo(); // returns true;
196 * }
197 * \endcode
198 *
199 * \return \c true if the media contains video data. \c false
200 * otherwise.
201 *
202 * \see hasVideoChanged
203 */
204 bool hasVideo() const;
205
206 /**
207 * Check whether the current media may be seeked.
208 *
209 * \warning This information cannot be known immediately. It is best
210 * to also listen to the seekableChanged signal.
211 *
212 * \code
213 * connect(media, SIGNAL(seekableChanged(bool)), seekableChanged(bool));
214 * media->setCurrentSource("somevideo.avi");
215 * media->isSeekable(); // returns false;
216 * }
217 *
218 * void seekableChanged(bool b)
219 * {
220 * // b == true
221 * media->isSeekable(); // returns true;
222 * }
223 * \endcode
224 *
225 * \return \c true when the current media may be seeked. \c false
226 * otherwise.
227 *
228 * \see seekableChanged()
229 */
230 bool isSeekable() const;
231
232 /**
233 * \brief The time interval in milliseconds between two ticks.
234 *
235 * The %tick interval is the time that elapses between the emission
236 * of two tick signals.
237 *
238 * \returns the tick interval in milliseconds
239 */
240 qint32 tickInterval() const;
241
242 /**
243 * Returns the strings associated with the given \p key.
244 *
245 * Backends should use the keys specified in the Ogg Vorbis
246 * documentation: http://xiph.org/vorbis/doc/v-comment.html
247 *
248 * Therefore the following should work with every backend:
249 *
250 * A typical usage looks like this:
251 * \code
252 * setMetaArtist (media->metaData("ARTIST" ));
253 * setMetaAlbum (media->metaData("ALBUM" ));
254 * setMetaTitle (media->metaData("TITLE" ));
255 * setMetaDate (media->metaData("DATE" ));
256 * setMetaGenre (media->metaData("GENRE" ));
257 * setMetaTrack (media->metaData("TRACKNUMBER"));
258 * setMetaComment(media->metaData("DESCRIPTION"));
259 * \endcode
260 *
261 * For Audio CDs you can query
262 * \code
263 * metaData("MUSICBRAINZ_DISCID");
264 * \endcode
265 * to get a DiscID hash that you can use with the MusicBrainz
266 * service:
267 * http://musicbrainz.org/doc/ClientHOWTO
268 */
269 QStringList metaData(const QString &key) const;
270
271 /**
272 * Returns the strings associated with the given \p key.
273 *
274 * Same as above except that the keys are defined in the
275 * Phonon::MetaData enum.
276 */
277 QStringList metaData(Phonon::MetaData key) const;
278
279 /**
280 * Returns all meta data.
281 */
282 QMultiMap<QString, QString> metaData() const;
283
284 /**
285 * Returns a human-readable description of the last error that occurred.
286 */
287 QString errorString() const;
288
289 /**
290 * Tells your program what to do about the error.
291 *
292 * \see Phonon::ErrorType
293 */
294 ErrorType errorType() const;
295
296 /**
297 * Returns the current media source.
298 *
299 * \see setCurrentSource
300 */
301 MediaSource currentSource() const;
302
303 /**
304 * Set the media source the MediaObject should use.
305 *
306 * \param source The MediaSource object to the media data. You can
307 * just as well use a QUrl or QString (for a local file) here.
308 * Setting an empty (invalid) source, will stop and remove the
309 * current source.
310 *
311 * \code
312 * QUrl url("http://www.example.com/music.ogg");
313 * media->setCurrentSource(url);
314 * \endcode
315 *
316 * \see currentSource
317 */
318 void setCurrentSource(const MediaSource &source);
319
320 /**
321 * Returns the queued media sources. This list does not include
322 * the current source (returned by currentSource).
323 */
324 QList<MediaSource> queue() const;
325
326 /**
327 * Set the MediaSources to play when the current media has finished.
328 *
329 * This function will overwrite the current queue.
330 *
331 * \see clearQueue
332 * \see enqueue
333 */
334 void setQueue(const QList<MediaSource> &sources);
335
336 /**
337 * Set the MediaSources to play when the current media has finished.
338 *
339 * This function overwrites the current queue.
340 *
341 * \see clearQueue
342 * \see enqueue
343 */
344 void setQueue(const QList<QUrl> &urls);
345
346 /**
347 * Appends one source to the queue. Use this function to provide
348 * the next source just in time after the aboutToFinish signal was
349 * emitted.
350 *
351 * \see aboutToFinish
352 * \see setQueue
353 * \see clearQueue
354 */
355 void enqueue(const MediaSource &source);
356
357 /**
358 * Appends multiple sources to the queue.
359 *
360 * \see setQueue
361 * \see clearQueue
362 */
363 void enqueue(const QList<MediaSource> &sources);
364
365 /**
366 * Appends multiple sources to the queue.
367 *
368 * \see setQueue
369 * \see clearQueue
370 */
371 void enqueue(const QList<QUrl> &urls);
372
373 /**
374 * Clears the queue of sources.
375 */
376 void clearQueue();
377
378 /**
379 * Get the current time (in milliseconds) of the file currently being played.
380 *
381 * \return The current time in milliseconds.
382 *
383 * \see tick
384 */
385 qint64 currentTime() const;
386
387 /**
388 * Get the total time (in milliseconds) of the file currently being played.
389 *
390 * \return The total time in milliseconds.
391 *
392 * \note The total time may change throughout playback as more accurate
393 * calculations become available, so it is recommended to connect
394 * and use the totalTimeChanged signal whenever possible unless
395 * best precision is not of importance.
396 *
397 * \warning The total time is undefined until the MediaObject entered
398 * the PlayingState. A valid total time is always indicated by
399 * emission of the totalTimeChanged signal.
400 * \see totalTimeChanged
401 */
402 qint64 totalTime() const;
403
404 /**
405 * Get the remaining time (in milliseconds) of the file currently being played.
406 *
407 * \return The remaining time in milliseconds.
408 */
409 qint64 remainingTime() const;
410
411 qint32 prefinishMark() const;
412 void setPrefinishMark(qint32 msecToEnd);
413
414 qint32 transitionTime() const;
415 void setTransitionTime(qint32 msec);
416
417 public Q_SLOTS:
418
419 /**
420 * Sets the tick interval in milliseconds.
421 *
422 * \param newTickInterval the new tick interval in milliseconds.
423 *
424 * \see tickInterval
425 */
426 void setTickInterval(qint32 newTickInterval);
427
428 /**
429 * Requests playback of the media data to start. Playback only
430 * starts when stateChanged() signals that it goes into PlayingState,
431 * though.
432 *
433 * \par Possible states right after this call:
434 * \li BufferingState
435 * \li PlayingState
436 * \li ErrorState
437 */
438 void play();
439
440 /**
441 * Requests playback to pause. If it was paused before nothing changes.
442 * If the media cannot be paused, some backends will internally call
443 * stop instead of pause.
444 *
445 * \par Possible states right after this call:
446 * \li PlayingState
447 * \li PausedState
448 * \li StoppedState
449 * \li ErrorState
450 */
451 void pause();
452
453 /**
454 * Requests playback to stop. If it was stopped before nothing changes.
455 *
456 * \par Possible states right after this call:
457 * \li the state it was in before (e.g. PlayingState)
458 * \li StoppedState
459 * \li ErrorState
460 */
461 void stop();
462
463 /**
464 * Requests a seek to the time indicated.
465 *
466 * You can only seek if state() == PlayingState, BufferingState or PausedState.
467 *
468 * The call is asynchronous, so currentTime can still be the old
469 * value right after this method was called. If all you need is a
470 * slider that shows the current position and allows the user to
471 * seek use the class SeekSlider.
472 *
473 * @param time The time in milliseconds where to continue playing.
474 *
475 * \par Possible states right after this call:
476 * \li BufferingState
477 * \li PlayingState
478 * \li ErrorState
479 *
480 * \see SeekSlider
481 */
482 void seek(qint64 time);
483
484 /**
485 * Stops and removes all playing and enqueued media sources.
486 *
487 * \see setCurrentSource
488 */
489 void clear();
490
491 Q_SIGNALS:
492 /**
493 * Emitted when the state of the MediaObject has changed.
494 *
495 * @param newstate The state the Player is in now.
496 * @param oldstate The state the Player was in before.
497 */
498 void stateChanged(Phonon::State newstate, Phonon::State oldstate);
499
500 /**
501 * This signal gets emitted every tickInterval milliseconds.
502 *
503 * @param time The position of the media file in milliseconds.
504 *
505 * @see setTickInterval, tickInterval
506 */
507 void tick(qint64 time);
508
509 /**
510 * This signal is emitted whenever the audio/video data that is
511 * being played is associated with new meta data. E.g. for radio
512 * streams this happens when the next song is played.
513 *
514 * You can get the new meta data with the metaData methods.
515 */
516 void metaDataChanged();
517
518 /**
519 * Emitted whenever the return value of isSeekable() changes.
520 *
521 * Normally you'll check isSeekable() first and then let this signal
522 * tell you whether seeking is possible now or not. That way you
523 * don't have to poll isSeekable().
524 *
525 * \param isSeekable \p true if the stream is seekable (i.e. calling
526 * seek() works)
527 * \p false if the stream is not seekable (i.e.
528 * all calls to seek() will be ignored)
529 */
530 void seekableChanged(bool isSeekable);
531
532 /**
533 * Emitted whenever the return value of hasVideo() changes.
534 *
535 * Normally you'll check hasVideo() first and then let this signal
536 * tell you whether video is available now or not. That way you
537 * don't have to poll hasVideo().
538 *
539 * \param hasVideo \p true The stream contains video and adding a
540 * VideoWidget will show a video.
541 * \p false There is no video data in the stream and
542 * adding a VideoWidget will show an empty (black)
543 * VideoWidget.
544 */
545#ifndef QT_NO_PHONON_VIDEO
546 void hasVideoChanged(bool hasVideo);
547#endif //QT_NO_PHONON_VIDEO
548
549 /**
550 * Tells about the status of the buffer.
551 *
552 * You can use this signal to show a progress bar to the user when
553 * in BufferingState:
554 *
555 * \code
556 * progressBar->setRange(0, 100); // this is the default
557 * connect(media, SIGNAL(bufferStatus(int)), progressBar, SLOT(setValue(int)));
558 * \endcode
559 *
560 * \param percentFilled A number between 0 and 100 telling you how
561 * much the buffer is filled.
562 */ // other names: bufferingProgress
563 void bufferStatus(int percentFilled);
564
565 /**
566 * Emitted when the object has finished playback.
567 * It is not emitted if you call stop(), pause() or
568 * load(), but only on end-of-queue or a critical error.
569 *
570 * \warning This signal is not emitted when the current source has
571 * finished and there's another source in the queue. It is only
572 * emitted when the queue is empty.
573 *
574 * \see currentSourceChanged
575 * \see aboutToFinish
576 * \see prefinishMarkReached
577 */
578 void finished();
579
580 /**
581 * Emitted when the MediaObject makes a transition to the next
582 * MediaSource in the queue().
583 *
584 * In other words, it is emitted when an individual MediaSource is
585 * finished.
586 *
587 * \param newSource The source that starts to play at the time the
588 * signal is emitted.
589 */
591
592 /**
593 * Emitted before the playback of the whole queue stops. When this
594 * signal is emitted you still have time to provide the next
595 * MediaSource (using enqueue()) so that playback continues.
596 *
597 * This signal can be used to provide the next MediaSource just in
598 * time for the transition still to work.
599 *
600 * \see enqueue
601 */
603
604 /**
605 * Emitted when there are only \p msecToEnd milliseconds left
606 * for playback.
607 *
608 * \param msecToEnd The remaining time until the playback queue finishes.
609 *
610 * \warning This signal is not emitted when there is another source in the queue.
611 * It is only emitted when the queue is empty.
612 *
613 * \see setPrefinishMark
614 * \see prefinishMark
615 * \see aboutToFinish
616 * \see finished
617 */
618 void prefinishMarkReached(qint32 msecToEnd);
619
620 /**
621 * This signal is emitted as soon as the total time of the media file is
622 * known or has changed. For most non-local media data the total
623 * time of the media can only be known after some time. Initially the
624 * totalTime function can not return useful information. You have
625 * to wait for this signal to know the real total time.
626 *
627 * This signal may appear at any given point after a MediaSource was set.
628 * Namely in the LoadingState, BufferingState, PlayingState or PausedState.
629 *
630 * \note When changing the currentSource there is no signal emission until
631 * a reasonable value for the new source has been calculated.
632 *
633 * \param newTotalTime The length of the media file in milliseconds.
634 *
635 * \see totalTime
636 */
637 void totalTimeChanged(qint64 newTotalTime);
638
639 protected:
640 //MediaObject(Phonon::MediaObjectPrivate &dd, QObject *parent);
641
642 private:
643 Q_PRIVATE_SLOT(k_func(), void _k_resumePlay())
644 Q_PRIVATE_SLOT(k_func(), void _k_resumePause())
645 Q_PRIVATE_SLOT(k_func(), void _k_metaDataChanged(const QMultiMap<QString, QString> &))
646#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
647 Q_PRIVATE_SLOT(k_func(), void _k_stateChanged(Phonon::State, Phonon::State))
648#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
649 Q_PRIVATE_SLOT(k_func(), void _k_aboutToFinish())
650 Q_PRIVATE_SLOT(k_func(), void _k_currentSourceChanged(const MediaSource &))
651 Q_PRIVATE_SLOT(k_func(), void _k_stateChanged(Phonon::State, Phonon::State))
652 };
653
654 /**
655 * Convenience function to create a MediaObject and AudioOutput connected by
656 * a path.
657 */
658 PHONON_EXPORT MediaObject *createPlayer(Phonon::Category category, const MediaSource &source = MediaSource());
659} //namespace Phonon
660
661
662// vim: sw=4 ts=4 tw=80
663#endif // Phonon_MEDIAOBJECT_H
Interface for media playback of a given URL.
Definition mediaobject.h:94
void currentSourceChanged(const Phonon::MediaSource &newSource)
Emitted when the MediaObject makes a transition to the next MediaSource in the queue().
void prefinishMarkReached(qint32 msecToEnd)
Emitted when there are only msecToEnd milliseconds left for playback.
void aboutToFinish()
Emitted before the playback of the whole queue stops.
void bufferStatus(int percentFilled)
Tells about the status of the buffer.
void totalTimeChanged(qint64 newTotalTime)
This signal is emitted as soon as the total time of the media file is known or has changed.
void finished()
Emitted when the object has finished playback.
void hasVideoChanged(bool hasVideo)
Emitted whenever the return value of hasVideo() changes.
Note that all constructors of this class are implicit, so that you can simply write.
Definition mediasource.h:63
void stop(Ekos::AlignState mode)
Q_SCRIPTABLE Q_NOREPLY void pause()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:24 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.