前一节已经实现了录制,只能录制一段视频,实际运用中我们可能会暂停,然后接着录制最终生成一条完整的视频。

我们在使用命令行操作ffmpeg时组合各段视频的命令如下:

ffmpeg -f conccat -safe 0 -i conccatfile -c copy dirfile

所以我的方法是暂停录制后生成一条临时视频,并把临时视频的文件名保存在conccatfile里面。重新开始录制又重新录制一条临时视频,这样如果一直反复暂停录制开始录制,会生成多个临时文件。停止录制时将这些视频组合成一条视频,从而完成录制的各种操作实现。

1.创建一个保存临时视频的文件

文件按录制开始的本地时间命名如下:

QString path = QString("%1/%2_tmp").arg(m_cacheDir).arg(QDateTime::currentDateTime().toMSecsSinceEpoch());
          m_pConcatFile = new QFile(path);
         if (!m_pConcatFile->open(QIODevice::ReadWrite | QIODevice::Text|QIODevice::Truncate))
             qDebug() << "File open error";

2.开始录制

之前是直接给出最终的录制文件名,这里为了实现暂停录制功能,开始录制时使用临时文件。并把临时视频文件内容写入步骤1创建的文件

QString tmpFilePath = QString("v%1_tmp").arg(QDateTime::currentDateTime().toMSecsSinceEpoch());
    QTextStream out(m_pConcatFile);
     out << "file" << " '" << tmpFilePath << "'\n";
     QString tmpFileAbsolutePath =  m_cacheDir + "/"+ tmpFilePath;
     args << tmpFileAbsolutePath;    m_currentRecordTempFiles<<tmpFileAbsolutePath;
     m_currentRecordTempFiles<<tmpFileAbsolutePath.replace("_tmp", ".mp4");
     m_pRecordProcess->start("ffmpeg", args);

3.停止录制

新增加一个成员变量来判断时真的停止录制,如果时停止录制就开始组合视频。并将步骤1创建的组合文件列表的文件删除

m_bStopRecord = true;
     m_concatFileName = m_pConcatFile->fileName();
     m_pConcatFile->close();
     m_pConcatFile->deleteLater();
     m_pConcatFile = nullptr;
     m_pRecordProcess->write("q");

4.暂停录制

暂停录制停止当前录制进程,并设置m_bStopRecord = false,这样就不会开始组合,下次开始录制会重新生成一个视频临时文件,并写入步骤1创建的组合文件列表的文件

m_bStopRecord = false;
     m_pRecordProcess->write("q");

录制过程中会生成如下临时文件:

python ffmpeg 启动录屏 和结束录屏 ffmpeg录屏停止_临时文件

带v的表示视频,不带的表示组合文件列表:

python ffmpeg 启动录屏 和结束录屏 ffmpeg录屏停止_临时文件_02

 

5.组合录制视频

每次录制进程退出都会去判断m_bStopRecord = true,如果true则新建一个进程去处理视频组合。

python ffmpeg 启动录屏 和结束录屏 ffmpeg录屏停止_临时文件_03

        connect(m_pRecordProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
            [this](int exitCode, QProcess::ExitStatus exitStatus) {
            if(!m_bStopRecord)
                return;
            QProcess* mergeProcess = new QProcess(this);
            connect(mergeProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
                [mergeProcess, this](int exitCode, QProcess::ExitStatus exitStatus) {
                qDebug() << QStringLiteral("成功合成视频");
                qDebug() << mergeProcess->readAllStandardError();
                if(m_currentRecordTempFiles.count()>3)
                    m_currentVideoPath = m_currentRecordTempFiles.at(2);
                clear();
            });

            if(m_currentRecordTempFiles.count()<3)
                return ;
            QStringList args;
            args << "-f" << "concat";
            args << "-safe" << "0";
            args << "-i" << m_currentRecordTempFiles.at(0);
            args << "-c" << "copy";
            args << m_currentRecordTempFiles.at(2);
            //合成视频
            mergeProcess->start("ffmpeg", args);
————————————

 

其实就是对应上面写的那条命令。

组合后删除临时文件生成视频。

python ffmpeg 启动录屏 和结束录屏 ffmpeg录屏停止_文件名_04

这样就能实现真正的录制场景。