Qt:如何从多个QImage创建视频

4
如何在Qt应用程序中使用多个 QImage创建一个.mp4视频。
查看 QMediaRecorder示例,它只知道如何从相机获取帧。似乎没有办法将多个 QImage 或其他图像数据类型简单地传递到 QMediaRecorder 中,以便制作与相机无关的视频

开发环境:
使用 Qt 5.9.1 商业版,应用程序在 Android iOS OSX 上运行。


1
Qt没有提供这样的功能。 - dtech
那么,我需要使用 FFmpeg 吗?将 FFmpeg 构建到我的 Qt 应用程序中,并通过某种方式传递这些 QImages 来创建 .mp4 视频? - TheWaterProgrammer
1
是的,ffmpeg、gstreamer、libav或libvnc,有很多选择。 - dtech
你有关于如何把 QImages 传递给 FFmpeg 的示例或片段吗?如果您认为这是一个不同的问题,那就算了。只是问一下您是否有现成的示例可供参考。 - TheWaterProgrammer
1
另外,您可以回复并说明Qt没有提供此功能。这个答案对我来说是可接受的。在开始使用QImage实现我的目标之前,我想确认一下,是否需要花费大量时间学习如何在Qt应用程序中构建FFmpeg并找出如何使用它。 - TheWaterProgrammer
抱歉,这样的答案不符合我的实用标准。我认为没有很多例子,我记得有一个Qt包装器用于gstreamer,但如果我没记错,它已经好几年没有维护了。 - dtech
1个回答

2

考虑到您处理的图片数量不明确,很难确定您需要在这里做什么。

尽管如此,如果您使用诸如ffmpeg之类的工具生成视频,则有可能实现此目标,但至少需要将这些图像写入磁盘。

下面是我用于为YouTube生成幻灯片视频的示例。通过它们在驱动器上保存的命名方案来确定图像的串联。

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

作为这样的,
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) + " ⟪WikiBook⟫.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();
}

我之前研究过这种技术。将光盘上的每个图像都写入不是一个选项,因为这样会花费太多时间来击中文件系统。如果有90个QImages,那么它将会命中文件系统90次?然后再保存视频?我正在寻找一种在应用程序主内存中完成此操作并仅在创建“.mp4”时才访问文件系统的方法。我的要求非常简单,就是“如何从多个QImages创建视频”。 - TheWaterProgrammer
@程序员 注意到的一个有趣的事情是,你在上面看到的ffmpeg配置实际上没有任何渲染开销,不像当你将avi转换为mp4可能需要花费几个小时。在这里,一个时长为2小时、包含90张幻灯片的视频只需要几秒钟就可以完成。这可能会抵消文件系统写入的惩罚,特别是如果你所寻求的替代方案确实需要渲染开销的话。 - Anon
你忘记提供包含90张幻灯片的视频链接了。 - TheWaterProgrammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接