某直播App问题分析

某直播App问题分析

一. 出现问题

  • 观看自己开播的直播间,经常出现卡顿,而且画面一卡6,7s,重新播放时会出现跳帧,卡顿频率也较高,导致该App可用性极低。

二. 分析

1. 直播架构分析

  • 根据log与抓包分析,其使用协议与后端架构如下:
    46057-20170407171235613-1383939588.png
  • 直播server
    • 国内:福建泉州(联通)、广东佛山、肇庆(电信)
    • 国外:如果ss登陆韩国,则访问韩国机房
  • 拉流CDN
    • 国内:潮州(联通)、揭阳(电信)
    • 国外:如果ss登陆韩国,则访问韩国机房
  • 推流协议
    • RTMP
  • 拉流协议
    • Http-flv
  • 观看端播放器
    • bilibili-ijkplayer

2. log分析

  • 跟进log,发现每当视频卡住和播放时日志如下:

    04-06 16:43:27.027 19089-25159/? D/IJKMEDIA﹕ ffp_toggle_buffering_l: start
    04-06 16:43:27.028 19089-25158/? D/AudioTrack﹕ pause() mState 0
    04-06 16:43:27.028 19089-25123/? D/IJKMEDIA﹕ FFP_MSG_BUFFERING_START:

    ...

    04-06 16:43:33.502 19089-25125/? D/IJKMEDIA﹕ ffp_toggle_buffering_l: end
    04-06 16:43:33.503 19089-25123/? D/IJKMEDIA﹕ FFP_MSG_BUFFERING_END:
    04-06 16:43:33.504 19089-25158/? D/AudioTrack﹕ start() mState 2

  • 部分ijk-player源码(ff_ffplay.c)
    46057-20170407171238128-1617996445.png
    46057-20170407171236816-1613012216.png
    46057-20170407171240910-2009441631.png
  • ijkplayer处理流程为
    • read_thread---> stream_component_open---> decoder_start---> video_thread--->ffplay_video_thread
    • log中,触发pause原因是:ffplay_video_thread在frame_decode时,如果不能从buffer中拿到新的frame,则触发pause,直到buffer满足播放要求后再start。
  • 分析结果
    • 按上面的代码,应用卡顿直接原因:本地buffer为空导致播放停止。但从主播端->观看端整个流程看,网络状况、服务器性能都可能导致/加剧问题。

3. TCP抓包分析

  • 由于App经常卡顿、且卡顿时间较长,为确定是否网络导致,在dump log同时,也抓了包:
    46057-20170407171239378-1511055922.png
  • 虽然有所卡顿,这段时间内数据包还是陆续有来的,卡6、7s不是很正常!根据上述代码,极有可能是App设置的IO buffer比较大,在网络环境较差情况下,触发start所需时间较长。
    46057-20170407171241972-1579131623.png

4. 其他分析

  • 在buffer方面,ijkplayer至少有2类buffer,一是上面提到的IO buffer,另外一类是显示buffer。
    46057-20170407171248066-617022055.png
  • IO线程把数据读到后,再把数据喂给显示线程,上述2类buffer分别属于这2个线程。
  • 在使用App过程中,当log中输出D/AudioTrack﹕ start()后,画面马上更新(可能伴随跳帧),且无延迟,所以推测:
    • 该App显示buffer相当小
    • 有做额外的丢帧处理
  • 这估计是导致该应用播放频繁卡顿、且跳帧的原因!!!

三. 分析过程中的一些坑

1. Shawdowsocks

  • 本次FQ在OpenWrt上直接部署ss-local进行全局FQ,在抓包时候发现 推流 与 拉流 服务器皆为国内服务器,作为一个海外直播App,国外用户要FQ过来访问墙内服务器实在费解,遂在ss-server上ping相关域名获取ip,发现ss-server获取的ip是国外,按ss原理,DNS解析应在ss-server执行。后面经过排查,发现问题出在OpenWrt上,OpenWrt处理流程是:接到请求,DNS解析(此时,域名对应ip已经解析完毕),出口时走ss-local,到ss-server,访问之前DNS解析后的ip,所以之前是走了一圈国外再回国内,蛋疼!
发布了184 篇原创文章 · 获赞 31 · 访问量 17万+

Android端使用Ijkplayer如何修改使RTSP延时降低

11-22

我在做Android端Ijkplayer的播放器,在局域网的情况下,使用1080p的分辨率, 用rtsp协议播放码流,使用ffmpeg最快可以达到440ms,使用Ijkplayer,设置一些option 之后只有最快700ms,请问如何设置才能起码降低到500ms或者更低 我的设置如下 //是否开启变调 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"soundtouch",1); //设置是否开启环路过滤: 0开启 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC,"skip_loop_filter",48L); //设置播放前的最大探测时间 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzemaxduration",50L); //设置播放前的探测时间 1,达到首屏秒开效果 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzeduration",1); //播放前的探测Size,默认是1M, 改小一点会出画面更快 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"probesize",1024*3); //每处理一个packet之后刷新io上下文 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"flush_packets",1L); //是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"packet-buffering",1); //不要限制输入缓冲区大小(与实时流一起使用) //ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"infbuf",1); //播放重连次数 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"reconnect",5); //最大缓冲大小,单位kb //ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"max-buffer-size",maxCacheSize); //跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"framedrop",5); //最大fps ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"max-fps",30); ``` ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览