TheWaterProgrammer
TheWaterProgrammer

Reputation: 8259

Qt : How to create a video from multiple QImages

How to create a .mp4 video out of multiple QImages in a Qt application.

Looking at QMediaRecorder examples, it only knows how to grab frames from camera. There seems to be no way to pass multiple QImages or some other image data type into QMediaRecorder simply to make a video out of them which has nothing to do with the camera.

Development Environment:
Using Qt 5.9.1 commercial version with app working on Android, iOS & OSX.

Upvotes: 4

Views: 3726

Answers (1)

Anon
Anon

Reputation: 2492

It is hard to ascertain exactly what you need to do here, considering it is not clear just how many images you are processing.

That being said, this is possible if you use a tool such as ffmpeg to generate the video, however it will require you to at the very least, write those images to disc.

Here is a working example I use to generate slideshows videos for youtube. The concatenation of images is ascertained by their naming scheme as saved on the drive.

    sl << "-i" << md.sku(true) + "##%03d.png"; // Images input,

as such,

mysku##001.png // First Slide
mysku##002.png // Second Slide
mysku##003.png // Third Slide
mysku##004.png // Fourth Slide

VideoConvert::VideoConvert(Metadata &md, QFile &oggFile, QObject *parent) : QObject(parent)
{
    QStringList sl;
    tt.warning(md.duration());
    tt.warning(md.length());
    QString framerate = md.duration(true);
    int hour   = QString(md.length()).split(":").at(0).toInt();
    int minute = QString(md.length()).split(":").at(1).toInt();
    int second = QString(md.length()).split(":").at(2).toInt();

    framerate.remove(".");
    framerate.remove(QRegularExpression("^[0]*"));

    sl << "-y"; // overwrite
    sl << "-framerate" << QString::number(md.images().length()) 
        + "/" + QString::number(((hour * 60) * 60) + (minute * 60) + second);
    sl << "-i" << md.sku(true) + "##%03d.png"; // Images input,
    sl << "-i" << oggFile.fileName();
    sl << "-c" << "copy";
    sl << "/home/akiva/FrogCast/" + md.title(true) + " ⟪Wiki🔊Book⟫.mp4";
    md.setName(sl.last());

    QEventLoop convertEvent;
    m_Convert.setReadChannelMode(QProcess::MergedChannels);
    connect(&m_Convert, SIGNAL(readyRead()), this, SLOT(convert()));
    connect(this, SIGNAL(converted()), &convertEvent, SLOT(quit()));
    tt.process("Converting Video File");
    for (int i=0; i < sl.length(); i++) {
        QTextStream(stdout) << "\t" << sl.at(i) << endl;
    }
    if (QFile("/home/akiva/FrogCast/Cereproc/ffmpeg").exists()) {
        m_Convert.start("/home/akiva/FrogCast/Cereproc/ffmpeg", sl);
    } else {
        m_Convert.start("ffmpeg", sl);
    }
    convertEvent.exec();
    disconnect(&m_Convert, SIGNAL(finished(int)), this, SLOT(convert()));
    disconnect(this, SIGNAL(converted()), &convertEvent, SLOT(quit()));
    m_Convert.waitForFinished();
}

Upvotes: 2

Related Questions