1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmediadevices.h"
5#include "private/qplatformmediaintegration_p.h"
6#include "private/qplatformaudiodevices_p.h"
7#include "private/qplatformvideodevices_p.h"
8
9#include <QtCore/qmetaobject.h>
10
11#include <qaudiodevice.h>
12#include <qcameradevice.h>
13
14QT_BEGIN_NAMESPACE
15
16/*!
17 \class QMediaDevices
18 \brief The QMediaDevices class provides information about available
19 multimedia input and output devices.
20 \ingroup multimedia
21 \inmodule QtMultimedia
22
23 The QMediaDevices class provides information about the available multimedia
24 devices and the system defaults. It monitors the following three groups:
25 \list
26 \li Audio input devices (Microphones)
27 \li Audio output devices (Speakers, Headsets)
28 \li Video input devices (Cameras)
29 \endlist
30
31 QMediaDevices provides a separate list for each device group. If it detects that a
32 new device has been connected to the system or an attached device has been disconnected
33 from the system, it will update the corresponding device list and emit a signal
34 notifying about the change.
35
36 The QMediaDevices::audioInputs and QMediaDevices::audioOutputs functions can be used
37 to enumerate all microphones and speakers/headsets on the system. This example first
38 gets a list of all connected microphones, and then prints their identifier, description,
39 and if it is the default device or not.
40
41 \snippet multimedia-snippets/devices.cpp Media Audio Input Device Enumeration
42
43 Similarly, the QMediaDevices::videoInputs will return a list of all connected cameras.
44 In this example we list all connected cameras and their identifier, description, and
45 if it is the default camera or not.
46
47 \snippet multimedia-snippets/devices.cpp Media Video Input Device Enumeration
48
49 QMediaDevices monitors the system defaults for each device group. It will notify about
50 any changes done through the system settings. For example, if the user selects a new
51 default audio output in the system settings, QMediaDevices will update the default audio
52 output accordingly and emit a signal. If the system does not provide a default for a
53 camera or an audio input, QMediaDevices will select the first device from the list as
54 the default device.
55
56 While using the default input and output devices is often sufficient for
57 playing back or recording multimedia, there is often a need to explicitly
58 select the device to be used.
59
60 QMediaDevices is a singleton object and all getters are thread-safe.
61*/
62
63/*!
64 \qmltype MediaDevices
65 \since 6.2
66 \nativetype QMediaDevices
67 \brief MediaDevices provides information about available
68 multimedia input and output devices.
69 \inqmlmodule QtMultimedia
70 \ingroup multimedia_qml
71
72 The MediaDevices type provides information about the available multimedia
73 devices and the system defaults. It monitors the following three groups:
74 \list
75 \li Audio input devices (Microphones)
76 \li Audio output devices (Speakers, Headsets)
77 \li Video input devices (Cameras)
78 \endlist
79
80 MediaDevices provides a separate list for each device group. If it detects that a
81 new device has been connected to the system or an attached device has been disconnected
82 from the system, it will update the corresponding device list and emit a signal
83 notifying about the change.
84
85 MediaDevices monitors the system defaults for each device group. It will notify about
86 any changes done through the system settings. For example, if the user selects a new
87 default audio output in the system settings, MediaDevices will update the default audio
88 output accordingly and emit a signal. If the system does not provide a default for a
89 camera or an audio input, MediaDevices will select the first device from the list as
90 the default device.
91
92 While using the default input and output devices is often sufficient for
93 playing back or recording multimedia, there is often a need to explicitly
94 select the device to be used.
95
96 For example, the snippet below will ensure that the media player always uses
97 the systems default audio output device for playback:
98
99 \qml
100 MediaDevices {
101 id: devices
102 }
103 MediaPlayer {
104 ...
105 audioOutput: AudioOutput {
106 device: devices.defaultAudioOutput
107 }
108 }
109 \endqml
110
111 \sa Camera, AudioInput, VideoOutput
112*/
113
114/*!
115 \qmlproperty list<audioDevice> QtMultimedia::MediaDevices::audioInputs
116 Contains a list of available audio input devices on the system.
117
118 Those devices are usually microphones. Devices can be either built-in, or
119 connected through for example USB or Bluetooth.
120*/
121
122/*!
123 \property QMediaDevices::audioInputs
124
125 Returns a list of available audio input devices on the system.
126
127 Those devices are usually microphones. Devices can be either built-in, or
128 connected through for example USB or Bluetooth.
129*/
130QList<QAudioDevice> QMediaDevices::audioInputs()
131{
132 return QPlatformMediaIntegration::instance()->audioDevices()->audioInputs();
133}
134
135/*!
136 \qmlproperty list<audioDevice> QtMultimedia::MediaDevices::audioOutputs
137 Contains a list of available audio output devices on the system.
138
139 Those devices are usually loudspeakers or head sets. Devices can be either
140 built-in, or connected through for example USB or Bluetooth.
141*/
142
143/*!
144 \property QMediaDevices::audioOutputs
145
146 Returns a list of available audio output devices on the system.
147
148 Those devices are usually loudspeakers or head sets. Devices can be either
149 built-in, or connected through for example USB or Bluetooth.
150*/
151QList<QAudioDevice> QMediaDevices::audioOutputs()
152{
153 return QPlatformMediaIntegration::instance()->audioDevices()->audioOutputs();
154}
155
156/*!
157 \qmlproperty list<cameraDevice> QtMultimedia::MediaDevices::videoInputs
158 Contains a list of cameras on the system.
159*/
160
161/*!
162 \property QMediaDevices::videoInputs
163
164 Returns a list of available cameras on the system.
165*/
166QList<QCameraDevice> QMediaDevices::videoInputs()
167{
168 QPlatformVideoDevices *videoDevices = QPlatformMediaIntegration::instance()->videoDevices();
169 return videoDevices ? videoDevices->videoInputs() : QList<QCameraDevice>{};
170}
171
172/*!
173 \qmlproperty audioDevice QtMultimedia::MediaDevices::defaultAudioInput
174 Returns the default audio input device.
175
176 The default device can change during the runtime of the application. The value
177 of this property will automatically adjust itself to such changes.
178*/
179
180/*!
181 \property QMediaDevices::defaultAudioInput
182
183 Returns the default audio input device.
184
185 The default device can change during the runtime of the application.
186 The audioInputsChanged() signal is emitted in this case.
187*/
188QAudioDevice QMediaDevices::defaultAudioInput()
189{
190 const auto inputs = audioInputs();
191 if (inputs.isEmpty())
192 return {};
193 for (const auto &info : inputs)
194 if (info.isDefault())
195 return info;
196 return inputs.value(i: 0);
197}
198
199/*!
200 \qmlproperty audioDevice QtMultimedia::MediaDevices::defaultAudioOutput
201 Returns the default audio output device.
202
203 The default device can change during the runtime of the application. The value
204 of this property will automatically adjust itself to such changes.
205*/
206
207/*!
208 \property QMediaDevices::defaultAudioOutput
209
210 Returns the default audio output device.
211
212 The default device can change during the runtime of the application. The
213 audioOutputsChanged() signal is emitted in this case.
214*/
215QAudioDevice QMediaDevices::defaultAudioOutput()
216{
217 const auto outputs = audioOutputs();
218 if (outputs.isEmpty())
219 return {};
220 for (const auto &info : outputs)
221 if (info.isDefault())
222 return info;
223 return outputs.value(i: 0);
224}
225
226/*!
227 \qmlproperty cameraDevice QtMultimedia::MediaDevices::defaultVideoInput
228 Returns the default camera on the system.
229
230 \note The returned object should be checked using isNull() before being used,
231 in case there is no camera available.
232
233 The default device can change during the runtime of the application. The value
234 of this property will automatically adjust itself to such changes.
235*/
236
237/*!
238 \property QMediaDevices::defaultVideoInput
239
240 Returns the default camera on the system.
241
242 \note The returned object should be checked using isNull() before being used,
243 in case there is no default camera or no cameras at all.
244
245 The default device can change during the runtime of the application. The
246 videoInputsChanged() signal is emitted in that case.
247
248 \sa videoInputs()
249*/
250QCameraDevice QMediaDevices::defaultVideoInput()
251{
252 const auto inputs = videoInputs();
253 if (inputs.isEmpty())
254 return {};
255 for (const auto &info : inputs)
256 if (info.isDefault())
257 return info;
258 return inputs.value(i: 0);
259}
260
261/*!
262 \internal
263*/
264QMediaDevices::QMediaDevices(QObject *parent) : QObject(parent) { }
265
266/*!
267 \internal
268*/
269QMediaDevices::~QMediaDevices() = default;
270
271void QMediaDevices::connectNotify(const QMetaMethod &signal)
272{
273 // we don't connect in the constructor in order to not initialize
274 // the cameras tracking pipeline or audio tracking pipeline if cameras or audio devices
275 // are not requested. The instance of device provider is lazily created upon the first
276 // connection or the first devices request.
277
278 auto ensureConnection = [&](auto devicesMethod, auto platformDevicesSignal, auto targetSignal) {
279 if (signal == QMetaMethod::fromSignal(targetSignal))
280 if (auto devices = (QPlatformMediaIntegration::instance()->*devicesMethod)()) {
281 connect(devices, platformDevicesSignal, this, targetSignal, Qt::UniqueConnection);
282 return true;
283 }
284
285 return false;
286 };
287
288 // clang-format off
289 ensureConnection(&QPlatformMediaIntegration::videoDevices,
290 &QPlatformVideoDevices::videoInputsChanged,
291 &QMediaDevices::videoInputsChanged) ||
292 ensureConnection(&QPlatformMediaIntegration::audioDevices,
293 &QPlatformAudioDevices::audioInputsChanged,
294 &QMediaDevices::audioInputsChanged) ||
295 ensureConnection(&QPlatformMediaIntegration::audioDevices,
296 &QPlatformAudioDevices::audioOutputsChanged,
297 &QMediaDevices::audioOutputsChanged);
298 // clang-format on
299
300 QObject::connectNotify(signal);
301}
302
303QT_END_NAMESPACE
304
305#include "moc_qmediadevices.cpp"
306

source code of qtmultimedia/src/multimedia/qmediadevices.cpp