我正在尝试制作一个寻求酒吧的小视频播放器(当然还有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())
我明白theffmpeg并不支持精确搜索,所以这里的平等意味着“合理的事情”。
到目前为止,我使用了什么代码:
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));
代码确实向前寻求,但在任何向后寻求我的第二个断言的尝试失败之后。在寻求以前的位置之后,我的获取时间的方法在寻求之前不会返回位置。这导致我的搜索滑块严重错误地工作。