文章目录

  • 1,准备知识,
    • seek代码流程:
    • 策略:
  • 2,问题描述,
  • 3,原因分析及其修改,
    • 拿到这个问题,在不debug代码或查看日志的情况下,根据上面1的准备知识,可以大概判断出原因。
    • 针对问题视频,对于上面几个值查看,以及代码修改

1,准备知识,

seek代码流程:

首先,调用seek设置pls->seek_timestamp等参数

ffplay.c:avformat_seek_file->av_seek_frame -> utils.c:seek_frame_internal -> hls.c:hls_read_seek

然后,在read_thread里读取packet时是否有seek操作,有的话则判断当前packet和seek time比较是否有效

utils:av_read_frame->…->hls.c:hls_read_packet

策略:

当seek时间值超过了视频结束时间 即seek_timestamp - HLSContext:first_timestamp > duration时直接返回错误;

当seek时间值小于视频开始时间 即seek_timestamp < HLSContext:first_timestamp时返回错误(find_timestamp_in_playlist函数里);

在hls.c:hls_read_packet读取packet时,会去查看当前的pls->seek_timestamp值,如果有seek操作这里pls->seek_timestamp会有赋值,将pls->seek_timestamp和读取到的packet dts比较,如果小于0则直接调用av_packet_unref(&pls->pkt)回收掉这个packet(这里会循环读取packet值的,不会返回空的packet给ffplay的),大于零才会返回当前的读取的packet。

2,问题描述,

基于ffmpeg的播放器播放m3u8文件的ts视频,seek时,有的视频出现无法seek到0或者结尾,有的就是无法seek到任何地方。

3,原因分析及其修改,

拿到这个问题,在不debug代码或查看日志的情况下,根据上面1的准备知识,可以大概判断出原因。

  1. 有的视频出现无法seek到0的问题,可以考虑是在如上策略中描述的,seek时间值(0)小于视频开始时间HLSContext:first_timestamp导致的。
  2. 有的视频出现无法seek到结尾的问题,可以考虑是在如上策略中描述的,seek时间值与HLSContext:first_timestamp的差大于视频duration导致的。
  3. 至于其它的seek无法到达,可能大概率是在如上策略中描述的第三种情况,seek time的值与当前packet dts(解码时间戳)值的差值大于零导致认为未到达seek的time值,就丢弃了。

总的来说,大概就是相关的几个变量的值可能有异常,包括:用户传进来的seek time值、当前视频片段的起始时间值HLSContext:first_timestamp、duration值、读取出来的packet的dts值等

针对问题视频,对于上面几个值查看,以及代码修改

debug代码查看seek time传值,发现传值的确是0,可是seek后就是到不了0的位置,输出日志,发现视频文件的起始时间不是0,而是大于0的值,所以在外面传值时将ffplay.c:stream_seek方法里的代码做如下修改

     //add by lxs startint64_t start_time = is->ic->start_time;if(start_time > 0 && start_time != AV_NOPTS_VALUE){pos += start_time;}//add by lxs endis->seek_pos = pos;is->seek_rel = rel;is->seek_flags &= ~AVSEEK_FLAG_BYTE;if (seek_by_bytes)is->seek_flags |= AVSEEK_FLAG_BYTE;is->seek_req = 1;SDL_CondSignal(is->continue_read_thread);

上面修改后大部分AVFormatContext start_time大于零的问题解决了,但是还是有些视频无法seek到0,或者结尾。怀疑是不是外面的AVFormatContext:start_time和里面的HLSContext:first_timestamp不相等,使用如下命令导出frames信息

ffprobe -show_frames /c/Users/Administrator/Downloads/2499929067_1947651037_1.ts > /c/Users/Administrator/Downloads/3hh.txt

打开3hh.txt文件查看,发现audio第一帧和video第一帧的pts/dts不一样,所以怀疑是两个分别被赋值给了上面的AVFormatContext:start_time和HLSContext:first_timestamp导致两个值不一样。

[FRAME]
media_type=audio
stream_index=1
key_frame=1
pkt_pts=31680
pkt_pts_time=0.352000
pkt_dts=31680
pkt_dts_time=0.352000
best_effort_timestamp=31680
best_effort_timestamp_time=0.352000
pkt_duration=1920
pkt_duration_time=0.021333
pkt_pos=34780
pkt_size=206
sample_fmt=fltp
nb_samples=1024
channels=2
channel_layout=stereo
[/FRAME]
[FRAME]
media_type=audio
stream_index=1
key_frame=1
pkt_pts=35550
pkt_pts_time=0.395000
pkt_dts=35550
pkt_dts_time=0.395000
best_effort_timestamp=35550
best_effort_timestamp_time=0.395000
pkt_duration=1920
pkt_duration_time=0.021333
pkt_pos=36472
pkt_size=215
sample_fmt=fltp
nb_samples=1024
channels=2
channel_layout=stereo
[/FRAME]
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=29970
pkt_pts_time=0.333000
pkt_dts=29970
pkt_dts_time=0.333000
best_effort_timestamp=29970
best_effort_timestamp_time=0.333000
pkt_duration=3000
pkt_duration_time=0.033333
pkt_pos=564
pkt_size=31935
width=1920
height=1080
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
color_range=unknown
color_space=unknown
color_primaries=unknown
color_transfer=unknown
chroma_location=left
[/FRAME]

