ffmpeg提供了如下命令行用于截取指定时间范围内的视频:
ffmpeg -i c:\record\out_computer.mp4 -ss 00:00:10 -to 00:00:39 out_computer_2second.mp4
我跟了下ffmpeg命令行代码,没有使用滤镜,直接读取的视频AVPacket,用里面的pts判断是否在时间范围内。
如果读取到的pts小于起始时间,则读取下一帧,接着判断。
如果读取到的pts大于结束时间,则结束。
本人为此专门写了一个工程,该工程考虑了只有视频,没音频的文件。
main函数的内容如下,通俗易懂:
int main()
{
CTrimFile cVideoTrim;
const char *pFileA = "c:\\record\\out-computer.mp4";
const char *pFileOut = "c:\\record\\out-computer_trimmed.mp4";
std::string strBeginTime = "00:00:10";
std::string strEndTime = "00:00:20";
int iStartTime = TimeToSeconds(strBeginTime);
int iEndTime = TimeToSeconds(strEndTime);
int iDuration = iEndTime - iStartTime;
cVideoTrim.StartTrim(pFileA, pFileOut, iStartTime, iDuration);
cVideoTrim.WaitFinish();
return 0;
}
下面是读取文件的部分代码,红色方框显示了帧的过滤逻辑

代码结构如下:

FfmpegTrimTest.cpp的内容如下:
#include <iostream>
#include "TrimFile.h"
#include <vector>
#ifdef __cplusplus
extern "C"
{
#endif
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")
#pragma comment(lib, "postproc.lib")
#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endif
void SeparateString(const char* pStr, std::vector<int>& vecResult, char chKey)
{
if (pStr == NULL || pStr[0] == 0)
{
return;
}
std::string tmp = pStr;
if (tmp.at(tmp.length() - 1) != chKey)
{
tmp += chKey;
}
size_t beginIndex = 0;
static const size_t npos = size_t(-1);
size_t indexCh1a = tmp.find(chKey, beginIndex);
std::string tmpBuf;
while (indexCh1a != npos)
{
int len = static_cast<int>(indexCh1a - beginIndex);
if (len > 0)
{
tmpBuf.clear();
tmpBuf.append(tmp.c_str() + beginIndex, static_cast<size_t>(len));
vecResult.push_back(atoi(tmpBuf.c_str()));
}
beginIndex = ++indexCh1a;
indexCh1a = tmp.find(chKey, beginIndex);
}
}
///00:00:10这种类型的时间转化为秒数
int TimeToSeconds(std::string strTime)
{
int iRetSecond = 0;
std::vector<int> vecTime;
SeparateString(strTime.c_str(), vecTime, ':');
if (vecTime.size() != 3)
{
return iRetSecond;
}
int iHour = vecTime[0];
int iMinute = vecTime[1];
int iSecond = vecTime[2];
iRetSecond = iHour * 3600 + iMinute * 60 + iSecond;
return iRetSecond;
}
int main()
{
CTrimFile cVideoTrim;
const char *pFileA = "c:\\record\\out-computer.mp4";
const char *pFileOut = "c:\\record\\out-computer_trimmed.mp4";
std::string strBeginTime = "00:00:10";
std::string strEndTime = "00:00:20";
int iStartTime =

本文介绍使用FFmpeg命令行工具及C++编程实现视频指定时间段的截取。通过示例代码展示了如何设置开始和结束时间,利用AVPacket判断视频帧时间戳来过滤并截取目标片段。
最低0.47元/天 解锁文章
9898

被折叠的 条评论
为什么被折叠?



