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 | |
14 | QT_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 | */ |
130 | QList<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 | */ |
151 | QList<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 | */ |
166 | QList<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 | */ |
188 | QAudioDevice 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 | */ |
215 | QAudioDevice 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 | */ |
250 | QCameraDevice 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 | */ |
264 | QMediaDevices::QMediaDevices(QObject *parent) : QObject(parent) { } |
265 | |
266 | /*! |
267 | \internal |
268 | */ |
269 | QMediaDevices::~QMediaDevices() = default; |
270 | |
271 | void 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 | |
303 | QT_END_NAMESPACE |
304 | |
305 | #include "moc_qmediadevices.cpp" |
306 | |