文件切割是一項很常見的基本功能,通過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_3/
Demo下載地址: http://www.chungen90.com/?news_2