前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ffmpeg-视频操作

ffmpeg-视频操作

作者头像
sofu456
发布2020-11-12 11:28:12
4300
发布2020-11-12 11:28:12
举报
文章被收录于专栏:sofu456

视频截取合并

代码语言:javascript
复制
__int64 index_context = 0, last_start_pts=0;
std::list<AVFormatContext*> ifmt_ctx_lst;
AVFormatContext *ofmt_ctx = nullptr, *ifmt_ctx = nullptr;
void BeginSplitFile(const char* file, const char* out_file)
{
	index_context = 0;
	AVFormatContext* ifmt_ctx_item = nullptr;
	if ((avformat_open_input(&ifmt_ctx_item, file, 0, 0)) < 0)
		return;
	ifmt_ctx_lst.push_back(ifmt_ctx_item);
	if ((avformat_find_stream_info(ifmt_ctx_item, 0)) < 0)
		return;
	if (ofmt_ctx != nullptr) return;
	avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_file);
	if (!ofmt_ctx)	return;
	for (unsigned int i = 0; i < ifmt_ctx_item->nb_streams; i++) {
		AVStream *out_stream, *in_stream = ifmt_ctx_item->streams[i];
		AVCodecParameters *in_codecpar = in_stream->codecpar;
		out_stream = avformat_new_stream(ofmt_ctx, NULL);
		if (!out_stream) return;
		if (avcodec_parameters_copy(out_stream->codecpar, in_codecpar) < 0)
			return;
		out_stream->codecpar->codec_tag = 0;
	}
	if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)){
		if (avio_open(&ofmt_ctx->pb, out_file, AVIO_FLAG_WRITE) < 0)
			return;
	}
	if (avformat_write_header(ofmt_ctx, NULL) < 0)
		return;
}
void SplitFile(double from, double to)
{
	std::list<AVFormatContext*>::iterator it = ifmt_ctx_lst.begin();
	std::advance(it, index_context);
	AVFormatContext* ifmt_ctx_item = *it;
	index_context++;
	if (!ifmt_ctx_item || av_seek_frame(ifmt_ctx_item, -1, (__int64)from * AV_TIME_BASE, AVSEEK_FLAG_ANY) < 0)
		return;

	__int64 start_pts = -1;
	for (int i = 0;; i++){
		AVPacket pkt;
		AVStream *in_stream, *out_stream;
		if (!ifmt_ctx_item || av_read_frame(ifmt_ctx_item, &pkt) < 0)
			break;
		in_stream = ifmt_ctx_item->streams[pkt.stream_index];
		out_stream = ofmt_ctx->streams[pkt.stream_index];

		double time_stamp = av_q2d(in_stream->time_base) * pkt.pts;
		if (time_stamp > to){
			last_start_pts = pkt.pts - start_pts;
			break;
		}
		if (start_pts == -1)	start_pts = pkt.pts;
		pkt.pts = av_rescale_q_rnd(pkt.pts - start_pts + last_start_pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
		pkt.dts = av_rescale_q_rnd(pkt.dts - start_pts + last_start_pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
		pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
		pkt.pos = -1;
		if (!ofmt_ctx || av_interleaved_write_frame(ofmt_ctx, &pkt) < 0)
			break;
		av_packet_unref(&pkt);
	}
	
}
void EndSplitFile()
{
	index_context--;
	AVFormatContext* it = ifmt_ctx_lst.front();
	if (it) avformat_close_input(&it);
	ifmt_ctx_lst.pop_front();

	if (ifmt_ctx_lst.size() == 0){
		if (ofmt_ctx) av_write_trailer(ofmt_ctx);
		if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
			avio_closep(&ofmt_ctx->pb);
		if (ofmt_ctx) {
			avformat_free_context(ofmt_ctx);
			ofmt_ctx = nullptr;
		}
	}
}

__int64 GetFileTimeSpan(const char* file)
{
    AVFormatContext *ifmt=avformat_alloc_context();
    if(avformat_open_input(&ifmt,file,NULL,NULL)<0)
        return -1;
    __int64 tduration=ifmt->duration;
    avformat_close_input(&ifmt);
    avformat_free_context(ifmt);
	return tduration / AV_TIME_BASE;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 视频截取合并
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档