如何在Ubuntu QML應用中進行語言錄音,ubuntuqml
在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.0import Ubuntu.Components 1.1import QtMultimedia 5.0import 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