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

news2024/11/15 21:22:22

目录

引言

一、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_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
#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模块的使用,对于开发多媒体应用程序至关重要。希望本文能为开发者们提供一些有用的参考和帮助。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ArcGIS for js 分屏(vue项目)

一、引入依赖 import {onMounted, ref} from "vue"; import Map from "arcgis/core/Map"; import MapView from "arcgis/core/views/MapView"; import WebTileLayer from "arcgis/core/layers/WebTileLayer"; 二、页面布局 <tem…

22. Hibernate 性能之缓存

1. 前言 本节和大家一起聊聊性能优化方案之&#xff1a;缓存。通过本节学习&#xff0c;你将了解到&#xff1a; 什么是缓存&#xff0c;缓存的作用&#xff1b;HIbernate 中的缓存级别&#xff1b;如何使用缓存。 2. 缓存 2.1 缓存是什么 现实世界里&#xff0c;缓存是一个…

纪念二2024.07 federated-解决mysql跨库联表问题

若需要创建FEDERATED引擎表&#xff0c;则目标端实例要开启FEDERATED引擎。从MySQL5.5开始FEDERATED引擎默认安装 只是没有启用&#xff0c;进入命令行输入 show engines ; FEDERATED行状态为NO。 mysql安装配置文件 一、连接工具查看是否开启federated show engines 二、m…

VMware Workstation17 安装 CentOS7 教程

今天给伙伴们分享一下VMware Workstation17 安装 CentOS7 教程&#xff0c;希望看了有所收获。 我是公众号「想吃西红柿」「云原生运维实战派」作者&#xff0c;对云原生运维感兴趣&#xff0c;也保持时刻学习&#xff0c;后续会分享工作中用到的运维技术&#xff0c;在运维的路…

JS【详解】内存泄漏(含泄漏场景、避免方案、检测方法),垃圾回收 GC (含引用计数、标记清除、标记整理、分代式垃圾回收)

内存泄漏 在执行一个长期运行的应用程序时&#xff0c;应用程序分配的内存没有被释放&#xff0c;导致可用内存逐渐减少&#xff0c;最终可能导致浏览器崩溃或者应用性能严重下降的情况&#xff0c;即 JS 内存泄漏 可能导致内存泄漏的场景 不断创建全局变量未及时清理的闭包&…

Graylog 收集网络设备日志的详细配置指南

需求:网络日志接入到日志服务中,做日志的备份和查询。 交换机或是其它网络设备日志需要接入到graylog日志服务中进行备份和查询。 软件版本 graylog5.1 架构图 一、添加inputs 接受日志信息 二、编辑inputs 配置 第1个红框 title 代表通道的名称,您可以根据需要自由定义…

【CTF-Crypto】格密码基础(例题较多,非常适合入门!)

格密码相关 文章目录 格密码相关格密码基本概念&#xff08;属于后量子密码&#xff09;基础的格运算&#xff08;行列式运算&#xff09;SVP&#xff08;shortest Vector Problem&#xff09;最短向量问题CVP&#xff08;Closet Vector Problem&#xff09;最近向量问题 做题要…

浏览器用户文件夹详解 - ShortCuts(六)

1. Shortcuts简介 1.1 什么是Shortcuts文件&#xff1f; Shortcuts文件是Chromium浏览器中用于存储用户创建的快捷方式信息的一个重要文件。每当用户在浏览器中创建快捷方式时&#xff0c;这些信息都会被记录在Shortcuts文件中。通过这些记录&#xff0c;用户可以方便地快速访…

《小迪安全》学习笔记02

域名默认存放目录和IP默认存放目录不一样。 IP地址是WWW文件里的&#xff0c;域名访问是WWW里的一个子目录里的&#xff08;比如是blog&#xff09;。 Nmap: Web源码拓展 拿到一个网站的源码&#xff0c;要分析这几个方面↑。 不同类型产生的漏洞类型也不一样 在网站中&…

MSPM0G3507_2024电赛自动行驶小车(H题)_问题与感悟

