菜鸟学ffmpeg音视频技术之二实现命令录制(暂停,组合)

11 篇文章 0 订阅
5 篇文章 0 订阅

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

我们在使用命令行操作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");

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

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

 

5.组合录制视频

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

        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);

 

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值