前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我攻克的技术难题安卓小程序推流声音失真卡顿问题

我攻克的技术难题安卓小程序推流声音失真卡顿问题

原创
作者头像
liuzhen007
发布2024-01-27 15:36:25
2160
发布2024-01-27 15:36:25
举报
文章被收录于专栏:流媒体音视频流媒体音视频

项目背景

近年来,随着人们生活方式的改变,直播带货日益成为大家必不可少的一种购物选择。直播连麦也是直播间的基础功能之一,今年 618 大促前,本人收到了一个关于直播连麦的问题反馈。用户反馈说华为手机(安卓)小程序推流时声音持续卡顿,始终不会恢复且稳定复现,但是 iOS 小程序推流时声音却是正常的。

二、疑惑

经过一系列常规处理后,问题依然存在。于是,针对这个问题,本人进行简单的信息整理汇总,得出了如下疑问。

疑惑点1、同样是小程序推流,为什么安卓有问题,iOS 就没有问题?

疑惑点2、服务器和客户端代码都进行了回退,问题依然存在,什么情况?

疑惑点3、最近服务器和客户端的代码基本上都没有更新过,为什么突然出现问题?

三、排查

针对上面的疑问,本人后续进行了更加详细的排查工作。

解惑1

首先,针对疑惑1,在线上环境复现后,发现确实是这个结论。相同环境,涉及的流媒体服务、业务服务、拉流端设备都一样,只是切换上麦推流的移动端设备,使用华为手机推流声音就有问题,iOS 设备声音就没有问题。后来进一步验证发现,不仅是华为手机,所有的安卓手机小程序推流声音都有问题。

按照一般的思路,既然 iOS 设备的小程序没有问题,理论上安卓设备的小程序也不应该有问题,那么很可能是后续链路出现了问题。也正是因为这种认知,导致前期的排查思路被带歪了。首先,来看一下小程序上麦的媒体数据流向示意图。

基于上图分析,我们排除了小程序的问题,那么就逐一分析后续流程涉及的各个模块。

首先是 RTMP 服务,因为小程序推流是 rtmp 协议的,用来接收小程序上行的媒体流。线上使用的 RMTP 服务是一个标准的开源服务,基本上没有进行过私有化改造,而且近两年年都来没有更新过,因此,首先排除了它的问题。

接下来,再说直播媒体服务,简称 MS(Media Server),它是直播专用的流媒体服务,几乎所有的直播和 RTC 场景中都会使用到它。在该场景中,MS 服务的作用是使用 ffmpeg 从 RTMP 服务拉取 rtmp 格式的媒体流,然后转换成 rtp 格式的媒体流,注意:此时的 rtp 媒体流中音频和视频是分开的,它们使用不同端口。之后的流程就是标准的 WebRTC 用法,媒体数据经过 producer 吐给 comsumer,最终以 rtp 包的形式给到对应的拉流端,拉流端可以是标准的 Web 页面,也可以是 Native 终端。所以说,有可能是 MS 服务中的某个环节导致了声音问题。

最后,说一下拉流端,拉流端的工作主要进行音频解包、音频解码、音频渲染等环节,一般来说,解码和渲染是最有可能出问题的。我们先用 Chrome 浏览器的 WebRTC 标准工具 webrtc-internals 来分析一下,在 Chrome 浏览器的地址栏中输入 chrome://webrtc-internals 命令就会看到 WebRTC 发送和接收的媒体统计数据。

有了上面的工具,我们先来看一下 iOS 设备小程序推流时,Chrome 浏览器拉流的音频数据统计情况,如下图所示:

其中,ConcealedSample/s 参数表示由于音频包由于丢失或者时间戳跨度太大而采取音频补偿的情况,此时该数值接近于0。反观安卓设备小程序推流的情况,concealedSample/s 数据始终在 2.5k/s 左右,影响了声音的正常播放。

解惑2

尽管最近没有更过和音视频需求相关的服务,也无法保证不是代码改动引入的新问题,为了快速定位是不是代码更新导致的声音异常。我们尝试将服务器和客户端的代码都回退到去年年初的时间点,再次测试后的结论让我们非常郁闷,声音卡顿问题依然存在。不过这也说明了一个问题,声音问题不是新代码引入的 Bug。

由于拉流端的表现都是一致的,无论是 Web 还是 Native 拉流时,安卓小程序的声音都卡顿。因此,可以排除是拉流端渲染异常导致的声音问题。既然现有的变量都没有问题,那么还有什么被忽略的变量呢?带着这个疑问,我们往下看。

解惑3

