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:
Dmytro Poplavskiy
2012-01-18 14:46:58 +10:00
committed by Qt by Nokia
parent 8c74e5e7e7
commit 69cef0c24c
16 changed files with 462 additions and 449 deletions

View File

@@ -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.
To begin, the developer sets up a source and a 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.
To begin, the developer sets up an audio recorder object. A
\l{QAudioRecorder} object is created. The output file name is then set for the \l{QMediaRecorder} object.
\code
audiosource = new QAudioCaptureSource;
capture = new QMediaRecorder(audiosource);
capture->setOutputLocation(QUrl("test.raw"));
audioRecorder = new QAudioRecorder;
audioRecorder->setOutputLocation(QUrl("test.raw"));
\endcode
A list of devices is needed so that an input can be selected in the user interface
\code
for(int i = 0; i < audiosource->deviceCount(); i++)
for (int i = 0; i < audioRecorder->deviceCount(); i++)
deviceBox->addItem(audiosource->name(i));
\endcode
and a list of the supported codecs for the user to select a codec,
\code
QStringList codecs = capture->supportedAudioCodecs();
for(int i = 0; i < codecs.count(); i++)
QStringList codecs = audioRecorder->supportedAudioCodecs();
for (int i = 0; i < codecs.count(); i++)
codecsBox->addItem(codecs.at(i));
\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,
\code
audiosource->setSelectedDevice(i);
audioRecorder->setSelectedDevice(i);
...
capture->setAudioCodec(codecIdx);
audioRecorder->setAudioCodec(codecIdx);
\endcode
Now start recording by using the \l {QMediaRecorder}{record()} function from the new \l{QMediaRecorder} object
\code
capture->record();
audioRecorder->record();
\endcode
And stop recording by calling the matching function \l {QMediaRecorder::stop()}{stop()} in \l{QMediaRecorder}.
\code
capture->stop();
audioRecorder->stop();
\endcode
How then would this audio file be played? The \l {QMediaPlayer} class will be
@@ -228,8 +226,7 @@ the next photo.
\section2 Video Clips
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
QAudioCaptureSource for sound.
video requires the use of a \l QMediaRecorder object.
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.

View File

