File indexing completed on 2024-12-01 04:21:26

0001 /*
0002     Copyright (C) 2011-2018 Harald Sitter <sitter@kde.org>
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Lesser General Public
0006     License as published by the Free Software Foundation; either
0007     version 2.1 of the License, or (at your option) any later version.
0008 
0009     This library is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012     Lesser General Public License for more details.
0013 
0014     You should have received a copy of the GNU Lesser General Public
0015     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0016 */
0017 
0018 #ifndef PHONON_VLC_MEDIAPLAYER_H
0019 #define PHONON_VLC_MEDIAPLAYER_H
0020 
0021 #include <QObject>
0022 #include <QSharedPointer>
0023 #include <QSize>
0024 
0025 #include <vlc/libvlc_version.h>
0026 #include <vlc/vlc.h>
0027 
0028 class QImage;
0029 class QString;
0030 
0031 namespace Phonon {
0032 namespace VLC {
0033 
0034 class Media;
0035 
0036 template<class VLCArray>
0037 class Descriptions
0038 {
0039 public:
0040     typedef void (*ReleaseFunction) (VLCArray**, unsigned int) ;
0041 
0042     Descriptions(VLCArray **data,
0043               unsigned int size,
0044               ReleaseFunction release)
0045         : m_release(release)
0046         , m_data(data)
0047         , m_size(size)
0048     {
0049     }
0050 
0051     ~Descriptions()
0052     {
0053         m_release(m_data, m_size);
0054     }
0055 
0056     unsigned int size() const { return m_size; }
0057 
0058 private:
0059     ReleaseFunction m_release;
0060 
0061     VLCArray **m_data;
0062     unsigned int m_size;
0063 };
0064 
0065 typedef Descriptions<libvlc_title_description_t> TitleDescriptions;
0066 typedef QSharedPointer<const TitleDescriptions> SharedTitleDescriptions;
0067 
0068 typedef Descriptions<libvlc_chapter_description_t> ChapterDescriptions;
0069 typedef QSharedPointer<ChapterDescriptions> SharedChapterDescriptions;
0070 
0071 class MediaPlayer : public QObject
0072 {
0073     Q_OBJECT
0074 public:
0075     enum State {
0076         NoState = 0,
0077         OpeningState,
0078         BufferingState,
0079         PlayingState,
0080         PausedState,
0081         StoppedState,
0082         EndedState,
0083         ErrorState
0084     };
0085 
0086     explicit MediaPlayer(QObject *parent = nullptr);
0087     ~MediaPlayer();
0088 
0089     inline libvlc_media_player_t *libvlc_media_player() const { return m_player; }
0090     inline operator libvlc_media_player_t *() const { return m_player; }
0091 
0092     void setMedia(Media *media);
0093 
0094     void setVideoCallbacks();
0095     void setVideoFormatCallbacks();
0096 
0097     void setNsObject(void *drawable) { libvlc_media_player_set_nsobject(m_player, drawable); }
0098     void setXWindow(quint32 drawable) { libvlc_media_player_set_xwindow(m_player, drawable); }
0099     void setHwnd(void *drawable) { libvlc_media_player_set_hwnd(m_player, drawable); }
0100 
0101     // Playback
0102     bool play();
0103     void pause();
0104     void pausedPlay();
0105     void resume();
0106     void togglePause();
0107     Q_INVOKABLE void stop();
0108 
0109     qint64 length() const;
0110     qint64 time() const;
0111     void setTime(qint64 newTime);
0112 
0113     bool isSeekable() const;
0114 
0115     // Video
0116     QSize videoSize() const
0117     {
0118         unsigned int width;
0119         unsigned int height;
0120         libvlc_video_get_size(m_player, 0, &width, &height);
0121         return QSize(width, height);
0122     }
0123 
0124     bool hasVideoOutput() const;
0125 
0126     /// Set new video aspect ratio.
0127     /// \param aspect new video aspect-ratio or empty to reset to default
0128     void setVideoAspectRatio(const QByteArray &aspect)
0129     { libvlc_video_set_aspect_ratio(m_player, aspect.isEmpty() ? 0 : aspect.data()); }
0130 
0131     void setVideoAdjust(libvlc_video_adjust_option_t adjust, int value)
0132     { libvlc_video_set_adjust_int(m_player, adjust, value); }
0133 
0134     void setVideoAdjust(libvlc_video_adjust_option_t adjust, float value)
0135     { libvlc_video_set_adjust_float(m_player, adjust, value); }
0136 
0137     int subtitle() const
0138     { return libvlc_video_get_spu(m_player); }
0139 
0140     libvlc_track_description_t *videoSubtitleDescription() const
0141     { return libvlc_video_get_spu_description(m_player); }
0142 
0143     bool setSubtitle(int subtitle);
0144     bool setSubtitle(const QString &file);
0145 
0146     int title() const
0147     { return libvlc_media_player_get_title(m_player); }
0148 
0149     int titleCount() const
0150     { return libvlc_media_player_get_title_count(m_player); }
0151 
0152     SharedTitleDescriptions titleDescription() const
0153     {
0154         libvlc_title_description_t **data;
0155         unsigned int size =
0156                 libvlc_media_player_get_full_title_descriptions(m_player, &data);
0157         return SharedTitleDescriptions(
0158                     new TitleDescriptions(
0159                         data, size,
0160                         &libvlc_title_descriptions_release)
0161                     );
0162     }
0163 
0164     void setTitle(int title);
0165 
0166     int videoChapterCount() const
0167     { return libvlc_media_player_get_chapter_count(m_player); }
0168 
0169     SharedChapterDescriptions videoChapterDescription(int title) const
0170     {
0171         libvlc_chapter_description_t **data;
0172         unsigned int size =
0173             libvlc_media_player_get_full_chapter_descriptions(m_player, title, &data);
0174         return SharedChapterDescriptions(
0175                     new ChapterDescriptions(
0176                         data, size,
0177                         &libvlc_chapter_descriptions_release)
0178                     );
0179     }
0180 
0181     void setChapter(int chapter);
0182 
0183     /** Reentrant, through libvlc */
0184     QImage snapshot() const;
0185 
0186     // Audio
0187     /// Get current audio volume.
0188     /// \return the software volume in percents (0 = mute, 100 = nominal / 0dB)
0189     int audioVolume() const { return m_volume; }
0190 
0191     /// Set new audio volume.
0192     /// \param volume new volume
0193     void setAudioVolume(int volume);
0194 
0195     /// \return mutness
0196     bool mute() const;
0197 
0198     /**
0199      * Mutes
0200      * @param mute whether to mute or unmute
0201      */
0202     void setMute(bool mute);
0203 
0204     /// Set the fade percentage, between 0 (muted) and 1.0 (no fade)
0205     void setAudioFade(qreal fade);
0206 
0207     /// \param name name of the output to set
0208     /// \returns \c true when setting was successful, \c false otherwise
0209     bool setAudioOutput(const QByteArray &name)
0210     { return libvlc_audio_output_set(m_player, name.data()) == 0; }
0211 
0212     /**
0213      * Set audio output device by name.
0214      * \param outputName the aout name (pulse, alsa, oss, etc.)
0215      * \param deviceName the output name (aout dependent)
0216      */
0217     void setAudioOutputDevice(const QByteArray &outputName, const QByteArray &deviceName)
0218     { libvlc_audio_output_device_set(m_player, outputName.data(), deviceName.data()); }
0219 
0220     int audioTrack() const
0221     { return libvlc_audio_get_track(m_player); }
0222 
0223     libvlc_track_description_t * audioTrackDescription() const
0224     { return libvlc_audio_get_track_description(m_player); }
0225 
0226     bool setAudioTrack(int track);
0227 
0228     void setCdTrack(int track);
0229 
0230     void setEqualizer(libvlc_equalizer_t *equalizer);
0231 
0232 Q_SIGNALS:
0233     void lengthChanged(qint64 length);
0234     void seekableChanged(bool seekable);
0235     void stateChanged(MediaPlayer::State state);
0236     void timeChanged(qint64 time);
0237     void bufferChanged(int percent);
0238 
0239     /** Emitted when the vout availability has changed */
0240     void hasVideoChanged(bool hasVideo);
0241 
0242     void mutedChanged(bool mute);
0243     void volumeChanged(float volume);
0244 
0245 private:
0246     static void event_cb(const libvlc_event_t *event, void *opaque);
0247     void setVolumeInternal();
0248 
0249     Media *m_media;
0250 
0251     libvlc_media_player_t *m_player;
0252 
0253     bool m_doingPausedPlay;
0254     int m_volume;
0255     qreal m_fadeAmount;
0256 };
0257 
0258 QDebug operator<<(QDebug dbg, const MediaPlayer::State &s);
0259 
0260 } // namespace VLC
0261 } // namespace Phonon
0262 
0263 #endif // PHONON_VLC_MEDIAPLAYER_H