IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 创建qml自定义视频源(Qt6.3.1+取景器帧) -> 正文阅读

[移动开发]创建qml自定义视频源(Qt6.3.1+取景器帧)

前言

笔者之前记录的是Qt5.15的,当前Qt6系列无法使用

笔者本次记录下Qt6中,如何创建qml自定义视频源

一、获取视频帧

这个笔者在之前的文档中记录过,本次算是重复了

1.通过videoSink获取

关键代码如下

    Camera {
        id: camera
    }

    CaptureSession {
        id: captureSession
        camera: camera
        videoOutput: page.videoOutput
    }

    Connections {
        target: videoOutput.videoSink
        function onVideoFrameChanged(frame) {
            //设置并处理已获取视频帧
        }
    }

笔者翻看源码时发现,QMediaCaptureSession中有关于QVideoSink的方法,但没有作为属性导出,不明白官方是什么用意。应该是可以在C++中正常使用的,笔者未测试,感兴趣的小伙伴可以试试

代码很好理解,videoSink的onVideoFrameChanged会将视频帧直接扔出来

2.通过imageCapture获取

正确地说,这是获取静态图片了,关键代码如下

    Camera {
        id: camera
    }

    ImageCapture {
        id: imageCapture
    }

    CaptureSession {
        id: captureSession
        camera: camera
        imageCapture: imageCapture
        videoOutput: page.videoOutput
    }

    Timer {
        id: timer
        interval: 500; running: true; repeat: true
        onTriggered: imageCapture.capture()
    }

    Connections {
        target: imageCapture
        function onErrorOccurred(requestId, error, message) {//发生错误
            console.debug("imageCapture onErrorOccurred",requestId, error, message)
        }
        function onImageCaptured(requestId, previewImage) {//已经捕获到QImage
            console.debug("imageCapture onImageCaptured",requestId, previewImage,imageCapture.preview)

            //imageCapture.preview可以直接作为Image的source,以显示图片
            //previewImage是QImage对象,可以交给C++处理

        }

        }
    }

?代码也很好理解,就是使用定时器,定时获取一个QImage

二、创建视频源

VideoOutput类型的videoSink属性中,有一个setVideoFrame()方法,可以添加新的视频帧,但此方法未注册到qml中,因此需要在C++中实现。笔者定义了一个工具类来实现,关键代码如下

class Tool : public QObject
{
    Q_OBJECT

public:
    explicit Tool(QObject *parent = nullptr);

    //设置并处理已获取视频帧
    Q_INVOKABLE void setVideoFrame(const QVideoFrame frame);
    Q_INVOKABLE void setVideoImage(const QImage image);

    //设置QVideoSink对象实例
    Q_INVOKABLE void setVideoSink(QVideoSink *newVideoSink);

signals:

private:
    QVideoSink *m_videoSink = nullptr;
};

?将此工具类直接注册到qml中,设置好QVideoSink对象实例,然后把已有的视频帧放入就可以了

实现的关键代码如下

/*!
 * \brief Tool::setVideoFrame 设置并处理已获取视频帧
 * \param frame 已获取视频帧
 */
void Tool::setVideoFrame(const QVideoFrame frame)
{
    qDebug()<<Q_FUNC_INFO<<__LINE__<<frame;

    if(m_videoSink != nullptr)
        m_videoSink->setVideoFrame(frame);
}

void Tool::setVideoImage(const QImage image)
{
    qDebug()<<Q_FUNC_INFO<<__LINE__<<image;

    QVideoFrameFormat frameFormat(image.size(), QVideoFrameFormat::Format_BGRA8888);
    QVideoFrame f(frameFormat);

    if (f.map(QVideoFrame::WriteOnly)) {
        memcpy(f.bits(0), image.bits(), image.sizeInBytes());

        f.setStartTime(0);
        f.unmap();
        if(m_videoSink != nullptr)
            m_videoSink->setVideoFrame(f);
    }
}

void Tool::setVideoSink(QVideoSink *newVideoSink)
{
    if (m_videoSink == newVideoSink)
        return;
    m_videoSink = newVideoSink;
}

?实现代码也不复杂,但笔者有点疑问,QImage明明显示是RGB32的颜色空间,但在生成QVideoFrame时,却要使用BGRA8888的颜色空间????

三、运行测试

代码不难理解,只是这个运行结果,有空让人难受

1.在win10下测试时,videoSink获取的QVideoFrame是Format_NV12,与Qt5下的完全不同。

若是需要QImage,可以通过QVideoFrame::toImage()方法直接得到

2.在鸿蒙系统下测试时,videoSink获取的QVideoFrame是Format_SamplerExternalOES,与Qt5下的完全不同。

若是需要QImage,无法通过QVideoFrame::toImage()方法得到,而且一用到这个方法,程序就会卡住,界面没响应

3.在win10下,通过imageCapture可是正常获取到QImage的图像,但在鸿蒙系统下获取会很慢

运行结果就不放图片了,笔者建议还是再等等官方修复吧

笔者测试使用的源码

后记

与之前的版本相关,新版本Qt6.3.1中的多媒体模块,已经修复了不少问题。已经可以使用mingw编译器,qml中可以获取正常的Image source。但目前仍然存在很多问题,如设置分辨率无效等。

笔者听说多媒体模块计划使用ffmpeg实现,笔者很期待

接下来,因项目需要,笔者计划暂时使用openCV获取视频帧,并使用VideoOutput显示

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 18:16:18  更:2022-06-25 18:18:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:53:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码