File indexing completed on 2024-04-14 04:43:55
0001 /* 0002 SPDX-FileCopyrightText: 2017 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-3.0-or-later 0005 */ 0006 0007 #include "audiowrapper.h" 0008 0009 #include "elisa-version.h" 0010 0011 #include "vlcLogging.h" 0012 #include "powermanagementinterface.h" 0013 0014 #include <QAudio> 0015 #include <QDir> 0016 #include <QGuiApplication> 0017 0018 #if defined Q_OS_WIN 0019 0020 #include <basetsd.h> 0021 typedef SSIZE_T ssize_t; 0022 0023 #endif 0024 0025 #include <cmath> 0026 0027 #include <vlc/vlc.h> 0028 #include <vlc/libvlc_version.h> 0029 0030 #include "config-upnp-qt.h" 0031 0032 class AudioWrapperPrivate 0033 { 0034 0035 public: 0036 0037 PowerManagementInterface mPowerInterface; 0038 0039 AudioWrapper *mParent = nullptr; 0040 0041 libvlc_instance_t *mInstance = nullptr; 0042 0043 libvlc_media_player_t *mPlayer = nullptr; 0044 0045 libvlc_event_manager_t *mPlayerEventManager = nullptr; 0046 0047 libvlc_media_t *mMedia = nullptr; 0048 0049 qint64 mMediaDuration = 0; 0050 0051 QMediaPlayer::PlaybackState mPreviousPlayerState = QMediaPlayer::StoppedState; 0052 0053 QMediaPlayer::MediaStatus mPreviousMediaStatus = QMediaPlayer::NoMedia; 0054 0055 qreal mPreviousVolume = 100.0; 0056 0057 qint64 mSavedPosition = 0.0; 0058 0059 qint64 mUndoSavedPosition = 0.0; 0060 0061 qint64 mPreviousPosition = 0; 0062 0063 QMediaPlayer::Error mError = QMediaPlayer::NoError; 0064 0065 bool mIsMuted = false; 0066 0067 bool mIsSeekable = false; 0068 0069 bool mHasSavedPosition = false; 0070 0071 void vlcEventCallback(const struct libvlc_event_t *p_event); 0072 0073 void mediaIsEnded(); 0074 0075 bool signalPlaybackChange(QMediaPlayer::PlaybackState newPlayerState); 0076 0077 void signalMediaStatusChange(QMediaPlayer::MediaStatus newMediaStatus); 0078 0079 void signalVolumeChange(int newVolume); 0080 0081 void signalMutedChange(bool isMuted); 0082 0083 void signalDurationChange(libvlc_time_t newDuration); 0084 0085 void signalPositionChange(float newPosition); 0086 0087 void signalSeekableChange(bool isSeekable); 0088 0089 void signalErrorChange(QMediaPlayer::Error errorCode); 0090 0091 }; 0092 0093 static void vlc_callback(const struct libvlc_event_t *p_event, void *p_data) 0094 { 0095 reinterpret_cast<AudioWrapperPrivate*>(p_data)->vlcEventCallback(p_event); 0096 } 0097 0098 AudioWrapper::AudioWrapper(QObject *parent) : QObject(parent), d(std::make_unique<AudioWrapperPrivate>()) 0099 { 0100 d->mParent = this; 0101 d->mInstance = libvlc_new(0, nullptr); 0102 libvlc_set_user_agent(d->mInstance, QGuiApplication::applicationDisplayName().toUtf8().constData(), "Elisa Music Player"); 0103 libvlc_set_app_id(d->mInstance, "org.kde.elisa", ELISA_VERSION_STRING, "elisa"); 0104 0105 d->mPlayer = libvlc_media_player_new(d->mInstance); 0106 0107 if (!d->mPlayer) { 0108 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::AudioWrapper" << "failed creating player" << libvlc_errmsg(); 0109 return; 0110 } 0111 0112 d->mPlayerEventManager = libvlc_media_player_event_manager(d->mPlayer); 0113 0114 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerOpening, &vlc_callback, d.get()); 0115 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerBuffering, &vlc_callback, d.get()); 0116 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPlaying, &vlc_callback, d.get()); 0117 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPaused, &vlc_callback, d.get()); 0118 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerStopped, &vlc_callback, d.get()); 0119 #if LIBVLC_VERSION_MAJOR >= 4 0120 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerStopping, &vlc_callback, d.get()); 0121 #else 0122 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEndReached, &vlc_callback, d.get()); 0123 #endif 0124 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEncounteredError, &vlc_callback, d.get()); 0125 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPositionChanged, &vlc_callback, d.get()); 0126 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerSeekableChanged, &vlc_callback, d.get()); 0127 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerLengthChanged, &vlc_callback, d.get()); 0128 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerMuted, &vlc_callback, d.get()); 0129 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerUnmuted, &vlc_callback, d.get()); 0130 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioVolume, &vlc_callback, d.get()); 0131 libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioDevice, &vlc_callback, d.get()); 0132 } 0133 0134 AudioWrapper::~AudioWrapper() 0135 { 0136 if (d->mInstance) { 0137 d->mPowerInterface.setPreventSleep(false); 0138 if (d->mPlayer && d->mPreviousPlayerState != QMediaPlayer::StoppedState) { 0139 #if LIBVLC_VERSION_MAJOR >= 4 0140 libvlc_media_player_stop_async(d->mPlayer); 0141 #else 0142 libvlc_media_player_stop(d->mPlayer); 0143 #endif 0144 } 0145 libvlc_release(d->mInstance); 0146 } 0147 } 0148 0149 bool AudioWrapper::muted() const 0150 { 0151 return d->mIsMuted; 0152 } 0153 0154 qreal AudioWrapper::volume() const 0155 { 0156 if (!d->mPlayer) { 0157 return 100.0; 0158 } 0159 0160 return d->mPreviousVolume; 0161 } 0162 0163 QUrl AudioWrapper::source() const 0164 { 0165 if (!d->mPlayer) { 0166 return {}; 0167 } 0168 if (d->mMedia) { 0169 auto filePath = QString::fromUtf8(libvlc_media_get_mrl(d->mMedia)); 0170 return QUrl::fromUserInput(filePath); 0171 } 0172 return {}; 0173 } 0174 0175 QMediaPlayer::Error AudioWrapper::error() const 0176 { 0177 return d->mError; 0178 } 0179 0180 qint64 AudioWrapper::duration() const 0181 { 0182 return d->mMediaDuration; 0183 } 0184 0185 qint64 AudioWrapper::position() const 0186 { 0187 if (!d->mPlayer) { 0188 return 0; 0189 } 0190 0191 if (d->mMediaDuration == -1) { 0192 return 0; 0193 } 0194 0195 return qRound64(libvlc_media_player_get_position(d->mPlayer) * d->mMediaDuration); 0196 } 0197 0198 bool AudioWrapper::seekable() const 0199 { 0200 return d->mIsSeekable; 0201 } 0202 0203 QMediaPlayer::PlaybackState AudioWrapper::playbackState() const 0204 { 0205 return d->mPreviousPlayerState; 0206 } 0207 0208 QMediaPlayer::MediaStatus AudioWrapper::status() const 0209 { 0210 return d->mPreviousMediaStatus; 0211 } 0212 0213 void AudioWrapper::setMuted(bool muted) 0214 { 0215 if (!d->mPlayer) { 0216 return; 0217 } 0218 0219 libvlc_audio_set_mute(d->mPlayer, muted); 0220 } 0221 0222 void AudioWrapper::setVolume(qreal volume) 0223 { 0224 if (!d->mPlayer) { 0225 return; 0226 } 0227 0228 const int intVolume = std::clamp(qRound(volume), 0, 100); 0229 libvlc_audio_set_volume(d->mPlayer, intVolume); 0230 } 0231 0232 void AudioWrapper::setSource(const QUrl &source) 0233 { 0234 if (source.isLocalFile()) { 0235 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource reading local resource"; 0236 #if LIBVLC_VERSION_MAJOR >= 4 0237 d->mMedia = libvlc_media_new_path(QDir::toNativeSeparators(source.toLocalFile()).toUtf8().constData()); 0238 #else 0239 d->mMedia = libvlc_media_new_path(d->mInstance, QDir::toNativeSeparators(source.toLocalFile()).toUtf8().constData()); 0240 #endif 0241 } else { 0242 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource reading remote resource"; 0243 #if LIBVLC_VERSION_MAJOR >= 4 0244 d->mMedia = libvlc_media_new_location(source.url().toUtf8().constData()); 0245 #else 0246 d->mMedia = libvlc_media_new_location(d->mInstance, source.url().toUtf8().constData()); 0247 #endif 0248 } 0249 0250 if (!d->mMedia) { 0251 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource" 0252 << "failed creating media" 0253 << libvlc_errmsg() 0254 << QDir::toNativeSeparators(source.toLocalFile()).toUtf8().constData(); 0255 0256 #if LIBVLC_VERSION_MAJOR >= 4 0257 d->mMedia = libvlc_media_new_path(QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData()); 0258 #else 0259 d->mMedia = libvlc_media_new_path(d->mInstance, QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData()); 0260 #endif 0261 if (!d->mMedia) { 0262 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource" 0263 << "failed creating media" 0264 << libvlc_errmsg() 0265 << QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData(); 0266 return; 0267 } 0268 } 0269 0270 // By default, libvlc caches only next 1000 (ms, 0..60000) of the playback, 0271 // which is unreasonable given our usecase of sequential playback. 0272 libvlc_media_add_option(d->mMedia, ":file-caching=10000"); 0273 libvlc_media_add_option(d->mMedia, ":live-caching=10000"); 0274 libvlc_media_add_option(d->mMedia, ":disc-caching=10000"); 0275 libvlc_media_add_option(d->mMedia, ":network-caching=10000"); 0276 0277 libvlc_media_player_set_media(d->mPlayer, d->mMedia); 0278 0279 if (d->signalPlaybackChange(QMediaPlayer::StoppedState)) { 0280 Q_EMIT stopped(); 0281 } 0282 0283 d->signalMediaStatusChange(QMediaPlayer::LoadingMedia); 0284 d->signalMediaStatusChange(QMediaPlayer::LoadedMedia); 0285 d->signalMediaStatusChange(QMediaPlayer::BufferedMedia); 0286 0287 d->mHasSavedPosition = false; 0288 } 0289 0290 void AudioWrapper::setPosition(qint64 position) 0291 { 0292 if (!d->mPlayer) { 0293 return; 0294 } 0295 0296 if (d->mMediaDuration == -1 || d->mMediaDuration == 0) { 0297 savePosition(position); 0298 return; 0299 } 0300 0301 #if LIBVLC_VERSION_MAJOR >= 4 0302 libvlc_media_player_set_position(d->mPlayer, static_cast<float>(position) / d->mMediaDuration, true); 0303 #else 0304 libvlc_media_player_set_position(d->mPlayer, static_cast<float>(position) / d->mMediaDuration); 0305 #endif 0306 Q_EMIT positionChanged(position); 0307 } 0308 0309 void AudioWrapper::savePosition(qint64 position) 0310 { 0311 if (!d->mHasSavedPosition) { 0312 d->mHasSavedPosition = true; 0313 d->mSavedPosition = position; 0314 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::savePosition" << "restore old position" << d->mSavedPosition; 0315 } 0316 } 0317 0318 void AudioWrapper::saveUndoPosition(qint64 position) 0319 { 0320 d->mUndoSavedPosition = position; 0321 } 0322 0323 void AudioWrapper::restoreUndoPosition() 0324 { 0325 d->mHasSavedPosition = true; 0326 d->mSavedPosition = d->mUndoSavedPosition; 0327 } 0328 0329 void AudioWrapper::play() 0330 { 0331 if (!d->mPlayer) { 0332 return; 0333 } 0334 0335 libvlc_media_player_play(d->mPlayer); 0336 } 0337 0338 void AudioWrapper::pause() 0339 { 0340 if (!d->mPlayer) { 0341 return; 0342 } 0343 0344 libvlc_media_player_pause(d->mPlayer); 0345 } 0346 0347 void AudioWrapper::stop() 0348 { 0349 if (!d->mPlayer) { 0350 return; 0351 } 0352 0353 #if LIBVLC_VERSION_MAJOR >= 4 0354 libvlc_media_player_stop_async(d->mPlayer); 0355 #else 0356 libvlc_media_player_stop(d->mPlayer); 0357 #endif 0358 } 0359 0360 void AudioWrapper::seek(qint64 position) 0361 { 0362 setPosition(position); 0363 } 0364 0365 void AudioWrapper::mediaStatusChanged() 0366 { 0367 } 0368 0369 void AudioWrapper::playerStateChanged() 0370 { 0371 } 0372 0373 void AudioWrapper::playerMutedChanged() 0374 { 0375 } 0376 0377 void AudioWrapper::playerVolumeChanged() 0378 { 0379 } 0380 0381 void AudioWrapper::playerStateSignalChanges(QMediaPlayer::PlaybackState newState) 0382 { 0383 QMetaObject::invokeMethod(this, [this, newState]() { 0384 Q_EMIT playbackStateChanged(newState); 0385 switch (newState) 0386 { 0387 case QMediaPlayer::StoppedState: 0388 Q_EMIT stopped(); 0389 d->mPowerInterface.setPreventSleep(false); 0390 break; 0391 case QMediaPlayer::PlayingState: 0392 Q_EMIT playing(); 0393 d->mPowerInterface.setPreventSleep(true); 0394 break; 0395 case QMediaPlayer::PausedState: 0396 Q_EMIT paused(); 0397 d->mPowerInterface.setPreventSleep(false); 0398 break; 0399 } 0400 }, Qt::QueuedConnection); 0401 } 0402 0403 void AudioWrapper::mediaStatusSignalChanges(QMediaPlayer::MediaStatus newStatus) 0404 { 0405 QMetaObject::invokeMethod(this, [this, newStatus]() {Q_EMIT statusChanged(newStatus);}, Qt::QueuedConnection); 0406 } 0407 0408 void AudioWrapper::playerErrorSignalChanges(QMediaPlayer::Error error) 0409 { 0410 QMetaObject::invokeMethod(this, [this, error]() {Q_EMIT errorChanged(error);}, Qt::QueuedConnection); 0411 } 0412 0413 void AudioWrapper::playerDurationSignalChanges(qint64 newDuration) 0414 { 0415 QMetaObject::invokeMethod(this, [this, newDuration]() {Q_EMIT durationChanged(newDuration);}, Qt::QueuedConnection); 0416 } 0417 0418 void AudioWrapper::playerPositionSignalChanges(qint64 newPosition) 0419 { 0420 QMetaObject::invokeMethod(this, [this, newPosition]() {Q_EMIT positionChanged(newPosition);}, Qt::QueuedConnection); 0421 } 0422 0423 void AudioWrapper::playerVolumeSignalChanges() 0424 { 0425 QMetaObject::invokeMethod(this, [this]() {Q_EMIT volumeChanged();}, Qt::QueuedConnection); 0426 } 0427 0428 void AudioWrapper::playerMutedSignalChanges(bool isMuted) 0429 { 0430 QMetaObject::invokeMethod(this, [this, isMuted]() {Q_EMIT mutedChanged(isMuted);}, Qt::QueuedConnection); 0431 } 0432 0433 void AudioWrapper::playerSeekableSignalChanges(bool isSeekable) 0434 { 0435 QMetaObject::invokeMethod(this, [this, isSeekable]() {Q_EMIT seekableChanged(isSeekable);}, Qt::QueuedConnection); 0436 } 0437 0438 void AudioWrapperPrivate::vlcEventCallback(const struct libvlc_event_t *p_event) 0439 { 0440 const auto eventType = static_cast<libvlc_event_e>(p_event->type); 0441 0442 switch(eventType) 0443 { 0444 case libvlc_MediaPlayerOpening: 0445 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerOpening"; 0446 signalMediaStatusChange(QMediaPlayer::LoadedMedia); 0447 break; 0448 case libvlc_MediaPlayerBuffering: 0449 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerBuffering"; 0450 signalMediaStatusChange(QMediaPlayer::BufferedMedia); 0451 break; 0452 case libvlc_MediaPlayerPlaying: 0453 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPlaying"; 0454 signalPlaybackChange(QMediaPlayer::PlayingState); 0455 break; 0456 case libvlc_MediaPlayerPaused: 0457 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPaused"; 0458 signalPlaybackChange(QMediaPlayer::PausedState); 0459 break; 0460 case libvlc_MediaPlayerStopped: 0461 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerStopped"; 0462 signalPlaybackChange(QMediaPlayer::StoppedState); 0463 break; 0464 #if LIBVLC_VERSION_MAJOR >= 4 0465 case libvlc_MediaPlayerStopping: 0466 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" 0467 << "libvlc_MediaPlayerStopping"; 0468 #else 0469 case libvlc_MediaPlayerEndReached: 0470 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" 0471 << "libvlc_MediaPlayerEndReached"; 0472 #endif 0473 signalMediaStatusChange(QMediaPlayer::BufferedMedia); 0474 signalMediaStatusChange(QMediaPlayer::NoMedia); 0475 signalMediaStatusChange(QMediaPlayer::EndOfMedia); 0476 mediaIsEnded(); 0477 break; 0478 case libvlc_MediaPlayerEncounteredError: 0479 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerEncounteredError"; 0480 signalErrorChange(QMediaPlayer::ResourceError); 0481 mediaIsEnded(); 0482 signalMediaStatusChange(QMediaPlayer::InvalidMedia); 0483 break; 0484 case libvlc_MediaPlayerPositionChanged: 0485 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPositionChanged"; 0486 signalPositionChange(p_event->u.media_player_position_changed.new_position); 0487 break; 0488 case libvlc_MediaPlayerSeekableChanged: 0489 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerSeekableChanged"; 0490 signalSeekableChange(p_event->u.media_player_seekable_changed.new_seekable); 0491 break; 0492 case libvlc_MediaPlayerLengthChanged: 0493 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerLengthChanged"; 0494 signalDurationChange(p_event->u.media_player_length_changed.new_length); 0495 if (mHasSavedPosition) { 0496 mParent->setPosition(mSavedPosition); 0497 mHasSavedPosition = false; 0498 } 0499 break; 0500 case libvlc_MediaPlayerMuted: 0501 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerMuted"; 0502 signalMutedChange(true); 0503 break; 0504 case libvlc_MediaPlayerUnmuted: 0505 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerUnmuted"; 0506 signalMutedChange(false); 0507 break; 0508 case libvlc_MediaPlayerAudioVolume: 0509 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioVolume"; 0510 signalVolumeChange(qRound(p_event->u.media_player_audio_volume.volume * 100)); 0511 break; 0512 case libvlc_MediaPlayerAudioDevice: 0513 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioDevice"; 0514 break; 0515 default: 0516 qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "eventType" << eventType; 0517 break; 0518 } 0519 } 0520 0521 void AudioWrapperPrivate::mediaIsEnded() 0522 { 0523 libvlc_media_release(mMedia); 0524 mMedia = nullptr; 0525 } 0526 0527 bool AudioWrapperPrivate::signalPlaybackChange(QMediaPlayer::PlaybackState newPlayerState) 0528 { 0529 if (mPreviousPlayerState != newPlayerState) { 0530 mPreviousPlayerState = newPlayerState; 0531 0532 mParent->playerStateSignalChanges(mPreviousPlayerState); 0533 0534 return true; 0535 } 0536 0537 return false; 0538 } 0539 0540 void AudioWrapperPrivate::signalMediaStatusChange(QMediaPlayer::MediaStatus newMediaStatus) 0541 { 0542 if (mPreviousMediaStatus != newMediaStatus) { 0543 mPreviousMediaStatus = newMediaStatus; 0544 0545 mParent->mediaStatusSignalChanges(mPreviousMediaStatus); 0546 } 0547 } 0548 0549 void AudioWrapperPrivate::signalVolumeChange(int newVolume) 0550 { 0551 if (newVolume == -1) { 0552 return; 0553 } 0554 0555 if (mPreviousPlayerState == QMediaPlayer::StoppedState) { 0556 return; 0557 } 0558 0559 if (abs(int(mPreviousVolume - newVolume)) >= 1) { 0560 mPreviousVolume = newVolume; 0561 0562 mParent->playerVolumeSignalChanges(); 0563 } 0564 } 0565 0566 void AudioWrapperPrivate::signalMutedChange(bool isMuted) 0567 { 0568 if (mIsMuted != isMuted) { 0569 mIsMuted = isMuted; 0570 0571 mParent->playerMutedSignalChanges(mIsMuted); 0572 } 0573 } 0574 0575 void AudioWrapperPrivate::signalDurationChange(libvlc_time_t newDuration) 0576 { 0577 if (mMediaDuration != newDuration) { 0578 mMediaDuration = newDuration; 0579 0580 mParent->playerDurationSignalChanges(mMediaDuration); 0581 } 0582 } 0583 0584 void AudioWrapperPrivate::signalPositionChange(float newPosition) 0585 { 0586 if (mMediaDuration == -1) { 0587 return; 0588 } 0589 0590 auto computedPosition = qRound64(newPosition * mMediaDuration); 0591 0592 if (mPreviousPosition != computedPosition) { 0593 mPreviousPosition = computedPosition; 0594 0595 mParent->playerPositionSignalChanges(mPreviousPosition); 0596 } 0597 0598 if (this->mMedia) { 0599 QString title = QLatin1String(libvlc_media_get_meta(this->mMedia, libvlc_meta_Title)); 0600 QString nowPlaying = QLatin1String(libvlc_media_get_meta(this->mMedia, libvlc_meta_NowPlaying)); 0601 0602 Q_EMIT mParent->currentPlayingForRadiosChanged(title, nowPlaying); 0603 } 0604 } 0605 0606 void AudioWrapperPrivate::signalSeekableChange(bool isSeekable) 0607 { 0608 if (mIsSeekable != isSeekable) { 0609 mIsSeekable = isSeekable; 0610 0611 mParent->playerSeekableSignalChanges(isSeekable); 0612 } 0613 } 0614 0615 void AudioWrapperPrivate::signalErrorChange(QMediaPlayer::Error errorCode) 0616 { 0617 if (mError != errorCode) { 0618 mError = errorCode; 0619 0620 mParent->playerErrorSignalChanges(errorCode); 0621 } 0622 } 0623 0624 0625 #include "moc_audiowrapper.cpp"