结合日志的确两者值不一样。所以在hls.c:hls_read_packet方法里给HLSContext:first_timestamp赋值的地方,将值修改为AVFormatContext:start_time,这样保证两者值一样。修改如下

                    /*if (c->first_timestamp == AV_NOPTS_VALUE &&pls->pkt.dts       != AV_NOPTS_VALUE)c->first_timestamp = av_rescale_q(pls->pkt.dts,get_timebase(pls), AV_TIME_BASE_Q);*/if(c->first_timestamp != (s->start_time != AV_NOPTS_VALUE ? s->start_time : 0))c->first_timestamp = s->start_time != AV_NOPTS_VALUE ? s->start_time : 0 ;

这样大部分问题解决了。可是还是一些视频源无法seek到某些位置。

最后发现一些dts值异常,比如我的这个视频源,在seek 传start time值的位置packet的dts为0,但是start time并不为0,导致计算异常。在hls.c:hls_read_packet方法里修改如下:

              //modify by lxs startint64_t pkt_ts;if (pls->pkt.pts != AV_NOPTS_VALUE)pkt_ts =  pls->pkt.pts;else if (pls->pkt.dts != AV_NOPTS_VALUE)pkt_ts =  pls->pkt.dts;elsepkt_ts = AV_NOPTS_VALUE;tb = get_timebase(pls);ts_diff = av_rescale_rnd(pkt_ts/*pls->pkt.dts*/, AV_TIME_BASE,tb.den, AV_ROUND_DOWN) -pls->seek_timestamp;//modify by lxs end

好了,目前就发现这些问题,后面有新的再增加。

基于ffmpeg的播放器,播放m3u8文件时,seek问题相关推荐

  1. 最简单的基于FFMPEG+SDL的音频播放器

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  2. 最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  3. 最简单的基于FFMPEG SDL的音频播放器

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...

  4. 最简单的基于FFMPEG+SDL的音频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  5. 最简单的基于FFMPEG+SDL的音频播放器 拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  6. 基于FFmpeg和Qt的播放器 QtAV库

    参与项目开发: https://github.com/wang-bin/QtAV 下载编译好的文件等:https://sourceforge.NET/projects/qtav win下编译好的可执行 ...

  7. C++基于ffmpeg和QT开发播放器~学习笔记

    C++基于ffmpeg和QT开发播放器 B站网址 https://www.bilibili.com/video/BV1h44y1t7D8?p=2&spm_id_from=pageDriver ...

  8. 基于Ffmpeg解码器的简单播放器(a simple audio player based on Ffmpeg)

    这是一个基于Ffmpeg解码器的简单播放器,怎么在Windows上编译Ffmpeg可以在网上找到很多,开发环境是Windows XP SP3+VS2008,其中DirectSound控制单元来自jdk ...

  9. 使用 阿里云 播放器播放 .flv 和 hls(.m3u8) 格式的视频流

    一.使用 阿里云 播放器播放 .flv 和 hls(.m3u8) 格式的视频流 官方教程:https://help.aliyun.com/document_detail/125570.htm?spm= ...

最新文章

  1. 20210927 LQR
  2. jmeter测试元件--控制器
  3. gitlab 开源项目 星_49必须了解的机器学习开源项目,Github上平均3600星
  4. Playfab开发(一)如何调用PlayFab接口
  5. react todolist代码优化
  6. 【项目管理】外包和采购
  7. 图像修复效果惊艳,一行命令就能实现!
  8. oracle rac单节点恢复,如何Oracle_RAC恢复一个节点总结
  9. lay-verify=required 没生效_眼睛一闭一睁,20万没了!|侧翻|交通事故|半挂车|追尾...
  10. 深度学习2.0-23.Keras高层接口之CIFAR10自定义网络实战
  11. 【原创】CGAL使用心得
  12. 在SSRS报表中,显示图片
  13. Atitit it计算机应用体系图  大数据 爬虫 非结构数据 nosql redis mongodb 分布式存储 es搜索 可视化 多媒体与office 19.1. 14.3 计
  14. KELl警告: MULTIPLE CALL TO SEGMENT
  15. python opencv 将lena图像嵌入空白画布处
  16. Akash,全球首个去中心化云计算
  17. 三菱fx5u modbus tcp fb块用法_一文教会你,如何掌握三菱FX5U PLC基础知识
  18. 记录下生活:ETC卡充值(上海)
  19. 计算机 绘图 教案,计算机绘图2教案.doc
  20. 作为一个前端开发工程师,你会怼人吗?

热门文章

  1. 怎样才算定金,定金和订金的区别是什么
  2. ​Python中的经典时间序列预测模型总结
  3. 树莓派:解决4B升级到Bullseye后xrdp不响应的问题
  4. 【计算机专业漫谈】【计算机系统基础学习笔记】W1-计算机系统概述
  5. 物联网技术在公共建筑能源管理系统中的应用
  6. Java开发大型互联网高并发架构实战之原理概念分析
  7. Android高工面试:用Glide加载Gif导致的卡顿,说一下你的优化思路
  8. input 输入框限制只能输入两位有效小数
  9. DRF如何序列化外键的字段
  10. 基于HTML5的移动Web应用——Bootstrap 样式案例:制作美联英语在线VIP页面微电影