如何在Ubuntu QML应用中进行语言录音
2015-05-29 13:07
671 查看
在QML API中,目前并没有一个相应的API来进行录音。我们必须使用Qt C++ API
QAudioRecorder来进行录音的工作。在这篇文章中,我们来介绍如何使用这个API来进行录音。
首先,我们来创建一个“QML App with C++ plugin (qmake)”模版的应用。注意qmake的项目必须是在15.04及以上的target上才可以运行。
为了录音,我创建了一个叫做“AudioRecorder”的类:
在这里,我们使用了QStandardPath来获得在Ubuntu手机中可以访问的文件目录。这个QAudioRecorder的API的使用也是非常直接的。
我们的Main.qml的界面也非常简单:
在QML中,我们直接地使用:
我们可以通过“Record Audio”按钮来进行录音的工作。应用的界面如下:
经过在手机上的实验,录音的效果非常好,非常清晰。我们可以使用“Play Audio”按钮来播放。
整个项目的源在: https://github.com/liu-xiao-guo/audiorecorder
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”按钮来播放。
整个项目的源在: https://github.com/liu-xiao-guo/audiorecorder
相关文章推荐
- Yahoo的mysql性能监控snmp服务设定
- Android-framework
- android布局分析工具
- java值传递思考
- 03.windows系统重新分配ip的cmd命令
- 利用kaptcha生成验证码的详细教程
- Android必知必会--使用shape制作drawable素材
- Django笔记(1)
- 加加减减有副作用, C/C++er 请小心
- Android必知必会--使用shape制作drawable素材
- Smart SVN-使用Smart SVN 管理Xcode项目文件
- `cocos2dx非完整` 游戏架构缩影 添加启动流程
- Excel 中使用SQL 语句查询数据(六)-----IN 语句的应用
- python之类
- Swift开发教程--UITextField输入框如何隐藏软键盘
- Elasticsearch 分片交互过程分析
- WebService如何传递HashTable
- scala 实习插入排序(Insert_sort)
- 知其然,也要知其所以然,《CS: APP--深入理解计算机系统(原书第2版)》 书评
- WebRequest.GetSystemWebProxy()的效能问题