我正在尝试制作一个带有搜索栏的小型视频播放器(当然是 ffmpeg)。为此,我需要使用来自帧和/或数据包的数据来获取视频中应该在搜索滑块中设置的当前时间的功能。
它应该像这样工作:
my_time = get_cur_time()
seek(my_time + 10)
assert(my_time+10 == get_cur_time())
seek(my_time - 10)
assert(my_time-10 == get_cur_time())
我确实理解ffmpeg不支持精确搜索,所以这里的平等意味着“合理的cloae”。
到目前为止,我为此使用了什么代码:
frame_time = frame->pts*av_q2d(video_dec_ctx->time_base) * 1000;
其中 frame 是AVFrame
, video_dec_ctx 是AVCodecContext
。
并寻求:
int fn = ffmpeg::av_rescale(tsms,fmt_ctx->streams[video_stream->index]->time_base.den,
fmt_ctx->streams[video_stream->index]->time_base.num);
int frame = fn/1000;
printf("\t avformat_seek_file to %d\n",frame);
int flags = AVSEEK_FLAG_FRAME;
if (frame < this->frame->pts)
flags |= AVSEEK_FLAG_BACKWARD;
if(ffmpeg::av_seek_frame(fmt_ctx,video_stream->index,frame,flags))
{
printf("\nFailed to seek for time %d",frame);
return false;
}
avcodec_flush_buffers(video_dec_ctx);
int got_frame = 0;
do
if (av_read_frame(fmt_ctx, &pkt) >= 0) {
decode_packet_ro(&got_frame, 0);
av_free_packet(&pkt);
}
else
{
read_cache = true;
pkt.data = NULL;
pkt.size = 0;
break;
}
while(!(got_frame && this->frame->pts >= frame));
该代码确实可以通过前向搜索,但是在任何向后搜索的尝试之后我的第二个断言都失败了。搜索到上一个位置后,我获取时间的方法不会返回比搜索前少的位置。这导致我的搜索滑块工作非常不正确。