@@ -41,7 +41,7 @@
#include <QtCore/qdir.h>
#include <QtWidgets/qfiledialog.h>
#include <qaudiocapturesource.h>
#include <qaudiorecorder.h>
#include <qmediarecorder.h>
#include "audiorecorder.h"
@@ -60,30 +60,29 @@ AudioRecorder::AudioRecorder(QWidget *parent)
{
ui->setupUi(this);
audiosource = new QAudioCaptureSource(this);
capture = new QMediaRecorder(audiosource, this);
audioRecorder = new QAudioRecorder(this);
//audio devices
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));
}
//audio codecs
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));
}
//containers
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));
}
//sample rate:
ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
foreach(int sampleRate, capture->supportedAudioSampleRates()) {
foreach (int sampleRate, audioRecorder->supportedAudioSampleRates()) {
ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
sampleRate));
}
@@ -98,23 +97,22 @@ AudioRecorder::AudioRecorder(QWidget *parent)
ui->bitrateBox->addItem(QString("96000"), QVariant(96000));
ui->bitrateBox->addItem(QString("128000"), QVariant(128000));
connect(capture, SIGNAL(durationChanged(qint64)), this,
connect(audioRecorder, SIGNAL(durationChanged(qint64)), this,
SLOT(updateProgress(qint64)));
connect(capture, SIGNAL(stateChanged(QMediaRecorder::State)), this,
connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this,
SLOT(updateState(QMediaRecorder::State)));
connect(capture, SIGNAL(error(QMediaRecorder::Error)), this,
connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this,
SLOT(displayErrorMessage()));
}
AudioRecorder::~AudioRecorder()
{
delete capture;
delete audiosource;
delete audioRecorder;
}
void AudioRecorder::updateProgress(qint64 duration)
{
if (capture->error() != QMediaRecorder::NoError || duration < 2000)
if (audioRecorder->error() != QMediaRecorder::NoError || duration < 2000)
return;
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
@@ -128,11 +126,11 @@ void AudioRecorder::updateState(QMediaRecorder::State state)
case QMediaRecorder::RecordingState:
ui->recordButton->setText(tr("Stop"));
ui->pauseButton->setText(tr("Pause"));
if (capture->outputLocation().isEmpty())
if (audioRecorder->outputLocation().isEmpty())
statusMessage = tr("Recording");
else
statusMessage = tr("Recording to %1").arg(
capture->outputLocation().toString());
audioRecorder->outputLocation().toString());
break;
case QMediaRecorder::PausedState:
ui->recordButton->setText(tr("Stop"));
@@ -147,7 +145,7 @@ void AudioRecorder::updateState(QMediaRecorder::State state)
ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState);
if (capture->error() == QMediaRecorder::NoError)
if (audioRecorder->error() == QMediaRecorder::NoError)
ui->statusbar->showMessage(statusMessage);
}
@@ -162,11 +160,11 @@ static QVariant boxValue(const QComboBox *box)
void AudioRecorder::toggleRecord()
{
if (capture->state() == QMediaRecorder::StoppedState) {
audiosource->setAudioInput(boxValue(ui->audioDeviceBox).toString());
if (audioRecorder->state() == QMediaRecorder::StoppedState) {
audioRecorder->setAudioInput(boxValue(ui->audioDeviceBox).toString());
if (!outputLocationSet)
capture->setOutputLocation(generateAudioFilePath());
audioRecorder->setOutputLocation(generateAudioFilePath());
QAudioEncoderSettings settings;
settings.setCodec(boxValue(ui->audioCodecBox).toString());
@@ -179,32 +177,32 @@ void AudioRecorder::toggleRecord()
QString container = boxValue(ui->containerBox).toString();
capture->setEncodingSettings(settings, QVideoEncoderSettings(), container);
capture->record();
audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
audioRecorder->record();
}
else {
capture->stop();
audioRecorder->stop();
}
}
void AudioRecorder::togglePause()
{
if (capture->state() != QMediaRecorder::PausedState)
capture->pause();
if (audioRecorder->state() != QMediaRecorder::PausedState)
audioRecorder->pause();
else
capture->record();
audioRecorder->record();
}
void AudioRecorder::setOutputLocation()
{
QString fileName = QFileDialog::getSaveFileName();
capture->setOutputLocation(QUrl(fileName));
audioRecorder->setOutputLocation(QUrl(fileName));
outputLocationSet = true;
}
void AudioRecorder::displayErrorMessage()
{
ui->statusbar->showMessage(capture->errorString());
ui->statusbar->showMessage(audioRecorder->errorString());
}
QUrl AudioRecorder::generateAudioFilePath()

View File

@@ -53,7 +53,7 @@ namespace Ui {
class AudioRecorder;
}
class QAudioCaptureSource;
class QAudioRecorder;
QT_END_NAMESPACE
QT_USE_NAMESPACE
@@ -78,8 +78,7 @@ private slots:
private:
Ui::AudioRecorder *ui;
QAudioCaptureSource* audiosource;
QMediaRecorder* capture;
QAudioRecorder* audioRecorder;
QAudioEncoderSettings audioSettings;
bool outputLocationSet;

View File

@@ -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

View 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

View File

@@ -39,21 +39,15 @@
**
****************************************************************************/
#ifndef QAUDIOCAPTURESOURCE_H
#define QAUDIOCAPTURESOURCE_H
#ifndef QAUDIORECORDER_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/qsize.h>
#include <qaudioformat.h>
#include "qmediarecorder.h"
#include "qmediacontrol.h"
#include "qmediaobject.h"
#include "qmediaservice.h"
#include "qmediaserviceprovider.h"
QT_BEGIN_HEADER
@@ -61,43 +55,42 @@ QT_BEGIN_NAMESPACE
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_PROPERTY(QString audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
public:
QAudioCaptureSource(QObject *parent = 0, QMediaServiceProvider *service = QMediaServiceProvider::defaultServiceProvider());
~QAudioCaptureSource();
QAudioRecorder(QObject *parent = 0, QMediaServiceProvider *serviceProvider = QMediaServiceProvider::defaultServiceProvider());
~QAudioRecorder();
bool isAvailable() const;
QtMultimedia::AvailabilityError availabilityError() const;
QList<QString> audioInputs() const;
QString audioDescription(const QString& name) const;
QStringList audioInputs() const;
QString defaultAudioInput() const;
QString activeAudioInput() const;
QString audioInputDescription(const QString& name) const;
QString audioInput() const;
public Q_SLOTS:
void setAudioInput(const QString& name);
Q_SIGNALS:
void activeAudioInputChanged(const QString& name);
void audioInputChanged(const QString& name);
void availableAudioInputsChanged();
private Q_SLOTS:
void statusChanged();
private:
Q_DECLARE_PRIVATE(QAudioCaptureSource)
Q_DISABLE_COPY(QAudioRecorder)
Q_DECLARE_PRIVATE(QAudioRecorder)
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QAUDIOCAPTURESOURCE_H
#endif // QAUDIORECORDER_H

View File

@@ -40,6 +40,7 @@
****************************************************************************/
#include "qmediarecorder.h"
#include "qmediarecorder_p.h"
#include <qmediarecordercontrol.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
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
\sa QAudioCaptureSource
\sa QAudioRecorder
*/
namespace
@@ -91,37 +92,6 @@ public:
} _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():
mediaObject(0),
control(0),
@@ -198,12 +168,27 @@ QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
{
Q_D(QMediaRecorder);
d->q_ptr = this;
setMediaObject(mediaObject);
d->notifyTimer = new QTimer(this);
d->notifyTimer->setInterval(mediaObject->notifyInterval());
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)));
}
disconnect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), this, SLOT(_q_updateNotifyInterval(int)));
QMediaService *service = d->mediaObject->service();
if (service) {
@@ -285,6 +272,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object)
if (d->mediaObject) {
QMediaService *service = d->mediaObject->service();
d->notifyTimer->setInterval(d->mediaObject->notifyInterval());
connect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int)));
if (service) {
d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid));

