当前位置: 首页 > news >正文

QT多媒体编程(一)——音频编程知识详解及MP3音频播放器Demo

目录

引言

一、QtMultimedia模块简介

主要类和功能

二、QtMultimedia相关类及函数解析

QAudioInput

QAudioOutput

QAudioFormat

QMediaPlayer

QMediaPlaylist

QCamera

三、音频项目实战Demo

UI界面

核心代码

运行结果

四、结论


引言

在数字时代,音频处理成为多媒体应用、实时通信和娱乐产业中不可或缺的一部分。Qt作为一种跨平台的C++应用程序开发框架,提供了强大的多媒体处理能力,特别是其QtMultimedia模块,为开发者提供了丰富的API来处理音频和视频。本文将详细介绍QT音频基础知识,特别是QtMultimedia模块的使用及相关函数解析。

一、QtMultimedia模块简介

QtMultimedia模块是Qt库中的一个重要模块,专门用于处理多媒体内容,如音频和视频。它提供了一组丰富的QML类型和C++类,支持音频和视频的采集、播放、录制和处理。QtMultimedia模块不仅支持基本的音频和视频播放,还提供了编解码、格式转换等高级功能。

// 在.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界面

核心代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QFileDialog>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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
#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"));}elseui->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模块的使用,对于开发多媒体应用程序至关重要。希望本文能为开发者们提供一些有用的参考和帮助。

传送门:QT多媒体编程(二)——视频编程知识详解及mp4视频播放器Demo

相关文章:

QT多媒体编程(一)——音频编程知识详解及MP3音频播放器Demo

目录 引言 一、QtMultimedia模块简介 主要类和功能 二、QtMultimedia相关类及函数解析 QAudioInput QAudioOutput QAudioFormat QMediaPlayer QMediaPlaylist QCamera 三、音频项目实战Demo UI界面 核心代码 运行结果 四、结论 引言 在数字时代&#xff0c;音频…...

MySQL使用教程 最最最实用的零基础教程 直接从安装开始教!!!!

数据构成了我们日益数字化的社会基础。想象一下&#xff0c;从移动应用和银行系统到搜索引擎&#xff0c;再到如 ChatGPT 这样的先进人工智能聊天机器人&#xff0c;这些工具若没有数据支撑&#xff0c;将寸步难行。你有没有好奇过这些海量数据都存放在哪里呢&#xff1f;答案正…...

pycharm怎么使用Anaconda和配置

打开Anaconda Prompt 要删除 Conda 环境 yolov5sconda&#xff0c;你可以使用以下命令&#xff1a; conda remove --name yolov5sconda --all这个命令会删除名为 yolov5sconda 的整个环境&#xff0c;包括其中安装的所有包和依赖项。请在命令提示符或终端中运行此命令。执行此…...

android中打包apk体积优化方案

1.在配置文件AndroidManifest中新增 android:extractNativeLibs"true" 2.在模块build文件下配置支持的cpu,一般配置64的就行了,多配一种so库体积大一倍&#xff0c;择优。 ndk { abiFilters arm64-v8a } 3.在模块builde文件下配置混淆除去无用的资源文件 注:三种…...

Kubernetes常见的3种部署方式

Kubernetes常见的3种部署方式 1. kubeadm2. 二进制包安装3. Minikube💖The Begin💖点点关注,收藏不迷路💖 Kubernetes(K8s)作为容器编排领域的领导者,提供了多种部署方式以适应不同场景的需求。 1. kubeadm 简介:Kubernetes官方推荐的集群部署工具。特点:简单易用…...

什么情况?我代码没了

前两天检视代码时&#xff0c;发现PR里面有两个提交的描述信息一模一样&#xff0c;于是我提出应该将这两个提交合并成一个&#xff0c;保持提交树的清晰。 1 先储存起来&#xff01; 而同事这时正在开发别的特性&#xff0c;工作区不是干净的&#xff0c;没法直接执行 git r…...

关于Unity四种合批技术详解

文章目录 一.静态合批(StaticBatching)1.启用静态合批2.举例说明3.静态合批的限制4.静态合批的优点缺点5.动态指定物品合批 二.动态合批(Dynamic Batching)1.启用动态合批2.合批规则3.举例说明4.使用限制 三.GPU Instancing1.启用GPU Instancing2.启用限制3.举例说明 四.SRP Ba…...

自定义注解+拦截器+redis限流

逻辑&#xff1a;写一个注解&#xff0c;自定义在多少秒内限制访问多少次。 自定义拦截器&#xff0c;对于加了注解的请求&#xff0c;在执行方法前。先检查有没有注解&#xff0c;如果有注解就将请求的ipurl拼接作为key。 查询redis中有没有该key&#xff0c;没有就存入&…...

