Replaced QAudioCaptureSource with QAudioRecorder.
QAudioCaptureSource name is confusing, it's essentially an audio recording service but it's not evident from API. QAudioRecorder replaces QAudioCaptureSource+QMediaRecorder combination. Change-Id: I0082d766fc0d1b8d5ecbfc527f13e715add730c8 Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
8c74e5e7e7
commit
69cef0c24c
@@ -61,49 +61,47 @@ API to quickly build functionality.
|
|||||||
|
|
||||||
The first step is to demonstrate recording audio to a file. When recording from an audio source there are a number of things we may want to control beyond the essential user interface. We may want a particular encoding of the file, MP3 or Ogg Vorbis for instance, or select a different input source. The user may modify the bitrate, number of channels, quality and sample rate. Here the example will only modify the codec and the source device, since they are essential.
|
The first step is to demonstrate recording audio to a file. When recording from an audio source there are a number of things we may want to control beyond the essential user interface. We may want a particular encoding of the file, MP3 or Ogg Vorbis for instance, or select a different input source. The user may modify the bitrate, number of channels, quality and sample rate. Here the example will only modify the codec and the source device, since they are essential.
|
||||||
|
|
||||||
To begin, the developer sets up a source and a recorder object. A
|
To begin, the developer sets up an audio recorder object. A
|
||||||
\l{QAudioCaptureSource} object is created and used to initialize a \l{QMediaRecorder} object. The output file name is then set for the \l{QMediaRecorder} object.
|
\l{QAudioRecorder} object is created. The output file name is then set for the \l{QMediaRecorder} object.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
audiosource = new QAudioCaptureSource;
|
audioRecorder = new QAudioRecorder;
|
||||||
capture = new QMediaRecorder(audiosource);
|
audioRecorder->setOutputLocation(QUrl("test.raw"));
|
||||||
|
|
||||||
capture->setOutputLocation(QUrl("test.raw"));
|
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
A list of devices is needed so that an input can be selected in the user interface
|
A list of devices is needed so that an input can be selected in the user interface
|
||||||
|
|
||||||
\code
|
\code
|
||||||
for(int i = 0; i < audiosource->deviceCount(); i++)
|
for (int i = 0; i < audioRecorder->deviceCount(); i++)
|
||||||
deviceBox->addItem(audiosource->name(i));
|
deviceBox->addItem(audiosource->name(i));
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
and a list of the supported codecs for the user to select a codec,
|
and a list of the supported codecs for the user to select a codec,
|
||||||
|
|
||||||
\code
|
\code
|
||||||
QStringList codecs = capture->supportedAudioCodecs();
|
QStringList codecs = audioRecorder->supportedAudioCodecs();
|
||||||
for(int i = 0; i < codecs.count(); i++)
|
for (int i = 0; i < codecs.count(); i++)
|
||||||
codecsBox->addItem(codecs.at(i));
|
codecsBox->addItem(codecs.at(i));
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
To set the selected device or codec just use the index of the device or codec by calling the setter in \i {audiosource} or \i {capture} as appropriate, for example,
|
To set the selected device or codec just use the index of the device or codec by calling the setter in \i {audiosource} or \i {capture} as appropriate, for example,
|
||||||
|
|
||||||
\code
|
\code
|
||||||
audiosource->setSelectedDevice(i);
|
audioRecorder->setSelectedDevice(i);
|
||||||
...
|
...
|
||||||
capture->setAudioCodec(codecIdx);
|
audioRecorder->setAudioCodec(codecIdx);
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
Now start recording by using the \l {QMediaRecorder}{record()} function from the new \l{QMediaRecorder} object
|
Now start recording by using the \l {QMediaRecorder}{record()} function from the new \l{QMediaRecorder} object
|
||||||
|
|
||||||
\code
|
\code
|
||||||
capture->record();
|
audioRecorder->record();
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
And stop recording by calling the matching function \l {QMediaRecorder::stop()}{stop()} in \l{QMediaRecorder}.
|
And stop recording by calling the matching function \l {QMediaRecorder::stop()}{stop()} in \l{QMediaRecorder}.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
capture->stop();
|
audioRecorder->stop();
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
How then would this audio file be played? The \l {QMediaPlayer} class will be
|
How then would this audio file be played? The \l {QMediaPlayer} class will be
|
||||||
@@ -228,8 +226,7 @@ the next photo.
|
|||||||
\section2 Video Clips
|
\section2 Video Clips
|
||||||
|
|
||||||
Previously we saw code that allowed the capture of a still image. Recording
|
Previously we saw code that allowed the capture of a still image. Recording
|
||||||
video requires the use of a \l QMediaRecorder object and a \l
|
video requires the use of a \l QMediaRecorder object.
|
||||||
QAudioCaptureSource for sound.
|
|
||||||
|
|
||||||
To record video we need a camera object, as before, a media recorder and a
|
To record video we need a camera object, as before, a media recorder and a
|
||||||
viewfinder object. The media recorder object will need to be initialized.
|
viewfinder object. The media recorder object will need to be initialized.
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
#include <QtCore/qdir.h>
|
#include <QtCore/qdir.h>
|
||||||
#include <QtWidgets/qfiledialog.h>
|
#include <QtWidgets/qfiledialog.h>
|
||||||
|
|
||||||
#include <qaudiocapturesource.h>
|
#include <qaudiorecorder.h>
|
||||||
#include <qmediarecorder.h>
|
#include <qmediarecorder.h>
|
||||||
|
|
||||||
#include "audiorecorder.h"
|
#include "audiorecorder.h"
|
||||||
@@ -60,30 +60,29 @@ AudioRecorder::AudioRecorder(QWidget *parent)
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
audiosource = new QAudioCaptureSource(this);
|
audioRecorder = new QAudioRecorder(this);
|
||||||
capture = new QMediaRecorder(audiosource, this);
|
|
||||||
|
|
||||||
//audio devices
|
//audio devices
|
||||||
ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
|
ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
|
||||||
foreach(const QString &device, audiosource->audioInputs()) {
|
foreach (const QString &device, audioRecorder->audioInputs()) {
|
||||||
ui->audioDeviceBox->addItem(device, QVariant(device));
|
ui->audioDeviceBox->addItem(device, QVariant(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
//audio codecs
|
//audio codecs
|
||||||
ui->audioCodecBox->addItem(tr("Default"), QVariant(QString()));
|
ui->audioCodecBox->addItem(tr("Default"), QVariant(QString()));
|
||||||
foreach(const QString &codecName, capture->supportedAudioCodecs()) {
|
foreach (const QString &codecName, audioRecorder->supportedAudioCodecs()) {
|
||||||
ui->audioCodecBox->addItem(codecName, QVariant(codecName));
|
ui->audioCodecBox->addItem(codecName, QVariant(codecName));
|
||||||
}
|
}
|
||||||
|
|
||||||
//containers
|
//containers
|
||||||
ui->containerBox->addItem(tr("Default"), QVariant(QString()));
|
ui->containerBox->addItem(tr("Default"), QVariant(QString()));
|
||||||
foreach(const QString &containerName, capture->supportedContainers()) {
|
foreach (const QString &containerName, audioRecorder->supportedContainers()) {
|
||||||
ui->containerBox->addItem(containerName, QVariant(containerName));
|
ui->containerBox->addItem(containerName, QVariant(containerName));
|
||||||
}
|
}
|
||||||
|
|
||||||
//sample rate:
|
//sample rate:
|
||||||
ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
|
ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
|
||||||
foreach(int sampleRate, capture->supportedAudioSampleRates()) {
|
foreach (int sampleRate, audioRecorder->supportedAudioSampleRates()) {
|
||||||
ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
|
ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
|
||||||
sampleRate));
|
sampleRate));
|
||||||
}
|
}
|
||||||
@@ -98,23 +97,22 @@ AudioRecorder::AudioRecorder(QWidget *parent)
|
|||||||
ui->bitrateBox->addItem(QString("96000"), QVariant(96000));
|
ui->bitrateBox->addItem(QString("96000"), QVariant(96000));
|
||||||
ui->bitrateBox->addItem(QString("128000"), QVariant(128000));
|
ui->bitrateBox->addItem(QString("128000"), QVariant(128000));
|
||||||
|
|
||||||
connect(capture, SIGNAL(durationChanged(qint64)), this,
|
connect(audioRecorder, SIGNAL(durationChanged(qint64)), this,
|
||||||
SLOT(updateProgress(qint64)));
|
SLOT(updateProgress(qint64)));
|
||||||
connect(capture, SIGNAL(stateChanged(QMediaRecorder::State)), this,
|
connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this,
|
||||||
SLOT(updateState(QMediaRecorder::State)));
|
SLOT(updateState(QMediaRecorder::State)));
|
||||||
connect(capture, SIGNAL(error(QMediaRecorder::Error)), this,
|
connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this,
|
||||||
SLOT(displayErrorMessage()));
|
SLOT(displayErrorMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioRecorder::~AudioRecorder()
|
AudioRecorder::~AudioRecorder()
|
||||||
{
|
{
|
||||||
delete capture;
|
delete audioRecorder;
|
||||||
delete audiosource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRecorder::updateProgress(qint64 duration)
|
void AudioRecorder::updateProgress(qint64 duration)
|
||||||
{
|
{
|
||||||
if (capture->error() != QMediaRecorder::NoError || duration < 2000)
|
if (audioRecorder->error() != QMediaRecorder::NoError || duration < 2000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
|
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
|
||||||
@@ -128,11 +126,11 @@ void AudioRecorder::updateState(QMediaRecorder::State state)
|
|||||||
case QMediaRecorder::RecordingState:
|
case QMediaRecorder::RecordingState:
|
||||||
ui->recordButton->setText(tr("Stop"));
|
ui->recordButton->setText(tr("Stop"));
|
||||||
ui->pauseButton->setText(tr("Pause"));
|
ui->pauseButton->setText(tr("Pause"));
|
||||||
if (capture->outputLocation().isEmpty())
|
if (audioRecorder->outputLocation().isEmpty())
|
||||||
statusMessage = tr("Recording");
|
statusMessage = tr("Recording");
|
||||||
else
|
else
|
||||||
statusMessage = tr("Recording to %1").arg(
|
statusMessage = tr("Recording to %1").arg(
|
||||||
capture->outputLocation().toString());
|
audioRecorder->outputLocation().toString());
|
||||||
break;
|
break;
|
||||||
case QMediaRecorder::PausedState:
|
case QMediaRecorder::PausedState:
|
||||||
ui->recordButton->setText(tr("Stop"));
|
ui->recordButton->setText(tr("Stop"));
|
||||||
@@ -147,7 +145,7 @@ void AudioRecorder::updateState(QMediaRecorder::State state)
|
|||||||
|
|
||||||
ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState);
|
ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState);
|
||||||
|
|
||||||
if (capture->error() == QMediaRecorder::NoError)
|
if (audioRecorder->error() == QMediaRecorder::NoError)
|
||||||
ui->statusbar->showMessage(statusMessage);
|
ui->statusbar->showMessage(statusMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +160,11 @@ static QVariant boxValue(const QComboBox *box)
|
|||||||
|
|
||||||
void AudioRecorder::toggleRecord()
|
void AudioRecorder::toggleRecord()
|
||||||
{
|
{
|
||||||
if (capture->state() == QMediaRecorder::StoppedState) {
|
if (audioRecorder->state() == QMediaRecorder::StoppedState) {
|
||||||
audiosource->setAudioInput(boxValue(ui->audioDeviceBox).toString());
|
audioRecorder->setAudioInput(boxValue(ui->audioDeviceBox).toString());
|
||||||
|
|
||||||
if (!outputLocationSet)
|
if (!outputLocationSet)
|
||||||
capture->setOutputLocation(generateAudioFilePath());
|
audioRecorder->setOutputLocation(generateAudioFilePath());
|
||||||
|
|
||||||
QAudioEncoderSettings settings;
|
QAudioEncoderSettings settings;
|
||||||
settings.setCodec(boxValue(ui->audioCodecBox).toString());
|
settings.setCodec(boxValue(ui->audioCodecBox).toString());
|
||||||
@@ -179,32 +177,32 @@ void AudioRecorder::toggleRecord()
|
|||||||
|
|
||||||
QString container = boxValue(ui->containerBox).toString();
|
QString container = boxValue(ui->containerBox).toString();
|
||||||
|
|
||||||
capture->setEncodingSettings(settings, QVideoEncoderSettings(), container);
|
audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
|
||||||
capture->record();
|
audioRecorder->record();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
capture->stop();
|
audioRecorder->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRecorder::togglePause()
|
void AudioRecorder::togglePause()
|
||||||
{
|
{
|
||||||
if (capture->state() != QMediaRecorder::PausedState)
|
if (audioRecorder->state() != QMediaRecorder::PausedState)
|
||||||
capture->pause();
|
audioRecorder->pause();
|
||||||
else
|
else
|
||||||
capture->record();
|
audioRecorder->record();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRecorder::setOutputLocation()
|
void AudioRecorder::setOutputLocation()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getSaveFileName();
|
QString fileName = QFileDialog::getSaveFileName();
|
||||||
capture->setOutputLocation(QUrl(fileName));
|
audioRecorder->setOutputLocation(QUrl(fileName));
|
||||||
outputLocationSet = true;
|
outputLocationSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRecorder::displayErrorMessage()
|
void AudioRecorder::displayErrorMessage()
|
||||||
{
|
{
|
||||||
ui->statusbar->showMessage(capture->errorString());
|
ui->statusbar->showMessage(audioRecorder->errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl AudioRecorder::generateAudioFilePath()
|
QUrl AudioRecorder::generateAudioFilePath()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Ui {
|
|||||||
class AudioRecorder;
|
class AudioRecorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QAudioCaptureSource;
|
class QAudioRecorder;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
@@ -78,8 +78,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
Ui::AudioRecorder *ui;
|
Ui::AudioRecorder *ui;
|
||||||
|
|
||||||
QAudioCaptureSource* audiosource;
|
QAudioRecorder* audioRecorder;
|
||||||
QMediaRecorder* capture;
|
|
||||||
QAudioEncoderSettings audioSettings;
|
QAudioEncoderSettings audioSettings;
|
||||||
bool outputLocationSet;
|
bool outputLocationSet;
|
||||||
|
|
||||||
|
|||||||
@@ -1,264 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
** All rights reserved.
|
|
||||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
||||||
**
|
|
||||||
** This file is part of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:LGPL$
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** This file may be used under the terms of the GNU Lesser General Public
|
|
||||||
** License version 2.1 as published by the Free Software Foundation and
|
|
||||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
|
||||||
** file. Please review the following information to ensure the GNU Lesser
|
|
||||||
** General Public License version 2.1 requirements will be met:
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU General
|
|
||||||
** Public License version 3.0 as published by the Free Software Foundation
|
|
||||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
|
||||||
** file. Please review the following information to ensure the GNU General
|
|
||||||
** Public License version 3.0 requirements will be met:
|
|
||||||
** http://www.gnu.org/copyleft/gpl.html.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "qmediaobject_p.h"
|
|
||||||
#include <qaudiocapturesource.h>
|
|
||||||
#include "qaudioendpointselector.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\class QAudioCaptureSource
|
|
||||||
\brief The QAudioCaptureSource class provides an interface to query and select an audio input endpoint.
|
|
||||||
\inmodule QtMultimedia
|
|
||||||
\ingroup multimedia
|
|
||||||
\ingroup multimedia_recording
|
|
||||||
|
|
||||||
QAudioCaptureSource provides access to the audio inputs available on your system.
|
|
||||||
|
|
||||||
You can query these inputs and select one to use.
|
|
||||||
|
|
||||||
A typical implementation example:
|
|
||||||
\snippet doc/src/snippets/multimedia-snippets/media.cpp Audio capture source
|
|
||||||
|
|
||||||
The audiocapturesource interface is then used to:
|
|
||||||
|
|
||||||
- Get and Set the audio input to use.
|
|
||||||
|
|
||||||
The capture interface is then used to:
|
|
||||||
|
|
||||||
- Set the destination using setOutputLocation()
|
|
||||||
|
|
||||||
- Set the format parameters using setAudioCodec(),
|
|
||||||
|
|
||||||
- Control the recording using record(),stop()
|
|
||||||
|
|
||||||
\sa QMediaRecorder
|
|
||||||
*/
|
|
||||||
|
|
||||||
class QAudioCaptureSourcePrivate : public QMediaObjectPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Q_DECLARE_PUBLIC(QAudioCaptureSource)
|
|
||||||
|
|
||||||
void initControls()
|
|
||||||
{
|
|
||||||
Q_Q(QAudioCaptureSource);
|
|
||||||
|
|
||||||
if (service != 0)
|
|
||||||
audioEndpointSelector = qobject_cast<QAudioEndpointSelector*>(service->requestControl(QAudioEndpointSelector_iid));
|
|
||||||
|
|
||||||
if (audioEndpointSelector) {
|
|
||||||
q->connect(audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)),
|
|
||||||
SIGNAL(activeAudioInputChanged(const QString&)));
|
|
||||||
q->connect(audioEndpointSelector, SIGNAL(availableEndpointsChanged()),
|
|
||||||
SIGNAL(availableAudioInputsChanged()));
|
|
||||||
q->connect(audioEndpointSelector, SIGNAL(availableEndpointsChanged()),
|
|
||||||
SLOT(statusChanged()));
|
|
||||||
errorState = QtMultimedia::NoError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QAudioCaptureSourcePrivate():provider(0), audioEndpointSelector(0), errorState(QtMultimedia::ServiceMissingError) {}
|
|
||||||
QMediaServiceProvider *provider;
|
|
||||||
QAudioEndpointSelector *audioEndpointSelector;
|
|
||||||
QtMultimedia::AvailabilityError errorState;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Construct a QAudioCaptureSource using the QMediaService from \a provider, with \a parent.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QAudioCaptureSource::QAudioCaptureSource(QObject *parent, QMediaServiceProvider *provider):
|
|
||||||
QMediaObject(*new QAudioCaptureSourcePrivate, parent, provider->requestService(Q_MEDIASERVICE_AUDIOSOURCE))
|
|
||||||
{
|
|
||||||
Q_D(QAudioCaptureSource);
|
|
||||||
|
|
||||||
d->provider = provider;
|
|
||||||
d->initControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Destroys the audiocapturesource object.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QAudioCaptureSource::~QAudioCaptureSource()
|
|
||||||
{
|
|
||||||
Q_D(QAudioCaptureSource);
|
|
||||||
|
|
||||||
if (d->service && d->audioEndpointSelector)
|
|
||||||
d->service->releaseControl(d->audioEndpointSelector);
|
|
||||||
|
|
||||||
if (d->provider)
|
|
||||||
d->provider->releaseService(d->service);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the error state of the audio capture service.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QtMultimedia::AvailabilityError QAudioCaptureSource::availabilityError() const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
return d->errorState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns true if the audio capture service is available, otherwise returns false.
|
|
||||||
*/
|
|
||||||
bool QAudioCaptureSource::isAvailable() const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
if (d->service != NULL) {
|
|
||||||
if (d->audioEndpointSelector && d->audioEndpointSelector->availableEndpoints().size() > 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a list of available audio inputs
|
|
||||||
*/
|
|
||||||
|
|
||||||
QList<QString> QAudioCaptureSource::audioInputs() const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
QList<QString> list;
|
|
||||||
if (d && d->audioEndpointSelector)
|
|
||||||
list <<d->audioEndpointSelector->availableEndpoints();
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the description of the audio input device with \a name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString QAudioCaptureSource::audioDescription(const QString& name) const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
if(d->audioEndpointSelector)
|
|
||||||
return d->audioEndpointSelector->endpointDescription(name);
|
|
||||||
else
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the default audio input name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString QAudioCaptureSource::defaultAudioInput() const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
if(d->audioEndpointSelector)
|
|
||||||
return d->audioEndpointSelector->defaultEndpoint();
|
|
||||||
else
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the active audio input name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString QAudioCaptureSource::activeAudioInput() const
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
if(d->audioEndpointSelector)
|
|
||||||
return d->audioEndpointSelector->activeEndpoint();
|
|
||||||
else
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Set the active audio input to \a name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void QAudioCaptureSource::setAudioInput(const QString& name)
|
|
||||||
{
|
|
||||||
Q_D(const QAudioCaptureSource);
|
|
||||||
|
|
||||||
if(d->audioEndpointSelector)
|
|
||||||
return d->audioEndpointSelector->setActiveEndpoint(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn QAudioCaptureSource::activeAudioInputChanged(const QString& name)
|
|
||||||
|
|
||||||
Signal emitted when active audio input changes to \a name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn QAudioCaptureSource::availableAudioInputsChanged()
|
|
||||||
|
|
||||||
Signal is emitted when the available audio inputs change.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
void QAudioCaptureSource::statusChanged()
|
|
||||||
{
|
|
||||||
Q_D(QAudioCaptureSource);
|
|
||||||
|
|
||||||
if (d->audioEndpointSelector) {
|
|
||||||
if (d->audioEndpointSelector->availableEndpoints().size() > 0) {
|
|
||||||
d->errorState = QtMultimedia::NoError;
|
|
||||||
emit availabilityChanged(true);
|
|
||||||
} else {
|
|
||||||
d->errorState = QtMultimedia::BusyError;
|
|
||||||
emit availabilityChanged(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
d->errorState = QtMultimedia::ServiceMissingError;
|
|
||||||
emit availabilityChanged(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_qaudiocapturesource.cpp"
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
231
src/multimedia/recording/qaudiorecorder.cpp
Normal file
231
src/multimedia/recording/qaudiorecorder.cpp
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qaudiorecorder.h"
|
||||||
|
#include "qaudioendpointselector.h"
|
||||||
|
#include "qmediaobject_p.h"
|
||||||
|
#include "qmediarecorder_p.h"
|
||||||
|
#include <qmediaservice.h>
|
||||||
|
#include <qmediaserviceprovider.h>
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qurl.h>
|
||||||
|
#include <QtCore/qstringlist.h>
|
||||||
|
#include <QtCore/qmetaobject.h>
|
||||||
|
|
||||||
|
#include <qaudioformat.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QAudioRecorder
|
||||||
|
\inmodule QtMultimedia
|
||||||
|
\ingroup multimedia
|
||||||
|
\ingroup multimedia_recording
|
||||||
|
|
||||||
|
\brief The QAudioRecorder class is used for the recording of media content.
|
||||||
|
|
||||||
|
The QAudioRecorder class is a high level media recording class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class QAudioRecorderObject : public QMediaObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QAudioRecorderObject(QObject *parent, QMediaService *service)
|
||||||
|
:QMediaObject(parent, service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~QAudioRecorderObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class QAudioRecorderPrivate : public QMediaRecorderPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_NON_CONST_PUBLIC(QAudioRecorder)
|
||||||
|
|
||||||
|
public:
|
||||||
|
void initControls()
|
||||||
|
{
|
||||||
|
Q_Q(QAudioRecorder);
|
||||||
|
audioEndpointSelector = 0;
|
||||||
|
|
||||||
|
QMediaService *service = mediaObject ? mediaObject->service() : 0;
|
||||||
|
|
||||||
|
if (service != 0)
|
||||||
|
audioEndpointSelector = qobject_cast<QAudioEndpointSelector*>(service->requestControl(QAudioEndpointSelector_iid));
|
||||||
|
|
||||||
|
if (audioEndpointSelector) {
|
||||||
|
q->connect(audioEndpointSelector, SIGNAL(activeEndpointChanged(QString)),
|
||||||
|
SIGNAL(audioInputChanged(QString)));
|
||||||
|
q->connect(audioEndpointSelector, SIGNAL(availableEndpointsChanged()),
|
||||||
|
SIGNAL(availableAudioInputsChanged()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QAudioRecorderPrivate():
|
||||||
|
QMediaRecorderPrivate(),
|
||||||
|
provider(0),
|
||||||
|
audioEndpointSelector(0) {}
|
||||||
|
|
||||||
|
QMediaServiceProvider *provider;
|
||||||
|
QAudioEndpointSelector *audioEndpointSelector;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an audio recorder.
|
||||||
|
The \a parent is passed to QMediaObject.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QAudioRecorder::QAudioRecorder(QObject *parent, QMediaServiceProvider *serviceProvider):
|
||||||
|
QMediaRecorder(*new QAudioRecorderPrivate, 0, parent)
|
||||||
|
{
|
||||||
|
Q_D(QAudioRecorder);
|
||||||
|
d->provider = serviceProvider;
|
||||||
|
|
||||||
|
QMediaService *service = d->provider->requestService(Q_MEDIASERVICE_AUDIOSOURCE);
|
||||||
|
setMediaObject(new QAudioRecorderObject(this, service));
|
||||||
|
d->initControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys an audio recorder object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QAudioRecorder::~QAudioRecorder()
|
||||||
|
{
|
||||||
|
Q_D(QAudioRecorder);
|
||||||
|
QMediaService *service = d->mediaObject ? d->mediaObject->service() : 0;
|
||||||
|
QMediaObject *mediaObject = d->mediaObject;
|
||||||
|
setMediaObject(0);
|
||||||
|
|
||||||
|
if (service && d->audioEndpointSelector)
|
||||||
|
service->releaseControl(d->audioEndpointSelector);
|
||||||
|
|
||||||
|
if (d->provider && service)
|
||||||
|
d->provider->releaseService(service);
|
||||||
|
|
||||||
|
delete mediaObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of available audio inputs
|
||||||
|
*/
|
||||||
|
|
||||||
|
QStringList QAudioRecorder::audioInputs() const
|
||||||
|
{
|
||||||
|
return d_func()->audioEndpointSelector->availableEndpoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the readable translated description of the audio input device with \a name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString QAudioRecorder::audioInputDescription(const QString& name) const
|
||||||
|
{
|
||||||
|
Q_D(const QAudioRecorder);
|
||||||
|
|
||||||
|
if (d->audioEndpointSelector)
|
||||||
|
return d->audioEndpointSelector->endpointDescription(name);
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the default audio input name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString QAudioRecorder::defaultAudioInput() const
|
||||||
|
{
|
||||||
|
Q_D(const QAudioRecorder);
|
||||||
|
|
||||||
|
if (d->audioEndpointSelector)
|
||||||
|
return d->audioEndpointSelector->defaultEndpoint();
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the active audio input name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString QAudioRecorder::audioInput() const
|
||||||
|
{
|
||||||
|
Q_D(const QAudioRecorder);
|
||||||
|
|
||||||
|
if (d->audioEndpointSelector)
|
||||||
|
return d->audioEndpointSelector->activeEndpoint();
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Set the active audio input to \a name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void QAudioRecorder::setAudioInput(const QString& name)
|
||||||
|
{
|
||||||
|
Q_D(const QAudioRecorder);
|
||||||
|
|
||||||
|
if (d->audioEndpointSelector)
|
||||||
|
return d->audioEndpointSelector->setActiveEndpoint(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QAudioRecorder::activeAudioInputChanged(const QString& name)
|
||||||
|
|
||||||
|
Signal emitted when active audio input changes to \a name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QAudioRecorder::availableAudioInputsChanged()
|
||||||
|
|
||||||
|
Signal is emitted when the available audio inputs change.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "moc_qaudiorecorder.cpp"
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
@@ -39,21 +39,15 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef QAUDIOCAPTURESOURCE_H
|
#ifndef QAUDIORECORDER_H
|
||||||
#define QAUDIOCAPTURESOURCE_H
|
#define QAUDIORECORDER_H
|
||||||
|
|
||||||
|
#include <qmediarecorder.h>
|
||||||
|
#include <qmediaobject.h>
|
||||||
|
#include <qmediaencodersettings.h>
|
||||||
|
#include <qmediaenumdebug.h>
|
||||||
|
|
||||||
#include <QtCore/qstringlist.h>
|
|
||||||
#include <QtCore/qpair.h>
|
#include <QtCore/qpair.h>
|
||||||
#include <QtCore/qsize.h>
|
|
||||||
|
|
||||||
#include <qaudioformat.h>
|
|
||||||
|
|
||||||
#include "qmediarecorder.h"
|
|
||||||
#include "qmediacontrol.h"
|
|
||||||
#include "qmediaobject.h"
|
|
||||||
#include "qmediaservice.h"
|
|
||||||
|
|
||||||
#include "qmediaserviceprovider.h"
|
|
||||||
|
|
||||||
QT_BEGIN_HEADER
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
@@ -61,43 +55,42 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
QT_MODULE(Multimedia)
|
QT_MODULE(Multimedia)
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
class QSize;
|
||||||
|
class QAudioFormat;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class QAudioCaptureSourcePrivate;
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Q_MULTIMEDIA_EXPORT QAudioCaptureSource : public QMediaObject
|
class QAudioRecorderPrivate;
|
||||||
|
class Q_MULTIMEDIA_EXPORT QAudioRecorder : public QMediaRecorder
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
|
||||||
public:
|
public:
|
||||||
QAudioCaptureSource(QObject *parent = 0, QMediaServiceProvider *service = QMediaServiceProvider::defaultServiceProvider());
|
QAudioRecorder(QObject *parent = 0, QMediaServiceProvider *serviceProvider = QMediaServiceProvider::defaultServiceProvider());
|
||||||
~QAudioCaptureSource();
|
~QAudioRecorder();
|
||||||
|
|
||||||
bool isAvailable() const;
|
QStringList audioInputs() const;
|
||||||
QtMultimedia::AvailabilityError availabilityError() const;
|
|
||||||
|
|
||||||
QList<QString> audioInputs() const;
|
|
||||||
|
|
||||||
QString audioDescription(const QString& name) const;
|
|
||||||
QString defaultAudioInput() const;
|
QString defaultAudioInput() const;
|
||||||
QString activeAudioInput() const;
|
QString audioInputDescription(const QString& name) const;
|
||||||
|
|
||||||
|
QString audioInput() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setAudioInput(const QString& name);
|
void setAudioInput(const QString& name);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void activeAudioInputChanged(const QString& name);
|
void audioInputChanged(const QString& name);
|
||||||
void availableAudioInputsChanged();
|
void availableAudioInputsChanged();
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void statusChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DECLARE_PRIVATE(QAudioCaptureSource)
|
Q_DISABLE_COPY(QAudioRecorder)
|
||||||
|
Q_DECLARE_PRIVATE(QAudioRecorder)
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
|
||||||
|
#endif // QAUDIORECORDER_H
|
||||||
#endif // QAUDIOCAPTURESOURCE_H
|
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qmediarecorder.h"
|
#include "qmediarecorder.h"
|
||||||
|
#include "qmediarecorder_p.h"
|
||||||
|
|
||||||
#include <qmediarecordercontrol.h>
|
#include <qmediarecordercontrol.h>
|
||||||
#include "qmediaobject_p.h"
|
#include "qmediaobject_p.h"
|
||||||
@@ -71,11 +72,11 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
The QMediaRecorder class is a high level media recording class. It's not
|
The QMediaRecorder class is a high level media recording class. It's not
|
||||||
intended to be used alone but for accessing the media recording functions
|
intended to be used alone but for accessing the media recording functions
|
||||||
of other media objects, like QRadioTuner, or QAudioCaptureSource.
|
of other media objects, like QRadioTuner, or QCamera.
|
||||||
|
|
||||||
\snippet doc/src/snippets/multimedia-snippets/media.cpp Media recorder
|
\snippet doc/src/snippets/multimedia-snippets/media.cpp Media recorder
|
||||||
|
|
||||||
\sa QAudioCaptureSource
|
\sa QAudioRecorder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -91,37 +92,6 @@ public:
|
|||||||
} _registerRecorderMetaTypes;
|
} _registerRecorderMetaTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class QMediaRecorderPrivate
|
|
||||||
{
|
|
||||||
Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)
|
|
||||||
|
|
||||||
public:
|
|
||||||
QMediaRecorderPrivate();
|
|
||||||
|
|
||||||
QMediaObject *mediaObject;
|
|
||||||
|
|
||||||
QMediaRecorderControl *control;
|
|
||||||
QMediaContainerControl *formatControl;
|
|
||||||
QAudioEncoderControl *audioControl;
|
|
||||||
QVideoEncoderControl *videoControl;
|
|
||||||
QMetaDataWriterControl *metaDataControl;
|
|
||||||
|
|
||||||
QTimer* notifyTimer;
|
|
||||||
|
|
||||||
QMediaRecorder::State state;
|
|
||||||
QMediaRecorder::Error error;
|
|
||||||
QString errorString;
|
|
||||||
|
|
||||||
void _q_stateChanged(QMediaRecorder::State state);
|
|
||||||
void _q_error(int error, const QString &errorString);
|
|
||||||
void _q_serviceDestroyed();
|
|
||||||
void _q_notify();
|
|
||||||
void _q_updateNotifyInterval(int ms);
|
|
||||||
|
|
||||||
QMediaRecorder *q_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
QMediaRecorderPrivate::QMediaRecorderPrivate():
|
QMediaRecorderPrivate::QMediaRecorderPrivate():
|
||||||
mediaObject(0),
|
mediaObject(0),
|
||||||
control(0),
|
control(0),
|
||||||
@@ -198,12 +168,27 @@ QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
|
|||||||
{
|
{
|
||||||
Q_D(QMediaRecorder);
|
Q_D(QMediaRecorder);
|
||||||
d->q_ptr = this;
|
d->q_ptr = this;
|
||||||
setMediaObject(mediaObject);
|
|
||||||
|
|
||||||
d->notifyTimer = new QTimer(this);
|
d->notifyTimer = new QTimer(this);
|
||||||
d->notifyTimer->setInterval(mediaObject->notifyInterval());
|
|
||||||
connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
|
connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
|
||||||
connect(mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int)));
|
|
||||||
|
setMediaObject(mediaObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
*/
|
||||||
|
QMediaRecorder::QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
d_ptr(&dd)
|
||||||
|
{
|
||||||
|
Q_D(QMediaRecorder);
|
||||||
|
d->q_ptr = this;
|
||||||
|
|
||||||
|
d->notifyTimer = new QTimer(this);
|
||||||
|
connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
|
||||||
|
|
||||||
|
setMediaObject(mediaObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -248,6 +233,8 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object)
|
|||||||
this, SLOT(_q_error(int,QString)));
|
this, SLOT(_q_error(int,QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), this, SLOT(_q_updateNotifyInterval(int)));
|
||||||
|
|
||||||
QMediaService *service = d->mediaObject->service();
|
QMediaService *service = d->mediaObject->service();
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
@@ -285,6 +272,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object)
|
|||||||
if (d->mediaObject) {
|
if (d->mediaObject) {
|
||||||
QMediaService *service = d->mediaObject->service();
|
QMediaService *service = d->mediaObject->service();
|
||||||
|
|
||||||
|
d->notifyTimer->setInterval(d->mediaObject->notifyInterval());
|
||||||
|
connect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int)));
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid));
|
d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid));
|
||||||
|
|
||||||
|
|||||||
@@ -171,10 +171,11 @@ Q_SIGNALS:
|
|||||||
void metaDataChanged();
|
void metaDataChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent = 0);
|
||||||
bool setMediaObject(QMediaObject *object);
|
bool setMediaObject(QMediaObject *object);
|
||||||
|
|
||||||
private:
|
|
||||||
QMediaRecorderPrivate *d_ptr;
|
QMediaRecorderPrivate *d_ptr;
|
||||||
|
private:
|
||||||
Q_DISABLE_COPY(QMediaRecorder)
|
Q_DISABLE_COPY(QMediaRecorder)
|
||||||
Q_DECLARE_PRIVATE(QMediaRecorder)
|
Q_DECLARE_PRIVATE(QMediaRecorder)
|
||||||
Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))
|
Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))
|
||||||
|
|||||||
91
src/multimedia/recording/qmediarecorder_p.h
Normal file
91
src/multimedia/recording/qmediarecorder_p.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QMEDIARECORDER_P_H
|
||||||
|
#define QMEDIARECORDER_P_H
|
||||||
|
|
||||||
|
#include "qmediarecorder.h"
|
||||||
|
#include "qmediaobject_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QMediaRecorderControl;
|
||||||
|
class QMediaContainerControl;
|
||||||
|
class QAudioEncoderControl;
|
||||||
|
class QVideoEncoderControl;
|
||||||
|
class QMetaDataWriterControl;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
class QMediaRecorderPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QMediaRecorderPrivate();
|
||||||
|
virtual ~QMediaRecorderPrivate() {}
|
||||||
|
|
||||||
|
QMediaObject *mediaObject;
|
||||||
|
|
||||||
|
QMediaRecorderControl *control;
|
||||||
|
QMediaContainerControl *formatControl;
|
||||||
|
QAudioEncoderControl *audioControl;
|
||||||
|
QVideoEncoderControl *videoControl;
|
||||||
|
QMetaDataWriterControl *metaDataControl;
|
||||||
|
|
||||||
|
QTimer* notifyTimer;
|
||||||
|
|
||||||
|
QMediaRecorder::State state;
|
||||||
|
QMediaRecorder::Error error;
|
||||||
|
QString errorString;
|
||||||
|
|
||||||
|
void _q_stateChanged(QMediaRecorder::State state);
|
||||||
|
void _q_error(int error, const QString &errorString);
|
||||||
|
void _q_serviceDestroyed();
|
||||||
|
void _q_notify();
|
||||||
|
void _q_updateNotifyInterval(int ms);
|
||||||
|
|
||||||
|
QMediaRecorder *q_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
INCLUDEPATH += recording
|
INCLUDEPATH += recording
|
||||||
|
|
||||||
PUBLIC_HEADERS += \
|
PUBLIC_HEADERS += \
|
||||||
recording/qaudiocapturesource.h \
|
recording/qaudiorecorder.h \
|
||||||
recording/qmediaencodersettings.h \
|
recording/qmediaencodersettings.h \
|
||||||
recording/qmediarecorder.h \
|
recording/qmediarecorder.h \
|
||||||
|
|
||||||
|
PRIVATE_HEADERS += \
|
||||||
|
recording/qmediarecorder_p.h \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
recording/qaudiocapturesource.cpp \
|
recording/qaudiorecorder.cpp \
|
||||||
recording/qmediaencodersettings.cpp \
|
recording/qmediaencodersettings.cpp \
|
||||||
recording/qmediarecorder.cpp
|
recording/qmediarecorder.cpp
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ TEMPLATE = subdirs
|
|||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
qabstractvideobuffer \
|
qabstractvideobuffer \
|
||||||
qabstractvideosurface \
|
qabstractvideosurface \
|
||||||
qaudiocapturesource \
|
qaudiorecorder \
|
||||||
qaudioformat \
|
qaudioformat \
|
||||||
qaudionamespace \
|
qaudionamespace \
|
||||||
qcamera \
|
qcamera \
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
CONFIG += testcase
|
|
||||||
TARGET = tst_qaudiocapturesource
|
|
||||||
|
|
||||||
QT += multimedia-private testlib
|
|
||||||
CONFIG += no_private_qt_headers_warning
|
|
||||||
|
|
||||||
SOURCES += tst_qaudiocapturesource.cpp
|
|
||||||
|
|
||||||
include (../qmultimedia_common/mockrecorder.pri)
|
|
||||||
include (../qmultimedia_common/mock.pri)
|
|
||||||
|
|
||||||
10
tests/auto/unit/qaudiorecorder/qaudiorecorder.pro
Normal file
10
tests/auto/unit/qaudiorecorder/qaudiorecorder.pro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CONFIG += testcase no_private_qt_headers_warning
|
||||||
|
TARGET = tst_qaudiorecorder
|
||||||
|
|
||||||
|
QT += multimedia-private testlib
|
||||||
|
|
||||||
|
SOURCES += tst_qaudiorecorder.cpp
|
||||||
|
|
||||||
|
include (../qmultimedia_common/mock.pri)
|
||||||
|
include (../qmultimedia_common/mockrecorder.pri)
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
#include <qaudioformat.h>
|
#include <qaudioformat.h>
|
||||||
|
|
||||||
#include <qaudiocapturesource.h>
|
#include <qaudiorecorder.h>
|
||||||
#include <qaudioencodercontrol.h>
|
#include <qaudioencodercontrol.h>
|
||||||
#include <qmediarecordercontrol.h>
|
#include <qmediarecordercontrol.h>
|
||||||
#include <qaudioendpointselector.h>
|
#include <qaudioendpointselector.h>
|
||||||
@@ -59,13 +59,13 @@
|
|||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
class tst_QAudioCaptureSource: public QObject
|
class tst_QAudioRecorder: public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void initTestCase();
|
void init();
|
||||||
void cleanupTestCase();
|
void cleanup();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
//void testNullService();
|
//void testNullService();
|
||||||
@@ -77,28 +77,29 @@ private slots:
|
|||||||
void testAvailableAudioInputChangedSignal();
|
void testAvailableAudioInputChangedSignal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAudioCaptureSource *audiosource;
|
QAudioRecorder *audiosource;
|
||||||
MockMediaRecorderService *mockMediaRecorderService;
|
MockMediaRecorderService *mockMediaRecorderService;
|
||||||
MockMediaServiceProvider *mockProvider;
|
MockMediaServiceProvider *mockProvider;
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::initTestCase()
|
void tst_QAudioRecorder::init()
|
||||||
{
|
{
|
||||||
mockMediaRecorderService = new MockMediaRecorderService;
|
mockMediaRecorderService = new MockMediaRecorderService(this, new MockMediaRecorderControl(this));
|
||||||
mockProvider = new MockMediaServiceProvider(mockMediaRecorderService);
|
mockProvider = new MockMediaServiceProvider(mockMediaRecorderService);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::cleanupTestCase()
|
void tst_QAudioRecorder::cleanup()
|
||||||
{
|
{
|
||||||
delete audiosource;
|
delete audiosource;
|
||||||
delete mockProvider;
|
delete mockProvider;
|
||||||
audiosource = 0;
|
audiosource = 0;
|
||||||
|
mockProvider = 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void tst_QAudioCaptureSource::testNullService()
|
void tst_QAudioRecorder::testNullService()
|
||||||
{
|
{
|
||||||
MockProvider provider(0);
|
MockProvider provider(0);
|
||||||
QAudioCaptureSource source(0, &provider);
|
QAudioRecorder source(0, &provider);
|
||||||
|
|
||||||
QCOMPARE(source.audioInputs().size(), 0);
|
QCOMPARE(source.audioInputs().size(), 0);
|
||||||
QCOMPARE(source.defaultAudioInput(), QString());
|
QCOMPARE(source.defaultAudioInput(), QString());
|
||||||
@@ -106,12 +107,12 @@ void tst_QAudioCaptureSource::testNullService()
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
void tst_QAudioCaptureSource::testNullControl()
|
void tst_QAudioRecorder::testNullControl()
|
||||||
{
|
{
|
||||||
MockRecorderService service;
|
MockRecorderService service;
|
||||||
service.hasAudioDeviceControl = false;
|
service.hasAudioDeviceControl = false;
|
||||||
MockProvider provider(&service);
|
MockProvider provider(&service);
|
||||||
QAudioCaptureSource source(0, &provider);
|
QAudioRecorder source(0, &provider);
|
||||||
|
|
||||||
QCOMPARE(source.audioInputs().size(), 0);
|
QCOMPARE(source.audioInputs().size(), 0);
|
||||||
QCOMPARE(source.defaultAudioInput(), QString());
|
QCOMPARE(source.defaultAudioInput(), QString());
|
||||||
@@ -125,14 +126,14 @@ void tst_QAudioCaptureSource::testNullControl()
|
|||||||
QCOMPARE(deviceNameSpy.count(), 0);
|
QCOMPARE(deviceNameSpy.count(), 0);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
void tst_QAudioCaptureSource::testAudioSource()
|
void tst_QAudioRecorder::testAudioSource()
|
||||||
{
|
{
|
||||||
audiosource = new QAudioCaptureSource(0, mockProvider);
|
audiosource = new QAudioRecorder(0, mockProvider);
|
||||||
|
|
||||||
QCOMPARE(audiosource->service(),(QMediaService *) mockMediaRecorderService);
|
QCOMPARE(audiosource->mediaObject()->service(),(QMediaService *) mockMediaRecorderService);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::testOptions()
|
void tst_QAudioRecorder::testOptions()
|
||||||
{
|
{
|
||||||
const QString codec(QLatin1String("audio/mpeg"));
|
const QString codec(QLatin1String("audio/mpeg"));
|
||||||
|
|
||||||
@@ -142,45 +143,45 @@ void tst_QAudioCaptureSource::testOptions()
|
|||||||
QVERIFY(mockMediaRecorderService->mockAudioEncoderControl->encodingOption(codec, options.first()).toInt() == 8000);
|
QVERIFY(mockMediaRecorderService->mockAudioEncoderControl->encodingOption(codec, options.first()).toInt() == 8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::testDevices()
|
void tst_QAudioRecorder::testDevices()
|
||||||
{
|
{
|
||||||
audiosource = new QAudioCaptureSource(0,mockProvider);
|
audiosource = new QAudioRecorder(0,mockProvider);
|
||||||
QList<QString> devices = audiosource->audioInputs();
|
QList<QString> devices = audiosource->audioInputs();
|
||||||
QVERIFY(devices.size() > 0);
|
QVERIFY(devices.size() > 0);
|
||||||
QVERIFY(devices.at(0).compare("device1") == 0);
|
QVERIFY(devices.at(0).compare("device1") == 0);
|
||||||
QVERIFY(audiosource->audioDescription("device1").compare("dev1 comment") == 0);
|
QVERIFY(audiosource->audioInputDescription("device1").compare("dev1 comment") == 0);
|
||||||
QVERIFY(audiosource->defaultAudioInput() == "device1");
|
QVERIFY(audiosource->defaultAudioInput() == "device1");
|
||||||
QVERIFY(audiosource->isAvailable() == true);
|
QVERIFY(audiosource->isAvailable() == true);
|
||||||
|
|
||||||
QSignalSpy checkSignal(audiosource, SIGNAL(activeAudioInputChanged(QString)));
|
QSignalSpy checkSignal(audiosource, SIGNAL(audioInputChanged(QString)));
|
||||||
audiosource->setAudioInput("device2");
|
audiosource->setAudioInput("device2");
|
||||||
QVERIFY(audiosource->activeAudioInput().compare("device2") == 0);
|
QVERIFY(audiosource->audioInput().compare("device2") == 0);
|
||||||
QVERIFY(checkSignal.count() == 1);
|
QVERIFY(checkSignal.count() == 1);
|
||||||
QVERIFY(audiosource->isAvailable() == true);
|
QVERIFY(audiosource->isAvailable() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::testAvailability()
|
void tst_QAudioRecorder::testAvailability()
|
||||||
{
|
{
|
||||||
MockMediaRecorderService service;
|
MockMediaRecorderService service(this, new MockMediaRecorderControl(this));
|
||||||
service.hasControls = false;
|
service.hasControls = false;
|
||||||
MockMediaServiceProvider provider(&service);
|
MockMediaServiceProvider provider(&service);
|
||||||
QAudioCaptureSource source(0, &provider);
|
QAudioRecorder source(0, &provider);
|
||||||
|
|
||||||
QVERIFY(source.isAvailable() == false);
|
QVERIFY(source.isAvailable() == false);
|
||||||
QVERIFY(source.availabilityError() == QtMultimedia::ServiceMissingError);
|
QVERIFY(source.availabilityError() == QtMultimedia::ServiceMissingError);
|
||||||
|
|
||||||
service.hasControls = true;
|
service.hasControls = true;
|
||||||
MockMediaServiceProvider provider2(&service);
|
MockMediaServiceProvider provider2(&service);
|
||||||
QAudioCaptureSource source2(0, &provider2);
|
QAudioRecorder source2(0, &provider2);
|
||||||
|
|
||||||
QVERIFY(source2.isAvailable() == true);
|
QVERIFY(source2.isAvailable() == true);
|
||||||
QVERIFY(source2.availabilityError() == QtMultimedia::NoError);
|
QVERIFY(source2.availabilityError() == QtMultimedia::NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAudioCaptureSource::testAvailableAudioInputChangedSignal()
|
void tst_QAudioRecorder::testAvailableAudioInputChangedSignal()
|
||||||
{
|
{
|
||||||
// The availabilityChangedSignal is implemented in QAudioCaptureSource. SO using it to test the signal.
|
// The availabilityChangedSignal is implemented in QAudioRecorder. SO using it to test the signal.
|
||||||
audiosource = new QAudioCaptureSource(0, mockProvider);
|
audiosource = new QAudioRecorder(0, mockProvider);
|
||||||
|
|
||||||
/* Spy the signal availableEndpointChanged and audioInputchanged */
|
/* Spy the signal availableEndpointChanged and audioInputchanged */
|
||||||
QSignalSpy changed(mockMediaRecorderService->mockAudioEndpointSelector, SIGNAL(availableEndpointsChanged()));
|
QSignalSpy changed(mockMediaRecorderService->mockAudioEndpointSelector, SIGNAL(availableEndpointsChanged()));
|
||||||
@@ -199,6 +200,6 @@ void tst_QAudioCaptureSource::testAvailableAudioInputChangedSignal()
|
|||||||
QVERIFY(audioInputchange.count() == 1);
|
QVERIFY(audioInputchange.count() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QAudioCaptureSource)
|
QTEST_GUILESS_MAIN(tst_QAudioRecorder)
|
||||||
|
|
||||||
#include "tst_qaudiocapturesource.moc"
|
#include "tst_qaudiorecorder.moc"
|
||||||
@@ -48,7 +48,6 @@
|
|||||||
#include <qmediaobject.h>
|
#include <qmediaobject.h>
|
||||||
#include <qmediaservice.h>
|
#include <qmediaservice.h>
|
||||||
#include <qmetadatareadercontrol.h>
|
#include <qmetadatareadercontrol.h>
|
||||||
#include <qaudiocapturesource.h>
|
|
||||||
#include <qaudioendpointselector.h>
|
#include <qaudioendpointselector.h>
|
||||||
|
|
||||||
#include "mockmediarecorderservice.h"
|
#include "mockmediarecorderservice.h"
|
||||||
@@ -103,7 +102,6 @@ private slots:
|
|||||||
void extendedMetaData();
|
void extendedMetaData();
|
||||||
|
|
||||||
void service();
|
void service();
|
||||||
void availabilityChangedSignal();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupNotifyTests();
|
void setupNotifyTests();
|
||||||
@@ -474,30 +472,6 @@ void tst_QMediaObject::availability()
|
|||||||
QtTestMediaObject mediaObject2;
|
QtTestMediaObject mediaObject2;
|
||||||
QMediaService *service2 = mediaObject2.service();
|
QMediaService *service2 = mediaObject2.service();
|
||||||
QVERIFY(service2 == NULL);
|
QVERIFY(service2 == NULL);
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QMediaObject::availabilityChangedSignal()
|
|
||||||
{
|
|
||||||
// The availabilityChangedSignal is implemented in QAudioCaptureSource. So using it to test the signal.
|
|
||||||
MockMediaRecorderService *mockAudioSourceService = new MockMediaRecorderService;
|
|
||||||
MockMediaServiceProvider *mockProvider = new MockMediaServiceProvider(mockAudioSourceService);
|
|
||||||
QAudioCaptureSource *audiosource = new QAudioCaptureSource(0, mockProvider);
|
|
||||||
|
|
||||||
QSignalSpy spy(audiosource, SIGNAL(availabilityChanged(bool)));
|
|
||||||
|
|
||||||
// Add the end points and verify if the availablity changed signal emitted with argument true.
|
|
||||||
QMetaObject::invokeMethod(mockAudioSourceService->mockAudioEndpointSelector, "addEndpoints");
|
|
||||||
QVERIFY(spy.count() == 1);
|
|
||||||
bool available = qvariant_cast<bool>(spy.at(0).at(0));
|
|
||||||
QVERIFY(available == true);
|
|
||||||
|
|
||||||
spy.clear();
|
|
||||||
|
|
||||||
// Remove all endpoints and verify if the signal is emitted with argument false.
|
|
||||||
QMetaObject::invokeMethod(mockAudioSourceService->mockAudioEndpointSelector, "removeEndpoints");
|
|
||||||
QVERIFY(spy.count() == 1);
|
|
||||||
available = qvariant_cast<bool>(spy.at(0).at(0));
|
|
||||||
QVERIFY(available == false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(tst_QMediaObject)
|
QTEST_GUILESS_MAIN(tst_QMediaObject)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
#include <qmediaobject.h>
|
#include <qmediaobject.h>
|
||||||
#include <qmediaservice.h>
|
#include <qmediaservice.h>
|
||||||
#include <qmediaplayer.h>
|
#include <qmediaplayer.h>
|
||||||
#include <qaudiocapturesource.h>
|
#include <qaudiorecorder.h>
|
||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
class MockMediaService : public QMediaService
|
class MockMediaService : public QMediaService
|
||||||
|
|||||||
Reference in New Issue
Block a user