1 | /* |
2 | Copyright (C) 2011-2018 Harald Sitter <sitter@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) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #ifndef PHONON_VLC_MEDIAPLAYER_H |
19 | #define PHONON_VLC_MEDIAPLAYER_H |
20 | |
21 | #include <QObject> |
22 | #include <QSharedPointer> |
23 | #include <QSize> |
24 | |
25 | #include <vlc/libvlc_version.h> |
26 | #include <vlc/vlc.h> |
27 | |
28 | class QImage; |
29 | class QString; |
30 | |
31 | namespace Phonon { |
32 | namespace VLC { |
33 | |
34 | class Media; |
35 | |
36 | template<class VLCArray> |
37 | class Descriptions |
38 | { |
39 | public: |
40 | typedef void (*ReleaseFunction) (VLCArray**, unsigned int) ; |
41 | |
42 | Descriptions(VLCArray **data, |
43 | unsigned int size, |
44 | ReleaseFunction release) |
45 | : m_release(release) |
46 | , m_data(data) |
47 | , m_size(size) |
48 | { |
49 | } |
50 | |
51 | ~Descriptions() |
52 | { |
53 | m_release(m_data, m_size); |
54 | } |
55 | |
56 | unsigned int size() const { return m_size; } |
57 | |
58 | private: |
59 | ReleaseFunction m_release; |
60 | |
61 | VLCArray **m_data; |
62 | unsigned int m_size; |
63 | }; |
64 | |
65 | typedef Descriptions<libvlc_title_description_t> TitleDescriptions; |
66 | typedef QSharedPointer<const TitleDescriptions> SharedTitleDescriptions; |
67 | |
68 | typedef Descriptions<libvlc_chapter_description_t> ChapterDescriptions; |
69 | typedef QSharedPointer<ChapterDescriptions> SharedChapterDescriptions; |
70 | |
71 | class MediaPlayer : public QObject |
72 | { |
73 | Q_OBJECT |
74 | public: |
75 | enum State { |
76 | NoState = 0, |
77 | OpeningState, |
78 | BufferingState, |
79 | PlayingState, |
80 | PausedState, |
81 | StoppedState, |
82 | EndedState, |
83 | ErrorState |
84 | }; |
85 | |
86 | explicit MediaPlayer(QObject *parent = nullptr); |
87 | ~MediaPlayer(); |
88 | |
89 | inline libvlc_media_player_t *libvlc_media_player() const { return m_player; } |
90 | inline operator libvlc_media_player_t *() const { return m_player; } |
91 | |
92 | void setMedia(Media *media); |
93 | |
94 | void setVideoCallbacks(); |
95 | void setVideoFormatCallbacks(); |
96 | |
97 | void setNsObject(void *drawable) { libvlc_media_player_set_nsobject(p_mi: m_player, drawable); } |
98 | void setXWindow(quint32 drawable) { libvlc_media_player_set_xwindow(p_mi: m_player, drawable); } |
99 | void setHwnd(void *drawable) { libvlc_media_player_set_hwnd(p_mi: m_player, drawable); } |
100 | |
101 | // Playback |
102 | bool play(); |
103 | void pause(); |
104 | void pausedPlay(); |
105 | void resume(); |
106 | void togglePause(); |
107 | Q_INVOKABLE void stop(); |
108 | |
109 | qint64 length() const; |
110 | qint64 time() const; |
111 | void setTime(qint64 newTime); |
112 | |
113 | bool isSeekable() const; |
114 | |
115 | // Video |
116 | QSize videoSize() const |
117 | { |
118 | unsigned int width; |
119 | unsigned int height; |
120 | libvlc_video_get_size(p_mi: m_player, num: 0, px: &width, py: &height); |
121 | return QSize(width, height); |
122 | } |
123 | |
124 | bool hasVideoOutput() const; |
125 | |
126 | /// Set new video aspect ratio. |
127 | /// \param aspect new video aspect-ratio or empty to reset to default |
128 | void setVideoAspectRatio(const QByteArray &aspect) |
129 | { libvlc_video_set_aspect_ratio(p_mi: m_player, psz_aspect: aspect.isEmpty() ? 0 : aspect.data()); } |
130 | |
131 | void setVideoAdjust(libvlc_video_adjust_option_t adjust, int value) |
132 | { libvlc_video_set_adjust_int(p_mi: m_player, option: adjust, value); } |
133 | |
134 | void setVideoAdjust(libvlc_video_adjust_option_t adjust, float value) |
135 | { libvlc_video_set_adjust_float(p_mi: m_player, option: adjust, value); } |
136 | |
137 | int subtitle() const |
138 | { return libvlc_video_get_spu(p_mi: m_player); } |
139 | |
140 | libvlc_track_description_t *videoSubtitleDescription() const |
141 | { return libvlc_video_get_spu_description(p_mi: m_player); } |
142 | |
143 | bool setSubtitle(int subtitle); |
144 | bool setSubtitle(const QString &file); |
145 | |
146 | int title() const |
147 | { return libvlc_media_player_get_title(p_mi: m_player); } |
148 | |
149 | int titleCount() const |
150 | { return libvlc_media_player_get_title_count(p_mi: m_player); } |
151 | |
152 | SharedTitleDescriptions titleDescription() const |
153 | { |
154 | libvlc_title_description_t **data; |
155 | unsigned int size = |
156 | libvlc_media_player_get_full_title_descriptions(p_mi: m_player, titles: &data); |
157 | return SharedTitleDescriptions( |
158 | new TitleDescriptions( |
159 | data, size, |
160 | &libvlc_title_descriptions_release) |
161 | ); |
162 | } |
163 | |
164 | void setTitle(int title); |
165 | |
166 | int videoChapterCount() const |
167 | { return libvlc_media_player_get_chapter_count(p_mi: m_player); } |
168 | |
169 | SharedChapterDescriptions videoChapterDescription(int title) const |
170 | { |
171 | libvlc_chapter_description_t **data; |
172 | unsigned int size = |
173 | libvlc_media_player_get_full_chapter_descriptions(p_mi: m_player, i_chapters_of_title: title, pp_chapters: &data); |
174 | return SharedChapterDescriptions( |
175 | new ChapterDescriptions( |
176 | data, size, |
177 | &libvlc_chapter_descriptions_release) |
178 | ); |
179 | } |
180 | |
181 | void setChapter(int chapter); |
182 | |
183 | /** Reentrant, through libvlc */ |
184 | QImage snapshot() const; |
185 | |
186 | // Audio |
187 | /// Get current audio volume. |
188 | /// \return the software volume in percents (0 = mute, 100 = nominal / 0dB) |
189 | int audioVolume() const { return m_volume; } |
190 | |
191 | /// Set new audio volume. |
192 | /// \param volume new volume |
193 | void setAudioVolume(int volume); |
194 | |
195 | /// \return mutness |
196 | bool mute() const; |
197 | |
198 | /** |
199 | * Mutes |
200 | * @param mute whether to mute or unmute |
201 | */ |
202 | void setMute(bool mute); |
203 | |
204 | /// Set the fade percentage, between 0 (muted) and 1.0 (no fade) |
205 | void setAudioFade(qreal fade); |
206 | |
207 | /// \param name name of the output to set |
208 | /// \returns \c true when setting was successful, \c false otherwise |
209 | bool setAudioOutput(const QByteArray &name) |
210 | { return libvlc_audio_output_set(p_mi: m_player, psz_name: name.data()) == 0; } |
211 | |
212 | /** |
213 | * Set audio output device by name. |
214 | * \param outputName the aout name (pulse, alsa, oss, etc.) |
215 | * \param deviceName the output name (aout dependent) |
216 | */ |
217 | void setAudioOutputDevice(const QByteArray &outputName, const QByteArray &deviceName) |
218 | { libvlc_audio_output_device_set(mp: m_player, module: outputName.data(), device_id: deviceName.data()); } |
219 | |
220 | int audioTrack() const |
221 | { return libvlc_audio_get_track(p_mi: m_player); } |
222 | |
223 | libvlc_track_description_t * audioTrackDescription() const |
224 | { return libvlc_audio_get_track_description(p_mi: m_player); } |
225 | |
226 | bool setAudioTrack(int track); |
227 | |
228 | void setCdTrack(int track); |
229 | |
230 | void setEqualizer(libvlc_equalizer_t *equalizer); |
231 | |
232 | Q_SIGNALS: |
233 | void lengthChanged(qint64 length); |
234 | void seekableChanged(bool seekable); |
235 | void stateChanged(MediaPlayer::State state); |
236 | void timeChanged(qint64 time); |
237 | void bufferChanged(int percent); |
238 | |
239 | /** Emitted when the vout availability has changed */ |
240 | void hasVideoChanged(bool hasVideo); |
241 | |
242 | void mutedChanged(bool mute); |
243 | void volumeChanged(float volume); |
244 | |
245 | private: |
246 | static void event_cb(const libvlc_event_t *event, void *opaque); |
247 | void setVolumeInternal(); |
248 | |
249 | Media *m_media; |
250 | |
251 | libvlc_media_player_t *m_player; |
252 | |
253 | bool m_doingPausedPlay; |
254 | int m_volume; |
255 | qreal m_fadeAmount; |
256 | }; |
257 | |
258 | QDebug operator<<(QDebug dbg, const MediaPlayer::State &s); |
259 | |
260 | } // namespace VLC |
261 | } // namespace Phonon |
262 | |
263 | #endif // PHONON_VLC_MEDIAPLAYER_H |
264 | |