针对疑惑3,综合研发同学和 QA 同学的反馈,去年年底的时候,安卓小程序推流音频还是正常的,而且之后流媒体服务器和客户端都没有进行过相关功能的升级。用户一直用得好好的,为什么突然反馈了这样一个问题?难道是之前 QA 的测试项遗漏了?和用户确认后,之前确实是好用的,但是最近几次使用都遇到了声音卡顿问题。

综合所有的信息,其实我们还忽略了一个变量,那就是微信,没错,微信的版本升级。换句话说,有没有可能是微信自己升级出现了 Bug?通过微信官网的发版列表可以知道,移动端设备(Android和iOS)基本上每个月都会有一个版本迭代,具体情况如下图所示:

既然怀疑是微信版本升级引入的问题,那就安装一个之前的版本验证一下,这样最有说服力。当时最新的版本是8.0.36,于是,自己下载了较早的8.0.0版本。

因为微信不支持版本回退,只能重新安装,连接手机数据线,使用如下命令安装:

adb install -f wechat.apk

安装完成后,登录账号,重新进入房间推流,声音卡顿问题消失了,Nice,终于破案了。

确定了问题的基本方向,于是我们在 MS 流媒体服务器上进行音频抓包,分析音频帧的时间戳,果然发现了问题,音频帧的时间戳间隔不是固定的,有时候间隔很小,有时候间隔很大。好了,至此,我们确定了声音卡顿问题的根本原因。

四、方案

既然,我们已经知道了问题真正的原因,那接下来就说一下解决方案,通过模块划分大体上有三种方案,下面分别介绍。

方案1

既然是安卓小程序推的音频流有问题,首先想到的就是在源头上解决问题,但是了解小程序直播业务开发的小伙伴一定都知道小程序的底层 SDK 是腾讯提供的,特别是音视频能力,很多接口都没有暴露出来。我们想修改小程序底层这条路是行不通的。

方案2

既然不能直接修改小程序底层 SDK,那就在后续流程模块中做兼容处理吧。其实,方案二和方案三都是兼容和修复的思路。

方案二就是修改 RTMP 服务,通过上文的流程图,我们可以知道 RTMP 服务是小程序上行媒体流的接收者,可以在这里进行音频时间戳的平滑处理。方案肯定是可行的,但是考虑到 RTMP 后期升级的便利性以及模块维护的聚焦性,还是建议不动 RTMP 服务,毕竟目前来看,它还是一个标准服务。

方案3

说到方案三时,大家肯定能想到是修改 MS 服务,是的,MS 服务是我们专用的流媒体服务,综合利弊,我们最终决定通过修改 MS 流媒体服务来平滑处理小程序音频流的时间戳。

具体是怎么做的呢?

MS 服务处理 rtmp 协议向 rtp 协议转换时,使用的是 ffmpeg 工具,这里可以简单介绍一下 ffmpeg,ffmpeg 是进行音视频功能开发时的常用工具之一,号称多媒体领域的瑞士军刀。在调用 ffmpeg 做 rtp 包转换的时候,增加参数 asetpts=N/SR/TB。

接下来,我们看一下源码。该功能对应的音频过滤器是 ff_af_asetpts,其声明如下:

代码语言:javascript
复制
const AVFilter ff_af_asetpts = {
    .name        = "asetpts",
    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
    .init        = init,
    .activate    = activate,
    .uninit      = uninit,
    .priv_size   = sizeof(SetPTSContext),
    .priv_class  = &asetpts_class,
    .flags       = AVFILTER_FLAG_METADATA_ONLY,
    FILTER_INPUTS(asetpts_inputs),
    FILTER_OUTPUTS(asetpts_outputs),
};

简单介绍一下传入音频过滤器的参数,其中,参数N,表示音频样本数;参数SR,表示音频采样率;参数TB,表示时间基准。这些参数最终的作用就是平滑音频的时间戳,其原理是根据音频采样数重新计算播放的时间戳。

五、结论

用户反馈的这个声音卡顿问题之所以比较棘手,就是因为问题点有些出人意料。一般小程序出问题了,大家肯定想到的是小程序代码写的有问题,又有几个人会想到是微信自身的 Bug 呢。所以,有时候遇到疑难问题,不如放开思路大胆假设根因。好了,关于安卓小程序音频卡顿的问题及解决方案就介绍完了,希望对大家解决问题有所帮助。

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景
  • 二、疑惑
  • 三、排查
    • 解惑1
      • 解惑2
        • 解惑3
        • 四、方案
          • 方案1
            • 方案2
              • 方案3
              • 五、结论
              相关产品与服务
              云开发 CloudBase
              云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档