diff options
-rw-r--r-- | examples/multimediawidgets/camera/camera.cpp | 29 | ||||
-rw-r--r-- | examples/multimediawidgets/camera/camera.h | 5 | ||||
-rw-r--r-- | src/multimedia/platform/darwin/qdarwindevicemanager.mm | 36 | ||||
-rw-r--r-- | src/multimedia/platform/darwin/qdarwindevicemanager_p.h | 3 |
4 files changed, 51 insertions, 22 deletions
diff --git a/examples/multimediawidgets/camera/camera.cpp b/examples/multimediawidgets/camera/camera.cpp index 196b8ba84..385608bbc 100644 --- a/examples/multimediawidgets/camera/camera.cpp +++ b/examples/multimediawidgets/camera/camera.cpp @@ -73,18 +73,10 @@ Camera::Camera() : ui(new Ui::Camera) //Camera devices: - QActionGroup *videoDevicesGroup = new QActionGroup(this); + videoDevicesGroup = new QActionGroup(this); videoDevicesGroup->setExclusive(true); - const QList<QCameraInfo> availableCameras = QMediaDeviceManager::videoInputs(); - for (const QCameraInfo &cameraInfo : availableCameras) { - QAction *videoDeviceAction = new QAction(cameraInfo.description(), videoDevicesGroup); - videoDeviceAction->setCheckable(true); - videoDeviceAction->setData(QVariant::fromValue(cameraInfo)); - if (cameraInfo == QMediaDeviceManager::defaultVideoInput()) - videoDeviceAction->setChecked(true); - - ui->menuDevices->addAction(videoDeviceAction); - } + updateCameras(); + connect(QMediaDeviceManager::instance(), &QMediaDeviceManager::videoInputsChanged, this, &Camera::updateCameras); connect(videoDevicesGroup, &QActionGroup::triggered, this, &Camera::updateCameraDevice); connect(ui->captureWidget, &QTabWidget::currentChanged, this, &Camera::updateCaptureMode); @@ -433,3 +425,18 @@ void Camera::closeEvent(QCloseEvent *event) event->accept(); } } + +void Camera::updateCameras() +{ + ui->menuDevices->clear(); + const QList<QCameraInfo> availableCameras = QMediaDeviceManager::videoInputs(); + for (const QCameraInfo &cameraInfo : availableCameras) { + QAction *videoDeviceAction = new QAction(cameraInfo.description(), videoDevicesGroup); + videoDeviceAction->setCheckable(true); + videoDeviceAction->setData(QVariant::fromValue(cameraInfo)); + if (cameraInfo == QMediaDeviceManager::defaultVideoInput()) + videoDeviceAction->setChecked(true); + + ui->menuDevices->addAction(videoDeviceAction); + } +} diff --git a/examples/multimediawidgets/camera/camera.h b/examples/multimediawidgets/camera/camera.h index bdef8b8f8..d45923cc4 100644 --- a/examples/multimediawidgets/camera/camera.h +++ b/examples/multimediawidgets/camera/camera.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE namespace Ui { class Camera; } +class QActionGroup; QT_END_NAMESPACE class Camera : public QMainWindow @@ -109,6 +110,8 @@ private slots: void readyForCapture(bool ready); void imageSaved(int id, const QString &fileName); + void updateCameras(); + protected: void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; @@ -117,6 +120,8 @@ protected: private: Ui::Camera *ui; + QActionGroup *videoDevicesGroup = nullptr; + QScopedPointer<QCamera> m_camera; QCameraImageCapture *m_imageCapture; QScopedPointer<QMediaRecorder> m_mediaRecorder; diff --git a/src/multimedia/platform/darwin/qdarwindevicemanager.mm b/src/multimedia/platform/darwin/qdarwindevicemanager.mm index 0643c121b..fadc254ae 100644 --- a/src/multimedia/platform/darwin/qdarwindevicemanager.mm +++ b/src/multimedia/platform/darwin/qdarwindevicemanager.mm @@ -144,10 +144,26 @@ QList<QAudioDeviceInfo> availableAudioDevices(QAudio::Mode mode) QDarwinDeviceManager::QDarwinDeviceManager() : QMediaPlatformDeviceManager() { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + m_deviceConnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *) { + this->updateCameraDevices(); + }]; + + m_deviceDisconnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *) { + this->updateCameraDevices(); + }]; } - QDarwinDeviceManager::~QDarwinDeviceManager() { + NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter removeObserver:(id)m_deviceConnectedObserver]; + [notificationCenter removeObserver:(id)m_deviceDisconnectedObserver]; } QList<QAudioDeviceInfo> QDarwinDeviceManager::audioInputs() const @@ -184,14 +200,9 @@ void QDarwinDeviceManager::updateCameraDevices() const // Cameras can't change dynamically on iOS. Update only once. if (!m_cameraDevices.isEmpty()) return; -#else - // On OS X, cameras can be added or removed. Update the list every time, but not more than - // once every 500 ms - if (deviceCheckTimer.isValid() && deviceCheckTimer.elapsed() < 500) // ms - return; #endif - QList<QCameraInfoPrivate> cameras; + QList<QCameraInfo> cameras; AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; @@ -204,12 +215,15 @@ void QDarwinDeviceManager::updateCameraDevices() const info->description = QString::fromNSString([device localizedName]); - m_cameraDevices.append(QCameraInfo(info)); + cameras.append(QCameraInfo(info)); } -#ifndef Q_OS_IOS - deviceCheckTimer.restart(); -#endif + if (cameras != m_cameraDevices) { + m_cameraDevices = cameras; + auto *m = deviceManager(); + if (m) + m->videoInputsChanged(); + } } diff --git a/src/multimedia/platform/darwin/qdarwindevicemanager_p.h b/src/multimedia/platform/darwin/qdarwindevicemanager_p.h index 5047791c5..518e5cc8d 100644 --- a/src/multimedia/platform/darwin/qdarwindevicemanager_p.h +++ b/src/multimedia/platform/darwin/qdarwindevicemanager_p.h @@ -79,6 +79,9 @@ public: private: mutable QElapsedTimer deviceCheckTimer; mutable QList<QCameraInfo> m_cameraDevices; + + void *m_deviceConnectedObserver; + void *m_deviceDisconnectedObserver; }; QT_END_NAMESPACE |