【QT】linux下alsa库的移植和QT中音视频的处理&笔记

简介: 【QT】linux下alsa库的移植和QT中音视频的处理&笔记

一、音频的输入

linux下有一个开源的音频库----alsa库,实现了录音的功能,alsa库包含如下内容:


alsa-lib-1.0.22.tar.bz2 ------- alsa的核心支持库

alsa-utils-1.0.22.tar.bz2----- alsa的工具库

1、移植alsa库

(移植三步曲):配置、编译、安装

(1)首先把下载好的压缩包放到非共享目录中解压,先移植核心支持库,再移植工具库(因为工具库依赖于支持库)

tar -xjvf xxx.tar.bz2

(2)核心支持库

1)配置

./configure --host=arm-linux --prefix=/home/gec/alsa --disable-python

2)编译

make

3)安装

make install

(3)移植工具库

1)工具库配置

./configure --host=arm-linux --prefix=/home/gec/alsa --with-alsa-prefix=/home/gec/alsa/lib --with-alsa-inc-prefix=/home/gec/alsa/include --disable-alsamixer --disable-xmlto

2)编译

make

3)安装

make install

注意:如果编译安装时报缺少某个文件的错误,直接手动在对应的目录下创建该文件


t-ja.gmo ------- alsaconf/po/t-ja.gmo

t-ru.gmo -------alsaconf/po/t-ru.gmo


(4)将编译生成的目录(alsa)打包,拷贝到开发板上解压,解压后将需要的文件拷贝到对应的目录中。


tar -cJvf alsa.tar.xz alsa

1)将三个库文件拷贝到/usr/lib中

cp alsa/lib/libasound.so* /usr/lib -r

2)将两个命令文件拷贝到/usr/bin中

cp alsa/bin/arecord alsa/bin/aplay /usr/bin -r

3)将配置文件拷贝到和Ubuntu中安装路径相同的位置

mkdir -p /home/gec/alsa

cp alsa/share /home/gec/alsa -r

(5)使用alsa实现录音和播放

arecord -d10 -c1 -r16000 -twav -fS16_LE xxx.WAV
    -d:录音时间
    -c:音轨
    -r:采样频率
    -t:封装格式
    -f:量化位数
    
aplay xxx.WAV    


二、Qt中的文字转语音

Qt5.8开始加入了文字转语音的模块,使用QTextToSpeech类,使用该类需要在项目文件中加入texttospeech模块(版本高于5.9)

QT += texttospeech

使用方法:

1、选择语音引擎

[static] QStringList QTextToSpeech::availableEngines();

//构造QTextToSpeech对象时可以选择引擎
QTextToSpeech::QTextToSpeech(const QString &engine, QObject *parent = nullptr);

2、选择语言、声音类型、音量、音调、语速

3、转换

[slot] void QTextToSpeech::say(const QString &text);

//调用系统语音系统播放文本信息

测试代码:

#include "myspeech.h"
#include "ui_myspeech.h"

MySpeech::MySpeech(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MySpeech)
{
    ui->setupUi(this);

    tts = new QTextToSpeech(this);
}

MySpeech::~MySpeech()
{
    delete ui;
}

//播放
void MySpeech::on_pushButton_clicked()
{
    tts->say(ui->lineEdit->text());
}


三、QT中的视频处理

视频是由图片流和音频流组成,为了保证视频存储和传输的效率,需要对视频进行压缩(编码),视频的压缩分为帧内压缩和帧间压缩,对视频的压缩和解压就叫视频的编解码。

1、视频播放

(1)mplayer----开源的视频播放器

视频播放器提供视频解码并播放的功能,mplayer是一个免费开源的视频播放器,支持各种常见格式的视频,用法和madplay类似。

mplayer 视频文件路径

//需要将mplayer文件拷贝到开发板/usr/bin目录下(我用的开发板是GEC6818开发板)

mplayer在启动时可以添加选项控制

-quiet --------------- 不输出变换信息
-slave --------------- 后台命令获取模式
-geometry ------------ 在当前界面的指定位置播放(开发板无效)
-zoom -x ** -y ## ---- 指定播放分辨率
-af volume=xxx ------- 设置音量(-200 ~ +60)

注意:挂载开发板的空闲分区

