Ffmpeg 实现文件切割

Posted 王纲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ffmpeg 实现文件切割相关的知识,希望对你有一定的参考价值。

 文件切割是一项很常见的基本功能,通过Ffmpeg可以很容易实现这项功能。

  首先介绍下基本原理,文件切割说白了就过滤掉文件的部分音视频包,按照什么规则过滤呢?

答案是时间戳。文件中每个视频及音频包都有时间戳用来标识在哪个时间点该包被播放。当我们有过滤需求,

比如需要过滤掉视频文件的第3分钟到5分钟的视频,首先我们需要计算第三分钟及第五分钟的音视频包时间

戳区间,然后遍历视频文件中所有音视频包时间戳,不再查找区间的音视频包直接丢弃,最后将后半段音视频包

时间戳一致前移即可。

    基于Ffmpeg的开发流程如下图所示:

图1 视频文件切割流程图

下面介绍代码:

一. 打开视频文件获取音视频流信息

int OpenInput(string inputUrl)
{
	inputContext = avformat_alloc_context();	
	lastReadPacktTime = av_gettime();
	inputContext->interrupt_callback.callback = interrupt_cb;
	int ret = avformat_open_input(&inputContext, inputUrl.c_str(), nullptr,nullptr);
	if(ret < 0)
	{
		av_log(NULL, AV_LOG_ERROR, "Input file open input failed\\n");
		return  ret;
	}
	ret = avformat_find_stream_info(inputContext,nullptr);
	if(ret < 0)
	{
		av_log(NULL, AV_LOG_ERROR, "Find input file stream inform failed\\n");
	}
	else
	{
		av_log(NULL, AV_LOG_FATAL, "Open input file  %s success\\n",inputUrl.c_str());
	}
	return ret;
}

 二. 计算过滤区间

//第20S开始,去掉8S
int startPacketNum = 500;
 int  discardtPacketNum = 200;

 三 遍历过滤

while(true)
{
	auto packet = ReadPacketFromSource();
	if(packet)
	{
	    packetCount++;
	    if(packetCount <= 500 || packetCount >= 700)
	    {
			if(packetCount >= 700)
			{
				if(packet->pts - lastPacketPts > 120)
				{
					lastPts = lastPacketPts ;
				}
				else
				{
					auto diff = packet->pts - lastPacketPts;
					lastPts += diff; 
				}
			}
			lastPacketPts = packet->pts;
			if(lastPts != AV_NOPTS_VALUE)
			{
			  packet->pts = packet->dts = lastPts;
			}
			ret = WritePacket(packet);
		}
	}
	else
	{
	  break;
	}
}

  完整代码下载地址:http://pan.baidu.com/s/1o8Lkozw

如需交流,可以加QQ群1038388075,766718184,或者QQ:350197870

 

视频下载地址:http://www.chungen90.com/?news_33/

 Demo下载地址: http://www.chungen90.com/?news_34

以上是关于Ffmpeg 实现文件切割的主要内容,如果未能解决你的问题,请参考以下文章

Ffmpeg 实现文件切割

ffmpeg如何批量切割视频尾部4秒?

使用 ffmpeg 生成单个 MPEG-Dash 片段

ffmpeg 截取切割视频报错

php代码片段: sendFile/videoStream/sendEmail/phpexcel/ffmpeg/zip

如何用ffmpeg截取视频片段&截取时间不准确的坑