Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt6.4: how to record a renderd camera video

Qt6.4: how to record a renderd camera video

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 396 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alex_Koeppel
    wrote on last edited by
    #1

    Hello there
    I would like to record a video via camera, add some overlay to it and finally save it as a mp4. The overlay must be visible in the mp4 file.
    I made it to display the overlay on a VideoOutput in qml.
    But i didn't got it to record the overlay on the video.
    Is there a way to set the VideoOutput as source to record, instead of the camera?

    My Code so far:
    video_input.h (QVideoSink)

    #ifndef VIDEO_INPUT_H
    #define VIDEO_INPUT_H
    
    #include "qmediacapturesession.h"
    #include <QVideoSink>
    #include <QCamera>
    #include <QMediaCaptureSession>
    #include <QPointer>
    #include <QMediaRecorder>
    
    class Video_input : public QVideoSink
    {
        Q_OBJECT
        Q_PROPERTY( QVideoSink* videoSink READ videoSink WRITE setVideoSink NOTIFY videoSinkChanged )
        Q_PROPERTY( QMediaRecorder* recorder READ recorder WRITE setRecorder NOTIFY recorderChanged )
        public:
            explicit Video_input(QObject * parent = nullptr);
            ~Video_input();
    
            QVideoSink * videoSink() const;
            void setVideoSink( QVideoSink * new_video_sink );
            QMediaRecorder * recorder() const;
            void setRecorder( QMediaRecorder * new_recorder );
    
        signals:
            void videoSinkChanged();
            void recorderChanged();
    
        private slots:
            void new_frame(const QVideoFrame& frame);
    
        private:
            void start_camera();
            void stop_camera();
    
        private:
            Q_DISABLE_COPY(Video_input)
            QCamera * m_camera;
            QMediaCaptureSession m_capture_session;
            QPointer<QVideoSink> m_video_sink;
            QMediaRecorder * m_recorder;
    };
    
    #endif // VIDEO_INPUT_H
    
    

    video_input.cpp (QVideoSink)

    #include "Video_input.h"
    
    #include <QPainter>
    #include <QFont>
    #include <QDebug>
    
    
    Video_input::Video_input(QObject * parent)
        : QVideoSink(parent)
    {
        connect(this,&QVideoSink::videoFrameChanged,this,&Video_input::new_frame);
        this->start_camera();
    }
    
    Video_input::~Video_input()
    {
        this->stop_camera();
    }
    
    QVideoSink * Video_input::videoSink() const
    {
        return m_video_sink.get();
    }
    
    void Video_input::setVideoSink(QVideoSink * new_video_sink)
    {
        if(m_video_sink == new_video_sink)
        {
            return;
        }
        m_video_sink = new_video_sink;
        emit videoSinkChanged();
    }
    
    QMediaRecorder * Video_input::recorder() const
    {
        return m_recorder;
    }
    
    void Video_input::setRecorder(QMediaRecorder * new_recorder)
    {
        if(m_recorder == new_recorder)
        {
            return;
        }
        m_recorder = new_recorder;
        m_capture_session.setRecorder(m_recorder);
        emit recorderChanged();
    }
    
    void Video_input::start_camera()
    {
        m_camera = new QCamera(this);
        m_capture_session.setCamera(m_camera);
        m_capture_session.setVideoSink(this);
        //m_capture_session.setVideoOutput(this);
        m_camera->start();
    }
    
    void Video_input::stop_camera()
    {
        m_camera->stop();
        disconnect(m_camera, 0, 0,0);
        m_camera->setParent(nullptr);
        delete m_camera;
        m_camera = nullptr;
    }
    
    void Video_input::new_frame(const QVideoFrame & frame)
    {
    
        QVideoFrame m_frame = frame;
        QImage m_image;
        //get frame to image
        m_frame.map(QVideoFrame::ReadOnly);
        if(m_frame.isValid())
        {
            m_image = m_frame.toImage();
        }
        //Unmap
        if(m_frame.isMapped())
            m_frame.unmap();
        m_image = m_image.convertToFormat(QImage::Format_RGBA8888);
    
        //Draw overlay
        QPainter m_painter(&m_image);
        m_painter.fillRect(QRect(0, 0, 100, 100), QColor(Qt::GlobalColor::red));
        m_painter.fillRect(QRect(0, 100, 100, 100), QColor(Qt::GlobalColor::green));
        m_painter.fillRect(QRect(0, 200, 100, 100), QColor(Qt::GlobalColor::blue));
    
    
        QVideoFrameFormat m_videoformat(m_image.size(), QVideoFrameFormat::Format_RGBA8888);
        QVideoFrame m_overlay(m_videoformat);
    
        m_overlay.map(QVideoFrame::WriteOnly);
        if(m_overlay.isValid())
        {
            uint8_t pane = 0;
            memcpy(m_overlay.bits(pane),m_image.bits(),m_image.sizeInBytes());
        }
        if(m_overlay.isMapped())
            m_overlay.unmap();
        if(m_video_sink)
        {
            m_video_sink->setVideoFrame(m_overlay);
        }
    }
    

    main.qml

    import QtQuick.Controls 2.2
    import QtQuick.Layouts 1.3
    import QtQuick 2.7
    import QtQuick.Window 2.2
    import my.Video_input 1.0
    import QtMultimedia
    
    Window {
        id: appWindow
        width: 640
        height: 480
        visible: true
    
        title: qsTr("My Video Overlay")
    
        Video_input {
                id: video_input
                videoSink:  view.videoSink
                recorder: recorder
        }
    
        VideoOutput {
            id: view
            anchors.fill: parent
        }
    
        MediaRecorder{
            id: recorder
        }
    
        Button {
            text: "Record"
            visible: recorder.recorderState !== MediaRecorder.RecordingState
            onClicked: recorder.record()
        }
        Button {
            text: "Stop"
            visible: recorder.recorderState === MediaRecorder.RecordingState
            onClicked: recorder.stop()
        }
    }
    
    

    Thanks in advance
    Alex

    1 Reply Last reply
    1
    • L Offline
      L Offline
      lyris
      wrote on last edited by
      #2

      I am facing the same problem. I would like to use qvideosink as input for the recorder and not a qcamera since I have customized qvideframes

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved