目录
引言
在数字时代,音频处理成为多媒体应用、实时通信和娱乐产业中不可或缺的一部分。Qt作为一种跨平台的C++应用程序开发框架,提供了强大的多媒体处理能力,特别是其QtMultimedia模块,为开发者提供了丰富的API来处理音频和视频。本文将详细介绍QT音频基础知识,特别是QtMultimedia模块的使用及相关函数解析。
一、QtMultimedia模块简介
QtMultimedia模块是Qt库中的一个重要模块,专门用于处理多媒体内容,如音频和视频。它提供了一组丰富的QML类型和C++类,支持音频和视频的采集、播放、录制和处理。QtMultimedia模块不仅支持基本的音频和视频播放,还提供了编解码、格式转换等高级功能。
cpp
// 在.pro文件中加入模块
QT += multimedia
主要类和功能
- QAudioInput:用于音频数据的采集。开发者可以通过这个类从麦克风等音频输入设备获取原始音频数据。
- QAudioOutput:用于音频数据的播放。它允许开发者将音频数据输出到扬声器等音频输出设备。
- QAudioFormat:用于定义音频数据的格式,包括采样率、样本大小、声道数等关键参数。
- QMediaPlayer:提供音频和视频文件的播放功能,支持多种媒体格式,如MP3、WAV、AVI、MP4等。
- QMediaPlaylist:允许开发者创建、编辑和播放一个包含多个媒体文件(如音频或视频)的列表。可以轻松地实现连续播放、随机播放或单曲循环等。
- QCamera:虽然主要用于视频处理,但也涉及音频采集,特别是与视频同步的音频数据。
二、QtMultimedia相关类及函数解析
QAudioInput
功能 :
QAudioInput类用于音频数据的采集。它提供了一个接口,允许开发者从音频输入设备(如麦克风)获取原始音频数据。
主要方法和属性:
start()
:开始音频数据的采集。stop()
:停止音频数据的采集。bytesReady()
:返回缓冲区中可读的字节数。read()
:从缓冲区读取音频数据。notify()
:设置当有新数据可读时发出的通知。
QAudioOutput
功能 :
QAudioOutput类用于音频数据的播放。它允许开发者将音频数据输出到音频输出设备(如扬声器)。
主要方法和属性:
start()
:开始音频数据的播放。stop()
:停止音频数据的播放。write()
:将音频数据写入播放缓冲区。bytesFree()
:返回播放缓冲区中可用的字节数。periodSize()
:返回播放缓冲区的周期大小。
QAudioFormat
功能 :
QAudioFormat类用于定义音频数据的格式。它包含了采样率、样本大小、声道数等关键参数,用于描述音频数据的属性。
主要方法和属性:
setSampleRate()
:设置采样率。setChannelCount()
:设置通道数。setSampleSize()
:设置样本大小。setCodec()
:设置音频编码器。setByteOrder()
:设置字节序。setSampleType()
:设置样本类型(如有符号整数、无符号整数、浮点数等)。
QMediaPlayer
功能 :
QMediaPlayer类提供音频和视频文件的播放功能。它支持多种媒体格式,如MP3、WAV、AVI、MP4等,并提供了丰富的API来控制媒体的播放。
主要方法和属性:
setMedia()
:设置要播放的媒体文件或媒体内容。play()
:开始播放媒体。pause()
:暂停播放媒体。stop()
:停止播放媒体。volume()
:获取或设置播放音量。position()
:获取当前播放位置。duration()
:获取媒体的总时长。
QMediaPlaylist
功能 :
QMediaPlaylist
类提供了一个管理媒体播放列表的接口。它允许开发者创建、编辑和播放一个包含多个媒体文件(如音频或视频)的列表。通过QMediaPlaylist
,可以轻松地实现连续播放、随机播放或单曲循环等功能。
主要方法和属性:
-
addMedia(const QMediaContent &content)
:向播放列表中添加一个媒体文件。QMediaContent
是一个包含媒体文件位置(如URL或文件路径)和其他相关信息的类。 -
insertMedia(int index, const QMediaContent &content)
:在播放列表的指定位置插入一个媒体文件。 -
removeMedia(int index)
:从播放列表中移除指定位置的媒体文件。 -
moveMedia(int from, int to)
:在播放列表中移动媒体文件的位置。 -
clear()
:清空播放列表中的所有媒体文件。 -
setCurrentIndex(int index)
:设置当前播放的媒体文件在播放列表中的索引。 -
currentIndex()
:获取当前播放的媒体文件在播放列表中的索引。 -
playbackMode()
:获取播放列表的播放模式,如顺序播放、随机播放或单曲循环。 -
setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
:设置播放列表的播放模式。 -
mediaCount()
:获取播放列表中的媒体文件数量。 -
media(int index)
:获取播放列表中指定位置的媒体文件信息。 -
next()
:播放下一个媒体文件。 -
previous()
:播放上一个媒体文件。
QCamera
功能 :
QCamera类主要用于视频处理,但也涉及音频采集,特别是与视频同步的音频数据。它提供了访问和控制相机设备的接口。
主要方法和属性(与音频相关):
start()
:开始相机的预览或捕获会话,这可能包括音频采集。stop()
:停止相机的预览或捕获会话。audioRecorder()
:获取与相机关联的音频录制器对象,用于控制音频的录制。setAudioEncoderSettings()
:设置音频编码器的参数。
三、音频项目实战Demo
UI界面
核心代码
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QFileDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QMediaPlayer *player;
QMediaPlaylist *playlist;
QString drtTime; // 播放时长
QString pstTime; // 播放位置
private slots:
void onstatechanged(QMediaPlayer::State state); // 按钮切换状态
void onplaylistchanged(int pos); // 播放列表
void ondrtchanged(qint64 drt); // 歌曲总时长
void onpstchanged(qint64 pos); // 播放歌曲当前位置
void on_pushButton_open_clicked();
void on_pushButton_play_clicked();
void on_pushButton_pause_clicked();
void on_pushButton_stop_clicked();
void on_pushButton_pre_clicked();
void on_pushButton_next_clicked();
void on_pushButton_volumn_clicked();
void on_horizontalSlider_volumn_valueChanged(int value);
void on_horizontalSlider_speed_valueChanged(int value);
};
#endif // MAINWINDOW_H
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
playlist = new QMediaPlaylist(this);
playlist->setPlaybackMode(QMediaPlaylist::Loop); // 循环播放
player->setPlaylist(playlist);
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(onstatechanged(QMediaPlayer::State)));
connect(player, SIGNAL(positionChanged(qint64)),this,SLOT(onpstchanged(qint64)));
connect(player, SIGNAL(durationChanged(qint64)),this,SLOT(ondrtchanged(qint64)));
connect(playlist,SIGNAL(currentIndexChanged(int)),this,SLOT(onplaylistchanged(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onstatechanged(QMediaPlayer::State state) // 按钮切换状态
{
ui->pushButton_play->setEnabled(!(state==QMediaPlayer::PlayingState));
ui->pushButton_pause->setEnabled(state==QMediaPlayer::PlayingState);
ui->pushButton_stop->setEnabled(state==QMediaPlayer::PlayingState);
}
void MainWindow::onplaylistchanged(int pos) // 播放列表
{
ui->listWidget->setCurrentRow(pos);
QListWidgetItem *item = ui->listWidget->currentItem();
if(item)
{
ui->label_name->setText(item->text());
}
}
void MainWindow::ondrtchanged(qint64 drt) // 歌曲总时长、更新变化
{
ui->horizontalSlider_speed->setMaximum(drt);
int sec = drt/1000; //总秒
int min = sec/60; //分
sec = sec%60; //余秒
drtTime = QString::asprintf("%02d:%02d",min,sec);
ui->label_time->setText(drtTime);
}
void MainWindow::onpstchanged(qint64 pos) // 播放歌曲当前位置
{
if(ui->horizontalSlider_speed->isSliderDown())
return;
ui->horizontalSlider_speed->setSliderPosition(pos);
int sec = pos/1000; //总秒
int min = sec/60; //分
sec = sec%60; //余秒
pstTime = QString::asprintf("%02d:%02d",min,sec);
ui->label_speed->setText(pstTime);
}
void MainWindow::on_pushButton_open_clicked()
{
// 添加歌曲文件
QString currentpath = QDir::currentPath();
QString dlgtitle = "请选择音频文件";
QString strfilter = "所有文件(*.*);;音频文件(*.mp3 *.wav);;mp3文件(*.mp3);;wav文件(*.wav)";
QStringList filelist = QFileDialog::getOpenFileNames(this,dlgtitle,currentpath,strfilter);
if(filelist.count() < 1)
return;
for (int i = 0; i < filelist.count(); ++i) {
QString afile = filelist.at(i);
playlist->addMedia(QUrl::fromLocalFile(afile)); // 添加文件
QFileInfo fileinfo(afile); // 获取文件信息
ui->listWidget->addItem("正在播放:"+fileinfo.fileName()); // 将文件名称添加到listwidget控件上
if(player->state() != QMediaPlayer::PlayingState)
playlist->setCurrentIndex(0); // 默认添加进来第一首播放
player->play();
}
}
void MainWindow::on_pushButton_play_clicked()
{
if(playlist->currentIndex() < 0) // 没选择歌曲默认播放第一首歌
playlist->setCurrentIndex(0);
player->play();
}
void MainWindow::on_pushButton_pause_clicked()
{
player->pause();
}
void MainWindow::on_pushButton_stop_clicked()
{
player->stop();
}
void MainWindow::on_pushButton_pre_clicked()
{
playlist->previous();
}
void MainWindow::on_pushButton_next_clicked()
{
playlist->next();
}
void MainWindow::on_pushButton_volumn_clicked()
{
// 控制静音状态
bool mutex = player->isMuted();
player->setMuted(!mutex);
if(mutex)
{
ui->pushButton_volumn->setIcon(QIcon(":/images/1.PNG"));
}
else
ui->pushButton_volumn->setIcon(QIcon(":/images/2.PNG"));
}
void MainWindow::on_horizontalSlider_volumn_valueChanged(int value)
{
player->setVolume(value);
}
void MainWindow::on_horizontalSlider_speed_valueChanged(int value)
{
player->setPosition(value);
}
运行结果
经过测试后,按钮暂停,停止,上一曲,下一曲和静音,音量和进度条等功能都可以实现。
四、结论
QtMultimedia模块为开发者提供了强大的音频处理能力,通过QAudioInput、QAudioOutput等类,可以轻松实现音频的采集、播放和处理。了解音频处理的基础概念和QtMultimedia模块的使用,对于开发多媒体应用程序至关重要。希望本文能为开发者们提供一些有用的参考和帮助。