1、格式化分区(只进行一次)
mkfs.vfat /dev/mmcblk0p7
2、挂载分区(创建一个空文件夹作为挂载点,每次启动都要执行)
mount -t vfat /dev/mmcblk0p7 挂载点(/Even)

//如果希望自动挂载可以把挂载命令写入/etc/profile文件中

使用Qt界面控制mplayer,方法和madplay一样,唯一的区别需要预留播放视频图像的区域。

(2)QMediaPlayer

QMediaPlayer既可以播放播放音频,也可以播放视频,播放视频需要显示图像信息,需要指定显示的窗口。

1)QMediaPlayer视频显示

QMediaPlayer提供成员函数,指定视频输出窗口。

2)使用了视频播放窗口,需要在工程中添加以下的内容

//在工程文件中添加
QT += multimedia multimediawidgets
//在头文件中添加
#include <QVideoWidget>

其他的操作和QMediaPlayer音频播放完全一致

播放/停止
暂停/继续
上一个/下一个
音量控制
进度条
视频文件 添加/删除/清空  

测试代码:

#include "myvideoplayer.h"
#include "ui_myvideoplayer.h"
#include <QFileDialog>

MyVideoPlayer::MyVideoPlayer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyVideoPlayer)
{
    ui->setupUi(this);

    player = new QMediaPlayer(this);
    playlist = new QMediaPlaylist(this);
    vw = new QVideoWidget(this);

    //将窗口放入布局管理器
    ui->horizontalLayout->addWidget(vw);
    //设置播放器的显示窗口
    player->setVideoOutput(vw);


    //设置播放模式
    playlist->setPlaybackMode(QMediaPlaylist::Loop);//循环播放
    //设置播放器的播放列表
    player->setPlaylist(playlist);

    //连接周期改变和进度改变的信号
    QObject::connect(player,&QMediaPlayer::durationChanged,this,[&](qint64 duration){
        //设置进度条的最大值
        ui->horizontalSlider->setRange(0,duration);
        //显示周期
        video_duration = QString("%1:%2:%3").arg(duration/1000/60/60,2,10,QChar('0'))
                                            .arg(duration/1000/60%60,2,10,QChar('0'))
                                            .arg(duration/1000%60,2,10,QChar('0'));
        ui->label_pos->setText(QString("00:00:00/%1").arg(video_duration));

        //显示歌曲切换
        ui->listWidget->setCurrentRow(playlist->currentIndex());
    });

    QObject::connect(player,&QMediaPlayer::positionChanged,this,[&](qint64 position){
        //更新进度条的值
        ui->horizontalSlider->setValue(position);
        //显示进度
        ui->label_pos->setText(QString("%1:%2:%3/%4").arg(position/1000/60/60,2,10,QChar('0'))
                                                  .arg(position/1000/60%60,2,10,QChar('0'))
                                                  .arg(position/1000%60,2,10,QChar('0'))
                                                  .arg(video_duration));
    });
}

MyVideoPlayer::~MyVideoPlayer()
{
    delete ui;
}

//添加视频
void MyVideoPlayer::on_pushButton_addvideo_clicked()
{
    QStringList video_files = QFileDialog::getOpenFileNames(this,"选择视频文件","E:/GZ2142/11-Qt/Qt高级资料","*.mp3 *.mp4 *.avi *.WAV");

    //去重
    for(int i=0;i<ui->listWidget->count();i++){
        for(int j=0;j<video_files.count();j++){
            if(ui->listWidget->item(i)->text()==video_files.at(j)){
                video_files.removeAt(j);
                break;
            }
        }
    }

    //如果无添加直接返回
    if(video_files.isEmpty())
        return;

    //添加到playlist
    for(int i=0;i<video_files.count();i++){
        QString file = video_files.at(i);
        playlist->addMedia(QUrl(file));
    }

    //添加到ListWid
    ui->listWidget->addItems(video_files);
    //定位
    ui->listWidget->setCurrentRow(0);
}

//删除视频
void MyVideoPlayer::on_pushButton_delvideo_clicked()
{
    int delrow = ui->listWidget->currentRow();

    //取出一项
    QListWidgetItem *item = ui->listWidget->takeItem(delrow);

    if(item)
        delete item;

    //从playlist中删除
    playlist->removeMedia(delrow);
}