这次电赛题目选的简单了&#xff0c;还规定不能使用到摄像头&#xff0c;这让我之前学习的Opencv 4与树莓派无用武之地了&#xff0c;但我当时对于三子棋题目饶有兴趣&#xff0c;但架不住队友想稳奖&#xff0c;只能选择这个H题了...... 之后我还想抽空将这个E题三子棋题目做…

快手批量取关

目录 突然发现快手木有批量取关功能&#xff0c;没有功能就创造功能 执行代码中 逐渐变少 后面关注列表没人了&#xff0c;总数还有32&#xff0c;不知道是不是帮测出个bug还是咋的(^_^) 突然发现快手木有批量取关功能&#xff0c;没有功能就创造功能 刚开始1000多人 执行代…

中间件之异步通讯组件rocketmq入门

一、概述 1.1介绍 RocketMQ是阿里巴巴2016年MQ中间件&#xff0c;使用Java语言开发&#xff0c;RocketMQ 是一款开源的分布式消息系统&#xff0c;基于高可用分布式集群技术&#xff0c;提供低延时的、高可靠的消息发布与订阅服务。同时&#xff0c;广泛应用于多个领域&#…

暖水袋 亚马逊日本站认证 PSE认证步骤

暖水袋是用来加热取暖的生活用品&#xff0c;有内置热水来加热的类型和利用微波炉加热后使用的类型等。内置热水的暖水袋有塑料制、橡胶制、陶器制等多种类型&#xff0c;但是利用加热石头而不是利用热水来取暖的产品类型为审查对象外商品。 审查资料 每个 ASIN 的文件&#x…

成为AI产品经理,为何应选择LLMs方向?

前言 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;越来越多的人开始考虑如何在这个领域找到自己的位置。对于那些希望成为AI产品经理的人来说&#xff0c;选择LLMs&#xff08;Large Language Models&#xff0c;大型语言模型&#xff09;方向是一个非常…

mac下通过brew安装mysql的环境调试

mac安装mysql 打开终端&#xff0c;运行命令&#xff08;必须已经装过homebrew哦&#xff09;&#xff1a; 安装brewbin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"已安装brew直接运行&#xff1a;brew install mysql8.0报…

模拟自然光照:饮料稳定性测试的创新方法

饮料添加剂的光照稳定性测试旨在评估其在光照影响下的保持稳定性的能力&#xff0c;特别是在储存期间。此测试有助于制造商理解饮料在不同光源作用下的变化&#xff0c;例如颜色、口感、香气等感官性质的变化&#xff0c;以及营养成分的衰变速率。这些信息对改进产品配方、包装…

泉盛UV-K5/K6固件编译教程

0.准备的硬件 win11/win10电脑泉盛UV-K5/K6k口写频线 1.准备的文件&#xff08;点击链接下载&#xff09; gcc arm编译器 链接: gcc-arm-none-eabi-10.3-2021.10-win32Make 链接:Download make-3.81.exe (GnuWin) 2.编译过程&#xff08;这里以Losehu固件为例子&#xff09; 0.…

AI时代的职场焦虑与机遇

原文链接&#xff1a;https://tecdat.cn/?p37205 在人工智能的浪潮中&#xff0c;职场焦虑愈发显著。本杰明米勒的故事便是这一现象的缩影。2023年初&#xff0c;他领导着一个超过60人的团队&#xff0c;为一家科技公司创作推广文章和博客。然而&#xff0c;随着公司决定采用…

排序算法:插入排序,golang实现

目录 前言 插入排序 代码示例 1. 算法包 2. 插入排序代码 3. 模拟程序 4. 运行程序 5. 从大到小排序 插入排序的思想 循环细节 外层循环 内层循环 循环次数测试 假如 10 条数据进行排序 假如 20 条数据进行排序 假如 30 条数据进行排序 假设 5000 条数据&…

Elasticsearch服务器开发教程(第2版 电子版)

前言 本书也将讨论被称为Querydsl的查询语言&#xff0c;通过它可以创建复杂的查询并过滤返回的结果。除了这些&#xff0c;你还将看到如何使用切面技术&#xff08;faceting&#xff09;基于查询结果来计算汇总数据&#xff0c;以及如何使用新引进的聚合框架&#xff08;分析…