View File

@@ -171,10 +171,11 @@ Q_SIGNALS:
void metaDataChanged();
protected:
QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent = 0);
bool setMediaObject(QMediaObject *object);
private:
QMediaRecorderPrivate *d_ptr;
private:
Q_DISABLE_COPY(QMediaRecorder)
Q_DECLARE_PRIVATE(QMediaRecorder)
Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))

View 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

View File

@@ -1,11 +1,14 @@
INCLUDEPATH += recording
PUBLIC_HEADERS += \
recording/qaudiocapturesource.h \
recording/qaudiorecorder.h \
recording/qmediaencodersettings.h \
recording/qmediarecorder.h \
PRIVATE_HEADERS += \
recording/qmediarecorder_p.h \
SOURCES += \
recording/qaudiocapturesource.cpp \
recording/qaudiorecorder.cpp \
recording/qmediaencodersettings.cpp \
recording/qmediarecorder.cpp

View File

@@ -3,7 +3,7 @@ TEMPLATE = subdirs
SUBDIRS += \
qabstractvideobuffer \
qabstractvideosurface \
qaudiocapturesource \
qaudiorecorder \
qaudioformat \
qaudionamespace \
qcamera \

View File

@@ -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)

View 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)

View File

@@ -44,7 +44,7 @@
#include <qaudioformat.h>
#include <qaudiocapturesource.h>
#include <qaudiorecorder.h>
#include <qaudioencodercontrol.h>
#include <qmediarecordercontrol.h>
#include <qaudioendpointselector.h>
@@ -59,13 +59,13 @@
QT_USE_NAMESPACE
class tst_QAudioCaptureSource: public QObject
class tst_QAudioRecorder: public QObject
{
Q_OBJECT
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
//void testNullService();
@@ -77,28 +77,29 @@ private slots:
void testAvailableAudioInputChangedSignal();
private:
QAudioCaptureSource *audiosource;
QAudioRecorder *audiosource;
MockMediaRecorderService *mockMediaRecorderService;
MockMediaServiceProvider *mockProvider;
};
void tst_QAudioCaptureSource::initTestCase()
void tst_QAudioRecorder::init()
{
mockMediaRecorderService = new MockMediaRecorderService;
mockMediaRecorderService = new MockMediaRecorderService(this, new MockMediaRecorderControl(this));
mockProvider = new MockMediaServiceProvider(mockMediaRecorderService);
}
void tst_QAudioCaptureSource::cleanupTestCase()
void tst_QAudioRecorder::cleanup()
{
delete audiosource;
delete mockProvider;
audiosource = 0;
mockProvider = 0;
}
/*
void tst_QAudioCaptureSource::testNullService()
void tst_QAudioRecorder::testNullService()
{
MockProvider provider(0);
QAudioCaptureSource source(0, &provider);
QAudioRecorder source(0, &provider);
QCOMPARE(source.audioInputs().size(), 0);
QCOMPARE(source.defaultAudioInput(), QString());
@@ -106,12 +107,12 @@ void tst_QAudioCaptureSource::testNullService()
}
*/
/*
void tst_QAudioCaptureSource::testNullControl()
void tst_QAudioRecorder::testNullControl()
{
MockRecorderService service;
service.hasAudioDeviceControl = false;
MockProvider provider(&service);
QAudioCaptureSource source(0, &provider);
QAudioRecorder source(0, &provider);
QCOMPARE(source.audioInputs().size(), 0);
QCOMPARE(source.defaultAudioInput(), QString());
@@ -125,14 +126,14 @@ void tst_QAudioCaptureSource::testNullControl()
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"));
@@ -142,45 +143,45 @@ void tst_QAudioCaptureSource::testOptions()
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();
QVERIFY(devices.size() > 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->isAvailable() == true);
QSignalSpy checkSignal(audiosource, SIGNAL(activeAudioInputChanged(QString)));
QSignalSpy checkSignal(audiosource, SIGNAL(audioInputChanged(QString)));
audiosource->setAudioInput("device2");
QVERIFY(audiosource->activeAudioInput().compare("device2") == 0);
QVERIFY(audiosource->audioInput().compare("device2") == 0);
QVERIFY(checkSignal.count() == 1);
QVERIFY(audiosource->isAvailable() == true);
}
void tst_QAudioCaptureSource::testAvailability()
void tst_QAudioRecorder::testAvailability()
{
MockMediaRecorderService service;
MockMediaRecorderService service(this, new MockMediaRecorderControl(this));
service.hasControls = false;
MockMediaServiceProvider provider(&service);
QAudioCaptureSource source(0, &provider);
QAudioRecorder source(0, &provider);
QVERIFY(source.isAvailable() == false);
QVERIFY(source.availabilityError() == QtMultimedia::ServiceMissingError);
service.hasControls = true;
MockMediaServiceProvider provider2(&service);
QAudioCaptureSource source2(0, &provider2);
QAudioRecorder source2(0, &provider2);
QVERIFY(source2.isAvailable() == true);
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.
audiosource = new QAudioCaptureSource(0, mockProvider);
// The availabilityChangedSignal is implemented in QAudioRecorder. SO using it to test the signal.
audiosource = new QAudioRecorder(0, mockProvider);
/* Spy the signal availableEndpointChanged and audioInputchanged */
QSignalSpy changed(mockMediaRecorderService->mockAudioEndpointSelector, SIGNAL(availableEndpointsChanged()));
@@ -199,6 +200,6 @@ void tst_QAudioCaptureSource::testAvailableAudioInputChangedSignal()
QVERIFY(audioInputchange.count() == 1);
}
QTEST_MAIN(tst_QAudioCaptureSource)
QTEST_GUILESS_MAIN(tst_QAudioRecorder)
#include "tst_qaudiocapturesource.moc"
#include "tst_qaudiorecorder.moc"

View File

@@ -48,7 +48,6 @@
#include <qmediaobject.h>
#include <qmediaservice.h>
#include <qmetadatareadercontrol.h>
#include <qaudiocapturesource.h>
#include <qaudioendpointselector.h>
#include "mockmediarecorderservice.h"
@@ -103,7 +102,6 @@ private slots:
void extendedMetaData();
void service();
void availabilityChangedSignal();
private:
void setupNotifyTests();
@@ -474,30 +472,6 @@ void tst_QMediaObject::availability()
QtTestMediaObject mediaObject2;
QMediaService *service2 = mediaObject2.service();
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)

View File

@@ -51,7 +51,7 @@
#include <qmediaobject.h>
#include <qmediaservice.h>
#include <qmediaplayer.h>
#include <qaudiocapturesource.h>
#include <qaudiorecorder.h>
QT_USE_NAMESPACE
class MockMediaService : public QMediaService