测试基础 某直播 App 问题分析

匿名 · April 07, 2017 · Last by 哎呀 第一章 replied at April 12, 2017 · 1844 hits
本帖已被设为精华帖!

原文:http://www.cnblogs.com/hyddd/p/6678930.html

某直播 App 问题分析

一. 出现问题

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

二. 分析

1. 直播架构分析

  • 根据 log 与抓包分析,其使用协议与后端架构如下:
  • 直播 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)
  • 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 同时,也抓了包:
  • 虽然有所卡顿,这段时间内数据包还是陆续有来的,卡 6、7s 不是很正常!根据上述代码,极有可能是 App 设置的 IO buffer 比较大,在网络环境较差情况下,触发 start 所需时间较长。

4. 其他分析

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

三. 分析过程中的一些坑

1. Shawdowsocks

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

由于没能逆向出 x.so 中的参数,所以以上分析是 结合现象与第三方源码 得出的结论,具有一定的主观性,作为分析思路分享大家,有其他想法欢迎交流!

赞!!!现在也有这方面的需求,能加 QQ(1505879845)好友指导下吗?

溜,这好文呀

—— 来自 TesterHome 官方 安卓客户端

这分析太牛逼了

这个给赞👍,QQ303103040 求交流

某直播是不是要给 BUG 分析费?

匿名 #7 · April 10, 2017

@tjj @xiaobeiying 还是这里交流,把讨论也分享他人

匿名 #8 · April 10, 2017
恒温 回复

@Lihuazhang 很久没写文章,算是冒个泡....

匿名 #9 · April 10, 2017
0x88 回复

多多益善啦~

思寒_seveniruby 将本帖设为了精华贴 10 Apr 13:44

分析的真到位学习了

赞赞,能加个 qq(1763162575) 嘛

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up