在QML API中,目前并没有一个相应的API来进行录音。我们必须使用Qt C++ API QAudioRecorder来进行录音的工作。在这篇文章中,我们来介绍如何使用这个API来进行录音。
首先,我们来创建一个“QML App with C++ plugin (qmake)”模版的应用。注意qmake的项目必须是在15.04及以上的target上才可以运行。
为了录音,我创建了一个叫做“AudioRecorder”的类:
audiorecorder.h
#ifndef AUDIORECORDER_H
#define AUDIORECORDER_H
#include <QAudioRecorder>
#include <QUrl>
class AudioRecorder : public QObject
{
Q_OBJECT
Q_PROPERTY ( bool recording READ recording NOTIFY recordingChanged )
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
explicit AudioRecorder(QObject *parent = 0);
const bool recording() const;
QString name() const;
Q_INVOKABLE QStringList supportedAudioCodecs();
Q_INVOKABLE QStringList supportedContainers();
Q_INVOKABLE QUrl path() {
return m_path;
}
signals:
void recordingChanged(bool);
void nameChanged(QUrl);
public slots:
void setName(QString name);
void setRecording(bool recording );
void record();
void stop();
private:
QString getFilePath(const QString filename) const;
private:
QAudioRecorder * m_audioRecorder;
bool m_recording;
QString m_name;
QUrl m_path;
};
#endif // AUDIORECORDER_H
audiorecorder.cpp
#include <QUrl>
#include <QStandardPaths>
#include <QDir>
#include "audiorecorder.h"
AudioRecorder::AudioRecorder(QObject *parent) : QObject(parent)
{
m_audioRecorder = new QAudioRecorder( this );
QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/PCM");
audioSettings.setQuality(QMultimedia::HighQuality);
m_audioRecorder->setEncodingSettings(audioSettings);
// https://forum.qt.io/topic/42541/recording-audio-using-qtaudiorecorder/2
m_audioRecorder->setContainerFormat("wav");
m_recording = false;
}
const bool AudioRecorder::recording() const
{
return m_recording;
}
void AudioRecorder::setRecording(bool recording ) {
if (m_recording == recording)
return;
m_recording = recording;
emit recordingChanged(m_recording);
}
void AudioRecorder::record()
{
qDebug() << "Entering record!";
if ( m_audioRecorder->state() == QMediaRecorder::StoppedState ) {
qDebug() << "recording....! ";
m_audioRecorder->record ( );
m_recording = true;
qDebug() << "m_recording: " << m_recording;
emit recordingChanged(m_recording);
}
}
void AudioRecorder::stop()
{
qDebug() << "Entering stop!";
if ( m_audioRecorder->state() == QMediaRecorder::RecordingState ) {
qDebug() << "Stopping....";
m_audioRecorder->stop();
m_recording = false;
emit recordingChanged(m_recording);
}
}
QString AudioRecorder::name() const
{
return m_name;
}
void AudioRecorder::setName(QString name)
{
if (m_name == name)
return;
m_name = name;
emit nameChanged(name);
// at the same time update the path
m_path = QUrl(getFilePath(name));
// set the path
m_audioRecorder->setOutputLocation(m_path);
}
QStringList AudioRecorder::supportedAudioCodecs() {
return m_audioRecorder->supportedAudioCodecs();
}
QStringList AudioRecorder::supportedContainers() {
return m_audioRecorder->supportedContainers();
}
QString AudioRecorder::getFilePath(const QString filename) const
{
QString writablePath = QStandardPaths::
writableLocation(QStandardPaths::DataLocation);
qDebug() << "writablePath: " << writablePath;
QString absolutePath = QDir(writablePath).absolutePath();
qDebug() << "absoluePath: " << absolutePath;
// We need to make sure we have the path for storage
QDir dir(absolutePath);
if ( dir.mkdir(absolutePath) ) {
qDebug() << "Successfully created the path!";
}
QString path = absolutePath + "/" + filename;
qDebug() << "path: " << path;
return path;
}
在这里,我们使用了QStandardPath来获得在Ubuntu手机中可以访问的文件目录。这个QAudioRecorder的API的使用也是非常直接的。
我们的Main.qml的界面也非常简单:
Main.qml
import QtQuick 2.0
import Ubuntu.Components 1.1
import QtMultimedia 5.0
import AudioRecorder 1.0
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "audiorecorder.liu-xiao-guo"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(85)
Page {
title: i18n.tr("AudioRecorder")
AudioRecorder {
id: audio
name: "sample.wav"
onRecordingChanged: {
console.log("recording: " + recording);
}
}
MediaPlayer {
id: player
autoPlay: true
volume: 1.0
}
Column {
anchors.fill: parent
spacing: units.gu(1)
Label {
text: "Supported Audio codecs:"
}
ListView {
id: audiocodecs
width: parent.width
height: audiocodecs.contentHeight
model:audio.supportedAudioCodecs()
delegate: Text {
text: modelData
}
}
Rectangle {
width: parent.width
height: units.gu(0.1)
}
Label {
text: "Supported Containers:"
}
ListView {
id: audiocontainer
width: parent.width
height: audiocontainer.contentHeight
model:audio.supportedContainers()
delegate: Text {
text: modelData
}
}
}
Row {
anchors.bottom: parent.bottom
anchors.bottomMargin: units.gu(2)
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: units.gu(2)
spacing: units.gu(2)
Button {
id: record
text: "Record Audio"
enabled: !audio.recording
onClicked: {
audio.record();
}
}
Button {
id: stop
text: "Stop"
onClicked: {
audio.stop();
player.stop();
}
}
Button {
id: play
text: "Play Audio"
onClicked: {
console.log("path: " + audio.path() );
player.source = audio.path();
player.play();
}
}
}
}
}
在QML中,我们直接地使用:
AudioRecorder {
id: audio
name: "sample.wav"
onRecordingChanged: {
console.log("recording: " + recording);
}
}
我们可以通过“Record Audio”按钮来进行录音的工作。应用的界面如下:
经过在手机上的实验,录音的效果非常好,非常清晰。我们可以使用“Play Audio”按钮来播放。
整个项目的源在: git clone https://gitcafe.com/ubuntu/audiorecorder.git
如何在QML应用中在触屏的时候感知触觉:http://www.linuxdiyf.com/linux/12271.html
如何在qmake项目中在QML语言中调用C++代码:http://www.linuxdiyf.com/linux/12105.html
安装Linux录音软件Record Audio:http://www.linuxdiyf.com/linux/5873.html
Sony X在Ubuntu下不能录音的解决方法:http://www.linuxdiyf.com/linux/9603.html
Skype 2.1在Fedora 14 x64位下录音不正常:http://www.linuxdiyf.com/linux/7549.html