DAY11-录音,视频播放和windows摄像头

178 阅读5分钟

音频的输入

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

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

移植alsa核心库

移植三部曲 ------------ 配置 编译 安装

tar -xjvf xxx.tar.bz2

拷贝到非共享目录解压,先移植核心支持库,再移植工具库

image-20220826210845202

核心库配置

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

编译

make

安装

make install

移植alsa工具库

工具库配置

./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

编译

make

安装

make install

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

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

将编译生成的目录打包,拷贝到开发板解压,解压后将需要的文件拷贝到对应目录

tar -cJvf alsa.tar.xz alsa

练习:

完成alsa库的移植

image-20220826210855699

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

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

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

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

将配置文件拷贝到和Ubuntu中安装路径相同的目录

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

使用alsa实现录音和播放

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

练习:

完成将alsa库移植到开发板,设计一个Qt界面程序,在开发板通过界面控制录音和播放(QProcess)

Qt中的文字转语音

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

QT += texttospeech

使用方法:

选择语音引擎

[static] QStringList QTextToSpeech::availableEngines();

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

选择语言,声音类型,音量,音调和语速

image-20220826210905788

image-20220826210913606

注意:前两步不操作就使用默认

转换

[slot] void QTextToSpeech::say(const QString &text);
//调用系统的语音模块播放文本信息

Qt中的视频处理

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

image-20220826210920081

视频播放

mplayer -------------- 开源的视频播放器

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

开发板上默认没有mplayer,需要将资料中的文件拷贝到/usr/bin目录下。

mplayer 视频文件路径
//需要把mplayer文件拷贝到开发板/usr/bin目录下。

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

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

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

-quiet ----- 输出变化信息
-slave ----- 后台命令处理模式
-geometry ----- 指定播放位置(开发板无效)
-zoom -x ** -y ## ----- 指定播放分辨率
-af volume=xxx ----- 设置音量(-200 ~ +60)

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

练习:

将Qt mplayer播放器的双击播放,上一个,下一个的的功能完成

QMediaPlayer播放视频

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

QMediaPlayer视频显示设置

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

image-20220826210928019

使用了视频播放窗口,需要在项目中添加如下内容

-quiet ----- 输出变化信息
-slave ----- 后台命令处理模式
-geometry ----- 指定播放位置(开发板无效)
-zoom -x ** -y ## ----- 指定播放分辨率
-af volume=xxx ----- 设置音量(-200 ~ +60)

其他操作和QMediaPlayer播放音频完全移植

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

windows的QMediaPlayer有很多视频格式不支持,需要手动安装解码器到Qt安装目录。

image-20220826210937284

image-20220826210943160

Qt中子窗口的全屏和恢复

Qt通过子窗口的成员函数showFullScreen实现窗口全屏,但是只允许顶层窗口全屏,子窗口如果要全屏必须先升级成顶层窗口。

QWidget ------------ setWindowFlags(Qt::Window);
QWidget ------------ showFullScreen();

子窗口退出全屏,也必须先恢复成子窗口,再通过showNormal成员函数退出全屏

QWidget ------------ setWindowFlags(Qt::SubWindow);
QWidget ------------ showNormal();

摄像头

摄像头是视频输入/捕获的硬件,在不同的系统和硬件环境下,可以选择不同的处理方法,主要介绍在windows和Linux中如何处理摄像头的信息。

windows摄像头

首先在项目文件加入多媒体模块:

QT += multimedia multimediawidgets

多媒体模块中包含了处理摄像头的类

摄像头信息类 ------------- QCameraInfo

//返回当前系统中可用的摄像头信息
[static] QList<QCameraInfo> QCameraInfo::availableCameras(QCamera::Position position = QCamera::UnspecifiedPosition);
//返回摄像头信息的链表

//获取摄像头的描述信息
QString QCameraInfo::description() const;
//获取摄像头的设备名
QString QCameraInfo::deviceName() const;

摄像头类 ----------- QCamera

//构造函数
QCamera::QCamera(const QCameraInfo &cameraInfo, QObject *parent = nullptr);
QCamera::QCamera(const QByteArray &deviceName, QObject *parent = nullptr);

//成员函数
//设置显示窗口
void QCamera::setViewfinder(QVideoWidget *viewfinder);
void QCamera::setViewfinder(QGraphicsVideoItem *viewfinder);
void QCamera::setViewfinder(QAbstractVideoSurface *surface);

//槽函数
//开始采集
[slot] void QCamera::start();
//停止采集
[slot] void QCamera::stop();

摄像头截屏类 ----------- QCameraImageCapture

构造函数:
QCameraImageCapture::QCameraImageCapture(QMediaObject *mediaObject, QObject *parent = nullptr);

截屏槽函数:
[slot] int QCameraImageCapture::capture(const QString &file = QString());
//参数就是截屏图片的保存路径

//截屏完成信号
[signal] void QCameraImageCapture::imageCaptured(int id, const QImage &preview);
//id代表截屏的编号,preview就是截屏的图像

作业:

将QMediaPlayer视频播放器的退出全屏改为用特定事件处理函数(按键事件)实现

提示:重写QVideoWidget类中的按键事件处理函数 ----- 继承