FFmpeg 将多张图片编码成视频

前言

本篇文章的需求是将相机获取到的图片进行编码,编码成一个视频,耗费了大约一个星期的时间在解决各种问题。这里阐述一下这篇文章所要解决的几个问题:

1、如何将多张图片编码成视频。

2、如何进行定时录制视频。

3、同时开启多线程进行视频录制。

4、对录制文件目录进行管理:每次都检测录制目录大小是否超过指定大小,如果超过,则删除指定大小的时间最早的一些文件。

正文

一、准备工作

1、下载FFmpeg的开发版

1、下载链接: https://ffmpeg.org/download.html

4、由于我是在Win10下,所以选择:

2、使用环境

Win10 + Qt8.0.2(MSVC2019) + FFmpeg 4.4

二、整体流程解析

上面的流程图,基本上就是这次这个项目的整体流程了,上面的 2 3 4点都是在单例层完成的。只有第一点是在FFmpegRecord那一层完成的。

三、单例模式——多线程视频录制

首先,确定目标,我是要“同时录制多个视频”,所以,必须得开多个线程,并且,在这一层,就必须要完成:

1、给上层应用的调用提供一个接口。

2、进行定时关闭录制的操作。

3、对底层FFmpegRecord对象进行管理。

4、对录制文件进行管理——在开启录制的时候,检测当前目录文件的大小。

先给出开录制与关录制中整体的代码,然后再慢慢进行解释吧.

//开启录制的接口
QString CRecordMgr::StartRecord(eRecordType eType, QString sFileName, int iRecordSTime)
{
    QMutexLocker oLocker(&m_mutex);
    QString sPath = "/ics/recordfile";
    quint64 iCountByte = _DetectDiskInfo(sPath);

    if (iCountByte > DetectMinMB*1024*1024)
    {
        _RemoveRecordFile(sPath);
        QThread::msleep(1000);
    }

    if (sFileName.isEmpty())
    {
        qint64 timestamp = QDateTime::currentDateTime().toSecsSinceEpoch();
        sFileName = QString("%1.mp4").arg(timestamp);
    }

    _PreActionStart();
    QString sMissionId = CCommonFunc::CreateUUID();
    CFFmpegRecord *pFFmpegRecord = new CFFmpegRecord();

    if (pFFmpegRecord)
    {
        pFFmpegRecord->setObjectName(sMissionId);

        m_mapFFmpegRecord.insert(sMissionId, pFFmpegRecord);
        m_mapRecordFileName.insert(sMissionId, sFileName);
        m_mapRecordType.insert(sMissionId, eType);

        pFFmpegRecord->SetMissionId(sMissionId);
        pFFmpegRecord->SetRecordType((CFFmpegRecord::eRecordType)eType);
        pFFmpegRecord->SetRecordFileName(sFileName);

        pFFmpegRecord->Init();

        int iTimeId = startTimer((iRecordSTime+1)*1000);//多录制1s,防止最后一帧未录制完整
        m_mapTimerId.insert(sMissionId, iTimeId);
        m_oConnect = connect(gVideoMgr::instance(), &CVideoMgr::SIGNAL_CommonCameraImage, pFFmpegRecord, &CFFmpegRecord::SLOT_FFmpegImage, Qt::QueuedConnection);
        m_mapConnect.insert(sMissionId, m_oConnect);
    }

    return sMissionId;
}

//使用任务Id对录制任务进行关闭

bool CRecordMgr::StopRecord(CRecordMgr::eRecordType eType)
{
    m_setDeleteId.clear();

    QMap<QString, eRecordType>::iterator it;
    for (it = m_mapRecordType.begin(); it != m_mapRecordType.end(); ++it)
    {
        QString sId = it.key();
        CRecordMgr::eRecordType eRecordType = it.value();

        if (eType == eRecordType)
        {
            CFFmpegRecord *pFFmpegRecord = m_mapFFmpegRecord.value(sId);

            if (pFFmpegRecord)
            {
                pFFmpegRecord->StopRecord();

                QEventLoop eventloop;
                QTimer::singleShot(500, &eventloop, SLOT(quit()));
                eventloop.exec();

                QMetaObject::Connection oConnect = m_mapConnect.value(sId);
                disconnect(oConnect);
                CRecordMgr::eRecordType eRecordType = m_mapRecordType.value(sId);
                QString sFileName = m_mapRecordFileName.value(sId);

                int iTimerId = m_mapTimerId.value(sId);
                killTimer(iTimerId);

                if (m_mapFFmpegRecord.size() == 0)
                {
                    _PreActionEnd();
                }

                pFFmpegRecord->deleteLater();
                pFFmpegRecord = nullptr;

                emit SIGNAL_RecordTask_Finished(eRecordTy
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值