Springcloud物流配送后台-计算机毕业设计源码69809

目 录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2 物流配送后台系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.2.2 数据修改流程 2.2.3 数据…...

【Java面试篇】数据埋点监控页面pv的SDK接口实现

面试题如下: 题目要求你实现一个 Monitor.counter(String code, String dim) 接口,用于监控数据统计。 具体要求: 数据聚合: 你需要按照 code 和 dim 的组合进行数据聚合, code 代表监控项的唯一标识, dim 为自定义维度。上报频率: 每分钟上报一次聚合后的数据。数据保证…...

vue3直播视频流easy-player

vue3直播视频流easy-player <script src"/easyPlayer/EasyPlayer-element.min.js"></script> easyPlayer文件下载地址 https://download.csdn.net/download/weixin_42120669/89605739 <template><div class"container"><div …...

Python笔试面试题AI答之面向对象(3)

文章目录 12.Python中OOPS是什么&#xff1f;1. 类&#xff08;Class&#xff09;2. 对象&#xff08;Object&#xff09;3. 面向对象编程的主要特性4. 面向对象编程的优点 13.解释一下Python中的继承&#xff1f;继承的基本语法继承的特性继承的类型 14. 什么是封装&#xff1…...

vulnhub靶场serial-php渗透(蜥蜴细!)

目录 一、信息收集 1.探测主机存活&#xff08;目标主机IP地址&#xff09; 2.访问web服务 3.后台目录和端口扫描 4.解析bak.zip源码 二、漏洞利用 1.构造payload 2.通过bp的repeater模块 3.get shell 4.获取反弹shell 三、提升权限 1. 查看系统版本&#xff0c;内核…...

Qt Designer,仿作一个ui界面的练习(一):界面的基本布局

初学不要太复杂&#xff0c;先做一个结构简单的&#xff0c;大致规划一下功能分区&#xff0c;绘制草图&#xff1a; 最终的效果&#xff1a; 界面主要由顶边栏、侧边栏、内容区构成。顶边栏左边是logo&#xff0c;右边是时钟显示。侧边栏最上边是切换按钮&#xff0c;用以动画…...

《深入了解 Postman 接口测试工具》

在现代 Web 开发中&#xff0c;接口测试是确保系统稳定性和可靠性的关键环节。Postman 作为一款强大的接口测试工具&#xff0c;为开发者和测试人员提供了便捷、高效的测试体验。本文将深入详解 Postman 的各项功能和使用方法。 一、Postman 简介 Postman 是一款功能丰富的 A…...

java使用org.apache.commons:commons-compress解压 .7z压缩包

前言 java使用org.apache.commons:commons-compress解压 .7z压缩包 一、使用步骤 1.引入库 代码如下&#xff08;示例&#xff09;&#xff1a;cpmpress需要用到xz依赖&#xff0c;不一起引入会报错。 <!-- https://mvnrepository.com/artifact/org.tukaani/xz --> …...

通过知识库系统实现卓越医疗保健

提供更好的患者治疗效果&#xff1b;提高医疗保健组织的效率和有效性。 利用 Baklib 的力量 Baklib 使患者、代理人和专业人员能够轻松采用知识库系统。 1.对于患者 通过自助在线知识库提供有关药品、测试、服务、康复等的信息&#xff0c;改善患者体验和健康结果。 2.对于…...

基于C语言从0开始手撸MQTT协议代码连接标准的MQTT服务器,完成数据上传和命令下发响应(华为云IOT服务器)

文章目录 一、前言二、搭建开发环境三、网络编程基础概念科普3.1 什么是网络编程3.2 TCP 和 UDP协议介绍3.3 TCP通信的实现过程 四、Windows下的网络编程相关API介绍4.1 常用的函数介绍4.2 函数参数介绍4.3 编写代码体验网络编程 五、访问华为云IOT服务器创建一个产品和设备5.2…...

程序员面试中的“八股文”:敲门砖还是绊脚石?

在现代技术行业中&#xff0c;“八股文”成为了程序员面试中的常见问题。“八股文”究竟能否在实际工作中发挥应有的作用&#xff0c;成了一个备受争议的话题。许多IT从业者都提出疑问&#xff1a;程序员面试到底考察的是什么&#xff1f;是工作能力、工作经验&#xff0c;还是…...

液位传感器- 从零开始认识各种传感器【二十四期】

液位传感器|从零开始认识各种传感器 1、什么是液位传感器 &#xff1f; 液位传感器是一种用于检测和测量液体位置和高度的装置&#xff0c;广泛应用于工业、农业、环保和家庭等领域。液位传感器可以实时监测液体的水平&#xff0c;以实现自动化控制和安全防护。 2、液位传感器…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...