我怎样才能用ffmpeg寻找第X号?

我正在编写一个video编辑器 ,我需要寻找确切的帧,知道帧编号

在stackoverflow上的其他post告诉我,ffmpeg可能会给我几个打破框架后,这不是一个播放的问题,但对video编辑的一个大问题。

而且我需要按照帧号来查找, 而不是按时间来查找,这样在转换为帧号时会变得不准确。

我已经阅读过dranger的内容(现在已经过时了),最后是:

av_seek_frame(fmt_ctx, video_stream_id, frame, AVSEEK_FLAG_ANY); 

它总是寻No. 0帧,总是return 0意味着成功。 然后我尝试阅读Blender的源代码,发现它非常复杂(也许我应该实现一个图像缓冲区?)。

那么,有没有什么简单的方法来寻求一个简单的调用像seek(context, frame_number) (而获得一个完整的框架,而不是一个破碎的一个框架)? 或者,有没有简化这个轻量级库?

编辑:由于praks411 ,我发现解决scheme:

 void AV_seek(AV * av, size_t frame) { int frame_delta = frame - av->frame_id; if (frame_delta < 0 || frame_delta > 5) av_seek_frame(av->fmt_ctx, av->video_stream_id, frame, AVSEEK_FLAG_BACKWARD); while (av->frame_id != frame) AV_read_frame(av); } void AV_read_frame(AV * av) { AVPacket packet; int frame_done; while (av_read_frame(av->fmt_ctx, &packet) >= 0) { if (packet.stream_index == av->video_stream_id) { avcodec_decode_video2(av->codec_ctx, av->frame, &frame_done, &packet); if (frame_done) { ... av->frame_id = packet.dts; av_free_packet(&packet); return; } } av_free_packet(&packet); } } 

Solutions Collecting From Web of "我怎样才能用ffmpeg寻找第X号?"

av_seek_frame只会根据关键帧的时间戳进行查找。 既然它寻求关键帧,你可能得不到你想要的。 因此,建议寻求最近的关键帧,然后逐帧阅读,达到所需的帧。

但是,如果您正在处理固定的FPS值,则可以轻松地将时间戳映射到帧索引。

在寻找之前,如果你已经指定了流,你需要将你的时间转换成AVStream.time_base单位。 在avformat.h阅读av_seek_frame ffmpeg文档。

例如,如果你想寻求1.23秒的剪辑:

  double m_out_start_time = 1.23; int flgs = AVSEEK_FLAG_ANY; int seek_ts = (m_out_start_time*(m_in_vid_strm->time_base.den))/(m_in_vid_strm->time_base.num); if(av_seek_frame(m_informat, m_in_vid_strm_idx,seek_ts, flgs) < 0) { PRINT_MSG("Failed to seek Video ") }