FFplay跳转时间点播放
  1bTlX33AWdQ4 2023年11月02日 78 0

播放器的最常用的功能之一 就是快进快退,快进快退的本质就是让 mp4文件 跳转到另一个时间点来播放。

FFplay 播放器有两种方式可以让 mp4文件 跳转到另一个时间点来播放。

1,在命令行里里使用 ​​-ss​​ 参数,如下,跳到到第 60 秒的地方开始播放。

ffplay -x 400 -ss 60 -i juren.mp4

2,在播放过程中,按上下左右减,进行快进后退操作。

上面这两种跳转时间点播放的方式,其实都是调 ​​avformat_seek_file()​​ 来实现的,都是在 ​​read_thread()​​ 线程函数里面进行 seek 操作的。


先来讲解命令行的 ​​-ss​​ 的原理,代码如下:

FFplay跳转时间点播放_FFplay

可以看到,是用 ​​opt_seek()​​ 函数来接受 ​​-ss​​ 参数的,代码如下:

提示:更多命令行参数解析的细节,请阅读《​​parse_options命令行参数解析​​》

FFplay跳转时间点播放_FFplay_02

可以看到,最后赋值到了 全局变量 ​​start_time​​,然后 ​​start_time​​ 变量会在 ​​read_thread()​​ 函数入口不远的地方被使用,如下:

FFplay跳转时间点播放_FFplay_03

注意,上面的 seek 是在 ​​for(;;) {...}​​ 循环之前的。


接着讲一下播放过程中 快进后退的实现。当按下 ↓ 键的时候,就会后退进 60s ,看一下代码实现:

FFplay跳转时间点播放_FFplay_04

从上图可以发现,有两种 seek 方式,一种是按时间 seek (默认),一种是 按字节 seek。

如果是按字节 seek,就会把时间转成字节位置。

无论是字节 seek,还是时间 seek,都是绝对的。例如绝对时间 跟 绝对位置。

​frame_queue_last_pos()​​ 获取当前视频流,或者音频流播放到哪个字节位置了,再加上 incr (相对)。

​get_master_clock()​​ 获取当前主时钟播放到第几秒了,然后再加上 incr (相对)。

最后调 ​​stream_seek()​​ 记录要跳转的位置,注意 ​​stream_seek()​​ 只是记录一下位置,并不会进行跳转操作。

FFplay跳转时间点播放_FFplay_05

那 ​​is->seek_req​​ 跟 ​​is->seek_pos​​ 会在哪里被使用呢?在 ​​read_thread()​​ 里面。

在播放一个 mp4 文件的时候,​​read_thread()​​ 会一直阻塞在 ​​for(;;) {...}​​ 循环里面,不断调 ​​av_read_frame()​​ 读取 ​​AVPacket​​ 出来。如下:

FFplay跳转时间点播放_FFplay_06

但是在 调 ​​av_read_frame()​​ 之前,会检测一下 ​​is->seek_req​​ 是否为 1,为 1 代表有 seek 请求发生,如下:

FFplay跳转时间点播放_FFplay_07

上图中,​​avformat_seek_file()​​ 之后,就需要用 ​​packet_queue_flush()​​ 清空之前队列里面的缓存,还有刷新序列号。序列号的内容请看《​​FFplay序列号分析​​》

​seek​​ 之后还会更新外部时钟,因为外部时钟就是预定的播放时刻,跳转的就是预定的播放时刻。

if (is->seek_flags & AVSEEK_FLAG_BYTE) {
set_clock(&is->extclk, NAN, 0);
} else {
set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
}

FFplay跳转时间点播放 分析完毕。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: FFplay暂停分析 下一篇: FFplay外部时钟分析
  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  1bTlX33AWdQ4   2023年11月02日   76   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   78   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   55   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   38   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   55   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   52   0   0 FFplay
  1bTlX33AWdQ4   2023年11月13日   44   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   67   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   39   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   70   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   60   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   58   0   0 FFplay
  1bTlX33AWdQ4   2023年11月02日   54   0   0 FFplay
1bTlX33AWdQ4