Changeset View
Changeset View
Standalone View
Standalone View
src/audiowrapper_libvlc.cpp
Show All 19 Lines | |||||
20 | #include "elisa-version.h" | 20 | #include "elisa-version.h" | ||
21 | 21 | | |||
22 | #include "vlcLogging.h" | 22 | #include "vlcLogging.h" | ||
23 | #include "powermanagementinterface.h" | 23 | #include "powermanagementinterface.h" | ||
24 | 24 | | |||
25 | #include <QTimer> | 25 | #include <QTimer> | ||
26 | #include <QAudio> | 26 | #include <QAudio> | ||
27 | #include <QDir> | 27 | #include <QDir> | ||
28 | #include <QHash> | ||||
28 | 29 | | |||
29 | #if defined Q_OS_WIN | 30 | #if defined Q_OS_WIN | ||
30 | 31 | | |||
31 | #include <basetsd.h> | 32 | #include <basetsd.h> | ||
32 | typedef SSIZE_T ssize_t; | 33 | typedef SSIZE_T ssize_t; | ||
33 | 34 | | |||
34 | #endif | 35 | #endif | ||
35 | 36 | | |||
36 | #include <vlc/vlc.h> | 37 | #include <vlc/vlc.h> | ||
37 | 38 | | |||
38 | #include "config-upnp-qt.h" | 39 | #include "config-upnp-qt.h" | ||
39 | 40 | | |||
40 | class AudioWrapperPrivate | 41 | class AudioWrapperPrivate | ||
41 | { | 42 | { | ||
42 | 43 | | |||
43 | public: | 44 | public: | ||
44 | 45 | | |||
45 | PowerManagementInterface mPowerInterface; | 46 | PowerManagementInterface mPowerInterface; | ||
46 | 47 | | |||
48 | QHash<QString, libvlc_renderer_item_t*> mExternalRenderers; | ||||
49 | | ||||
50 | QHash<QString, QString> mExternalRenderersType; | ||||
51 | | ||||
47 | AudioWrapper *mParent = nullptr; | 52 | AudioWrapper *mParent = nullptr; | ||
48 | 53 | | |||
49 | libvlc_instance_t *mInstance = nullptr; | 54 | libvlc_instance_t *mInstance = nullptr; | ||
50 | 55 | | |||
51 | libvlc_media_player_t *mPlayer = nullptr; | 56 | libvlc_media_player_t *mPlayer = nullptr; | ||
52 | 57 | | |||
53 | libvlc_event_manager_t *mPlayerEventManager = nullptr; | 58 | libvlc_event_manager_t *mPlayerEventManager = nullptr; | ||
54 | 59 | | |||
60 | std::vector<libvlc_renderer_discoverer_t*> mRendererDiscoverers; | ||||
61 | | ||||
62 | std::vector<libvlc_event_manager_t*> mRendererDiscovererEventManagers; | ||||
63 | | ||||
55 | libvlc_media_t *mMedia = nullptr; | 64 | libvlc_media_t *mMedia = nullptr; | ||
56 | 65 | | |||
57 | qint64 mMediaDuration = 0; | 66 | qint64 mMediaDuration = 0; | ||
58 | 67 | | |||
59 | QMediaPlayer::State mPreviousPlayerState = QMediaPlayer::StoppedState; | 68 | QMediaPlayer::State mPreviousPlayerState = QMediaPlayer::StoppedState; | ||
60 | 69 | | |||
61 | QMediaPlayer::MediaStatus mPreviousMediaStatus = QMediaPlayer::NoMedia; | 70 | QMediaPlayer::MediaStatus mPreviousMediaStatus = QMediaPlayer::NoMedia; | ||
62 | 71 | | |||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | 116 | { | |||
128 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEncounteredError, &vlc_callback, d.get()); | 137 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEncounteredError, &vlc_callback, d.get()); | ||
129 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPositionChanged, &vlc_callback, d.get()); | 138 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPositionChanged, &vlc_callback, d.get()); | ||
130 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerSeekableChanged, &vlc_callback, d.get()); | 139 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerSeekableChanged, &vlc_callback, d.get()); | ||
131 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerLengthChanged, &vlc_callback, d.get()); | 140 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerLengthChanged, &vlc_callback, d.get()); | ||
132 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerMuted, &vlc_callback, d.get()); | 141 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerMuted, &vlc_callback, d.get()); | ||
133 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerUnmuted, &vlc_callback, d.get()); | 142 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerUnmuted, &vlc_callback, d.get()); | ||
134 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioVolume, &vlc_callback, d.get()); | 143 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioVolume, &vlc_callback, d.get()); | ||
135 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioDevice, &vlc_callback, d.get()); | 144 | libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioDevice, &vlc_callback, d.get()); | ||
145 | | ||||
146 | libvlc_rd_description_t **rendererTypeList = nullptr; | ||||
147 | | ||||
148 | auto nbRendererTypes = libvlc_renderer_discoverer_list_get(d->mInstance, &rendererTypeList); | ||||
149 | | ||||
150 | for (unsigned int rendererTypeIndex = 0; rendererTypeIndex < nbRendererTypes; ++rendererTypeIndex) { | ||||
151 | qDebug() << "activate renderer discovery for type" << rendererTypeList[rendererTypeIndex]->psz_longname; | ||||
152 | auto newRenderer = libvlc_renderer_discoverer_new(d->mInstance, rendererTypeList[rendererTypeIndex]->psz_name); | ||||
153 | if (newRenderer) { | ||||
154 | d->mRendererDiscoverers.push_back(newRenderer); | ||||
155 | | ||||
156 | auto newRendererEventManager = libvlc_renderer_discoverer_event_manager(newRenderer); | ||||
157 | if (newRendererEventManager) { | ||||
158 | d->mRendererDiscovererEventManagers.push_back(newRendererEventManager); | ||||
159 | | ||||
160 | libvlc_event_attach(newRendererEventManager, libvlc_RendererDiscovererItemAdded, &vlc_callback, d.get()); | ||||
161 | libvlc_event_attach(newRendererEventManager, libvlc_RendererDiscovererItemDeleted, &vlc_callback, d.get()); | ||||
162 | | ||||
163 | libvlc_renderer_discoverer_start(newRenderer); | ||||
164 | } | ||||
165 | } | ||||
166 | } | ||||
167 | | ||||
168 | libvlc_renderer_discoverer_list_release(rendererTypeList, nbRendererTypes); | ||||
136 | } | 169 | } | ||
137 | 170 | | |||
138 | AudioWrapper::~AudioWrapper() | 171 | AudioWrapper::~AudioWrapper() | ||
139 | { | 172 | { | ||
140 | if (d->mInstance) { | 173 | if (d->mInstance) { | ||
141 | libvlc_release(d->mInstance); | 174 | libvlc_release(d->mInstance); | ||
142 | } | 175 | } | ||
143 | } | 176 | } | ||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Line(s) | |||||
197 | { | 230 | { | ||
198 | if (!d->mPlayer) { | 231 | if (!d->mPlayer) { | ||
199 | return {}; | 232 | return {}; | ||
200 | } | 233 | } | ||
201 | 234 | | |||
202 | return {}/*d->mPlayer.audioRole()*/; | 235 | return {}/*d->mPlayer.audioRole()*/; | ||
203 | } | 236 | } | ||
204 | 237 | | |||
238 | QList<QString> AudioWrapper::externalRenderers() const | ||||
239 | { | ||||
240 | return d->mExternalRenderers.keys(); | ||||
241 | } | ||||
242 | | ||||
205 | QMediaPlayer::State AudioWrapper::playbackState() const | 243 | QMediaPlayer::State AudioWrapper::playbackState() const | ||
206 | { | 244 | { | ||
207 | return d->mPreviousPlayerState; | 245 | return d->mPreviousPlayerState; | ||
208 | } | 246 | } | ||
209 | 247 | | |||
210 | QMediaPlayer::MediaStatus AudioWrapper::status() const | 248 | QMediaPlayer::MediaStatus AudioWrapper::status() const | ||
211 | { | 249 | { | ||
212 | return d->mPreviousMediaStatus; | 250 | return d->mPreviousMediaStatus; | ||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | 290 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource" | |||
254 | << libvlc_errmsg() | 292 | << libvlc_errmsg() | ||
255 | << QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData(); | 293 | << QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData(); | ||
256 | return; | 294 | return; | ||
257 | } | 295 | } | ||
258 | } | 296 | } | ||
259 | 297 | | |||
260 | libvlc_media_player_set_media(d->mPlayer, d->mMedia); | 298 | libvlc_media_player_set_media(d->mPlayer, d->mMedia); | ||
261 | 299 | | |||
300 | if (!d->mExternalRenderers.isEmpty()) { | ||||
301 | libvlc_media_player_set_renderer(d->mPlayer, d->mExternalRenderers.begin().value()); | ||||
302 | } | ||||
303 | | ||||
262 | if (d->signalPlaybackChange(QMediaPlayer::StoppedState)) { | 304 | if (d->signalPlaybackChange(QMediaPlayer::StoppedState)) { | ||
263 | Q_EMIT stopped(); | 305 | Q_EMIT stopped(); | ||
264 | } | 306 | } | ||
265 | 307 | | |||
266 | d->signalMediaStatusChange(QMediaPlayer::LoadingMedia); | 308 | d->signalMediaStatusChange(QMediaPlayer::LoadingMedia); | ||
267 | d->signalMediaStatusChange(QMediaPlayer::LoadedMedia); | 309 | d->signalMediaStatusChange(QMediaPlayer::LoadedMedia); | ||
268 | d->signalMediaStatusChange(QMediaPlayer::BufferedMedia); | 310 | d->signalMediaStatusChange(QMediaPlayer::BufferedMedia); | ||
269 | } | 311 | } | ||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Line(s) | 449 | { | |||
408 | QMetaObject::invokeMethod(this, [this, isMuted]() {Q_EMIT mutedChanged(isMuted);}, Qt::QueuedConnection); | 450 | QMetaObject::invokeMethod(this, [this, isMuted]() {Q_EMIT mutedChanged(isMuted);}, Qt::QueuedConnection); | ||
409 | } | 451 | } | ||
410 | 452 | | |||
411 | void AudioWrapper::playerSeekableSignalChanges(bool isSeekable) | 453 | void AudioWrapper::playerSeekableSignalChanges(bool isSeekable) | ||
412 | { | 454 | { | ||
413 | QMetaObject::invokeMethod(this, [this, isSeekable]() {Q_EMIT seekableChanged(isSeekable);}, Qt::QueuedConnection); | 455 | QMetaObject::invokeMethod(this, [this, isSeekable]() {Q_EMIT seekableChanged(isSeekable);}, Qt::QueuedConnection); | ||
414 | } | 456 | } | ||
415 | 457 | | |||
458 | void AudioWrapper::externalRenderersSignalChanges() | ||||
459 | { | ||||
460 | QMetaObject::invokeMethod(this, [this]() {Q_EMIT externalRenderersChanged();}, Qt::QueuedConnection); | ||||
461 | } | ||||
462 | | ||||
416 | void AudioWrapperPrivate::vlcEventCallback(const struct libvlc_event_t *p_event) | 463 | void AudioWrapperPrivate::vlcEventCallback(const struct libvlc_event_t *p_event) | ||
417 | { | 464 | { | ||
418 | const auto eventType = static_cast<libvlc_event_e>(p_event->type); | 465 | const auto eventType = static_cast<libvlc_event_e>(p_event->type); | ||
419 | 466 | | |||
420 | switch(eventType) | 467 | switch(eventType) | ||
421 | { | 468 | { | ||
422 | case libvlc_MediaPlayerOpening: | 469 | case libvlc_MediaPlayerOpening: | ||
423 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerOpening"; | 470 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerOpening"; | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 522 | case libvlc_MediaPlayerUnmuted: | |||
478 | break; | 525 | break; | ||
479 | case libvlc_MediaPlayerAudioVolume: | 526 | case libvlc_MediaPlayerAudioVolume: | ||
480 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioVolume"; | 527 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioVolume"; | ||
481 | signalVolumeChange(qRound(p_event->u.media_player_audio_volume.volume * 100)); | 528 | signalVolumeChange(qRound(p_event->u.media_player_audio_volume.volume * 100)); | ||
482 | break; | 529 | break; | ||
483 | case libvlc_MediaPlayerAudioDevice: | 530 | case libvlc_MediaPlayerAudioDevice: | ||
484 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioDevice"; | 531 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioDevice"; | ||
485 | break; | 532 | break; | ||
533 | case libvlc_RendererDiscovererItemAdded: | ||||
534 | qDebug() << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_RendererDiscovererItemAdded"; | ||||
535 | libvlc_renderer_item_hold(p_event->u.renderer_discoverer_item_added.item); | ||||
536 | | ||||
537 | mExternalRenderers[QString::fromLatin1(libvlc_renderer_item_name(p_event->u.renderer_discoverer_item_added.item))] = | ||||
538 | p_event->u.renderer_discoverer_item_added.item; | ||||
539 | mExternalRenderersType[QString::fromLatin1(libvlc_renderer_item_name(p_event->u.renderer_discoverer_item_added.item))] = | ||||
540 | QString::fromLatin1(libvlc_renderer_item_type(p_event->u.renderer_discoverer_item_added.item)); | ||||
541 | | ||||
542 | mParent->externalRenderersSignalChanges(); | ||||
543 | | ||||
544 | break; | ||||
545 | case libvlc_RendererDiscovererItemDeleted: | ||||
546 | qDebug() << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_RendererDiscovererItemDeleted"; | ||||
547 | mExternalRenderers.remove(QString::fromLatin1(libvlc_renderer_item_name(p_event->u.renderer_discoverer_item_deleted.item))); | ||||
548 | mExternalRenderersType.remove(QString::fromLatin1(libvlc_renderer_item_name(p_event->u.renderer_discoverer_item_deleted.item))); | ||||
549 | | ||||
550 | mParent->externalRenderersSignalChanges(); | ||||
551 | | ||||
552 | libvlc_renderer_item_hold(p_event->u.renderer_discoverer_item_deleted.item); | ||||
553 | | ||||
554 | break; | ||||
486 | default: | 555 | default: | ||
487 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "eventType" << eventType; | 556 | qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "eventType" << eventType; | ||
488 | break; | 557 | break; | ||
489 | } | 558 | } | ||
490 | } | 559 | } | ||
491 | 560 | | |||
492 | void AudioWrapperPrivate::mediaIsEnded() | 561 | void AudioWrapperPrivate::mediaIsEnded() | ||
493 | { | 562 | { | ||
▲ Show 20 Lines • Show All 103 Lines • Show Last 20 Lines |