【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();
}

效果演示:

相关文章
|
1月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
109 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
3月前
|
安全 Linux vr&ar
Linux的动态库和静态库
Linux的动态库和静态库
|
27天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
75 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
3月前
|
Unix Linux 开发工具
linux笔记 diff及patch的制作与使用
这篇文章是关于Linux系统中使用`diff`命令生成补丁文件以及使用`patch`命令应用这些补丁的详细教程和实战案例。
85 2
linux笔记 diff及patch的制作与使用
|
3月前
|
Linux API
在Linux中,程序产生了库日志虽然删除了,但磁盘空间未更新是什么原因?
在Linux中,程序产生了库日志虽然删除了,但磁盘空间未更新是什么原因?
|
3月前
|
Linux
Linux源码阅读笔记13-进程通信组件中
Linux源码阅读笔记13-进程通信组件中
|
3月前
|
消息中间件 安全 Java
Linux源码阅读笔记13-进程通信组件上
Linux源码阅读笔记13-进程通信组件上
|
3月前
|
Linux 开发者
Linux源码阅读笔记18-插入模型及删除模块操作
Linux源码阅读笔记18-插入模型及删除模块操作
|
3月前
|
Linux
Linux源码阅读笔记12-RCU案例分析
Linux源码阅读笔记12-RCU案例分析
|
3月前
|
数据采集 Linux
Linux源码阅读笔记20-PCI设备驱动详解
Linux源码阅读笔记20-PCI设备驱动详解