//清空视频
void MyVideoPlayer::on_pushButton_clearvideo_clicked()
{
    ui->listWidget->clear();
    playlist->clear();
}

void MyVideoPlayer::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
    //指定当前播放的文件
    int row = ui->listWidget->currentRow();
    playlist->setCurrentIndex(row);

    player->play();
    //音量设置
    player->setVolume(ui->verticalSlider->value());

    ui->pushButton_stopcont->setEnabled(true);
}

//播放
void MyVideoPlayer::on_pushButton_start_clicked()
{
    //指定当前播放的文件
    int row = ui->listWidget->currentRow();
    playlist->setCurrentIndex(row);

    player->play();
    //音量设置
    player->setVolume(ui->verticalSlider->value());

    ui->pushButton_stopcont->setEnabled(true);
}

//暂停
void MyVideoPlayer::on_pushButton_stopcont_clicked()
{
    ui->pushButton_stopcont->setEnabled(false);
    player->pause();
}

//停止
void MyVideoPlayer::on_pushButton_kill_clicked()
{
    //禁止暂停按钮
    ui->pushButton_stopcont->setEnabled(false);
    player->stop();
}

效果演示:

相关文章
|
9天前
|
Linux iOS开发 开发者
Qt问题(二):无法定位程序输入点于动态链接库
动态链接库(Dynamic Link Library,简称DLL)是一种可执行文件格式,常见于Windows操作系统中,而在Linux和macOS等其他操作系统中,相似的概念通常被称为共享库(Shared Library)。动态链接库允许程序在运行时加载所需的代码和数据,而不是在编译时静态链接到应用程序中。这种方式带来了几个重要的优点:
|
10天前
|
Ubuntu Linux vr&ar
IM跨平台技术学习(十二):万字长文详解QQ Linux端实时音视频背后的跨平台实践
本文详细记录了新版QQ音视频通话在 Linux 平台适配开发过程中的技术方案与实现细节,希望能帮助大家理解在 Linux 平台从 0 到 1 实现音视频通话能力的过程。
32 2
|
1天前
|
Web App开发 缓存 Linux
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
《FFmpeg开发实战》书中第10章提及轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适合生产环境。推荐使用SRS或ZLMediaKit,其中SRS是国产开源实时视频服务器,支持多种流媒体协议。本文简述在华为欧拉系统上编译安装SRS和FFmpeg的步骤,包括安装依赖、下载源码、配置、编译以及启动SRS服务。此外,还展示了如何通过FFmpeg进行RTMP推流,并使用VLC播放器测试拉流。更多FFmpeg开发内容可参考相关书籍。
10 2
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
|
8天前
|
Linux
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
《FFmpeg开发实战》书中介绍了直播的RTSP和RTMP协议,以及新协议SRT和RIST。SRT是安全可靠传输协议,RIST是可靠的互联网流传输协议,两者于2017年发布。腾讯视频云采用SRT改善推流卡顿。以下是Linux环境下为FFmpeg集成libsrt和librist的步骤:下载安装源码,配置、编译和安装。要启用这些库,需重新配置FFmpeg,添加相关选项,然后编译和安装。成功后,通过`ffmpeg -version`检查版本信息以确认启用SRT和RIST支持。详细过程可参考书中相应章节。
16 1
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
|
16天前
|
Unix Shell Linux
技术笔记:linux中SIGHUP与nohup的关系
技术笔记:linux中SIGHUP与nohup的关系
12 1
|
16天前
|
Unix 关系型数据库 Linux
技术笔记:linux学习心得
技术笔记:linux学习心得
12 0
|
16天前
|
机器学习/深度学习 Unix Java
技术笔记:Linux之Shell脚本编程(一)
技术笔记:Linux之Shell脚本编程(一)
20 0
|
16天前
|
网络协议 算法 Linux
技术笔记:Linux学习:TCP粘包问题
技术笔记:Linux学习:TCP粘包问题
15 0
|
16天前
|
网络协议 Linux Shell
技术笔记:Linux中的两种守护进程standalone和xinetd
技术笔记:Linux中的两种守护进程standalone和xinetd
13 0
|
16天前
|
NoSQL Linux Shell
技术笔记:linux系统开发基础
技术笔记:linux系统开发基础
17 0