前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版

小程序直播总结 live-pusher与live-player接入实践

首页2020-06-14 15:20:12Front-End
小程序直播音视频

产品那边提了个需求,要在小程序里做直播。听上去像是加个播放器的事,真去调研才发现门槛全在代码之外:类目过不过得了、资质有没有、推流地址从哪来、服务端要不要自己搭。技术选型反而是最后才轮到的事。

这篇把当时调研和接入的过程完整记一遍,三条实现路线各自的适用场景,live-pusher 和 live-player 两个组件的参数怎么配,腾讯云直播那边的域名和 CNAME 怎么弄,最后是 IM 互动和直播回放。看完你应该能判断出自己这个项目该走哪条路。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • 小程序直播的三种实现方案,各自的成本和限制
  • 类目和资质门槛,哪些账号根本开不了直播
  • 推流和拉流的完整链路,以及两张 API 调用流程图怎么读
  • live-player 的 live 与 RTC 两种模式,min-cache 和 max-cache 怎么调
  • live-pusher 的 SD / HD / FHD / RTC 四种模式怎么选
  • 云直播服务的选型,推流域名与播放域名的 CNAME 配置
  • 直播回放和 IM 弹幕互动的接入路径
  • 这几年微信和云厂商这边变了什么

# 一、小程序直播功能目前有哪些实现方案

先把路摆出来,一共三条。

内嵌腾讯直播 H5。腾讯直播已改名 NOW 直播,小程序接入工具文档已经找不到了。这条路当时就走不通,列在这里是为了说明它曾经存在过。

小程序原生实现。小程序对直播和 websocket 都做了比较好的封装,通过 live-pusher、live-player 组件和 websocket API 就能实现直播互动功能。这条路自由度最高,弹幕、连麦、礼物这些自定义交互都能做,代价是链路要自己搭,云直播的账单也要自己扛。

接入小程序直播插件实现。小程序直播是微信提供给小程序开发者的直播组件。这条路接入最快,微信把推流端、播放端、商品挂载、回放这一整套都封装好了,代价是交互样式和业务流程基本按微信的来,改不了多少。

我的判断是这样:如果你的诉求就是「电商小程序里加个直播卖货」,走插件;如果你要做的是在线教育、多人连麦、或者直播界面上有大量自定义交互,那只能走原生。这篇后面主要讲原生这条路。

# 二、小程序原生实现直播功能流程

微信小程序从 1.7 开始,为开发者提供了两个新接口,live-pusher 和 live-player,可以在小程序上实现单向的直播功能。通过和其他技术结合,比如 WebRTC,开发者们还可以进一步在小程序直播的基础上实现连麦功能。

# 2.1 先过类目这一关

由于微信对小程序直播功能的类目有限制,限定了特定类目的小程序才能使用。

微信对小程序直播功能开放的类目限制表

另外需要注意几点:

  • 个人号无法申请使用直播功能
  • 社交类目开通直播功能需要相关视频许可和文网文资质许可
  • 所以小程序开通直播的业务,要根据产品的目的和场景去申请对应的类目

这条路我建议排在所有技术工作前面。类目和资质走不通,后面代码写得再漂亮也上不了线。

在小程序管理后台,「开发」-「接口设置」中自助开通对应的权限,如下图所示:

在小程序管理后台的接口设置中自助开通直播权限

# 2.2 整条链路长什么样

小程序原生实现直播功能的完整链路示意图

微信小程序原生实现直播功能的流程如上图所示。录制端小程序通过 live-pusher 组件对手机摄像头和麦克风的数据进行采集和编码,推流到服务器;服务器端对数据进行加工处理并分发给多个客户端;播放端小程序通过 live-player 组件从云端拉流并进行实时无差异的解码和渲染,从而实现直播小程序完整的互动功能。

这条链路里,小程序只负责最两头的采集和渲染。中间那一大段全是云服务商的活儿。

推流 API 调用流程图:

live-pusher 推流的 API 调用时序流程图

拉流 API 调用流程图:

live-player 拉流的 API 调用时序流程图

这两张图读的时候盯住两件事:状态回调和错误分支。真机上出问题的时候,你能拿到的信息全在 bindstatechange 和 bindnetstatus 这两个事件里,前者报状态码,后者报网络质量。别嫌麻烦,一开始就把这两个回调的日志打全,后面排查能省一半时间。

# 三、小程序直播实现过程

微信小程序中的推拉流功能,需要用到微信提供的 live-player 和 live-pusher 标签。

# 3.1 live-player

live-player 是微信提供的支持实时音视频播放的组件, 官方介绍详见组件介绍。

创建 live-player 的演示源码如下:

<live-player
    autoplay
    wx:if="{{item.playUrl}}"
    id="{{item.streamID}}"
    mode="RTC"
    object-fit="fillCrop"
    min-cache="0.1"
    max-cache="0.3"
    src="{{item.playUrl}}"
    debug="{{pushConfig.showLog}}"
    bindstatechange="onPlayStateChange"
    bindnetstatus="onPlayNetStateChange"
    binderror="error">
    <cover-view class='character' style='padding: 0 5px;'>{{item.streamID}}</cover-view>
</live-player>
@前端进阶之旅: 代码已经复制到剪贴板

请注意两种模式的区别。

live 模式主要用于直播类场景,比如赛事直播、在线教育、远程培训等等。该模式下,小程序内部的模块会优先保证观看体验的流畅,通过调整 min-cache 和 max-cache 属性,你可以调节观众端所感受到的时间延迟的大小。

RTC 则主要用于双向视频通话或多人视频通话场景,比如金融开会、在线客服、车险定损、培训会议等等。在此模式下,对 min-cache 和 max-cache 的设置不会起作用,因为小程序内部会自动将延迟控制在一个很低的水平,500ms 左右。

那 min-cache 和 max-cache 到底在调什么呢?调的是播放端的缓冲区水位。播放器不会拿到一帧就渲染一帧,它会先囤一小段数据再开始播,用来抵消网络抖动。囤得多,卡顿少但延迟大;囤得少,延迟低但网络一抖就卡。

所以这两个参数不是越小越好,它是延迟和流畅度之间的一个滑块。单向观看的直播,比如带货或者赛事,观众感知不到延迟,可以把水位调高换流畅;需要主播和观众实时对话的场景才值得压低。

还有一个 cover-view。live-player 是原生组件,层级高于普通的 WXML 元素,想在视频上盖字或者盖按钮只能用 cover-view 和 cover-image,普通的 view 会被压在下面看不见。这个坑我踩过,写了半天弹幕层发现真机上什么都看不到。

# 3.2 live-pusher

live-pusher 是微信提供的支持实时音视频录制的组件, 官方介绍详见组件介绍。

创建 live-pusher 的演示源码如下:

<live-pusher
    wx:if="{{pushUrl}}"
    id="video-livePusher"
    mode="RTC"
    url="{{pushUrl}}"
    min-bitrate="{{pushConfig.minBitrate}}"
    max-bitrate="{{pushConfig.maxBitrate}}"
    aspect="{{pushConfig.aspect}}"
    beauty="{{pushConfig.isBeauty}}"
    muted="{{pushConfig.isMute}}"
    background-mute="true"
    debug="{{pushConfig.showLog}}"
    bindstatechange="onPushStateChange"
    bindnetstatus="onPushNetStateChange">
    <cover-view class='character' style='padding: 0 5px;'>{{isPublishing ? "我(" + publishStreamID + ")": ""}}</cover-view>
</live-pusher>
@前端进阶之旅: 代码已经复制到剪贴板

请注意,推流端的模式比播放端多几个。

SD、HD 和 FHD 主要用于直播类场景,比如赛事直播、在线教育、远程培训等等,分别对应三种默认的清晰度。该模式下,小程序会更加注重清晰度和观看的流畅性,不会过分强调低延迟,也不会为了延迟牺牲画质和流畅性。

RTC 则主要用于双向视频通话或多人视频通话场景。该模式下,小程序会更加注重降低点到点的时延,也会优先保证声音的质量,在必要的时候会对画面清晰度和画面的流畅性进行一定的缩水。

min-bitrate 和 max-bitrate 是码率上下限,单位是 kbps。移动端网络波动大,推流端会在这个区间内动态调整。区间给窄了,网络一差就只能丢帧;给宽了,画质会在好网和差网之间明显跳变。这个值没有标准答案,得看你的内容类型,画面静态多的场景可以把上限压低。

background-mute 这个属性容易被忽略,它决定 App 切到后台时是否静音推流。主播接了个电话回来发现直播断了,多半就是后台策略没配对。

# 3.3 服务端的选择

自己搭 RTMP 服务,比如 Nginx rtmp,成本较高,技术实现难度大。所以更现实的做法是用云服务商提供的视频直播服务产品,让它生成推流地址和播放地址。目前市面上主流的云直播产品有腾讯云、阿里云、七牛云等。

主流云直播服务商的功能与价格对比

各平台均提供内容接入与分发和分布式实时视频处理技术,每个平台提供的功能大同小异但各有千秋。按当时的价格,平均费用大概 20 到 30 元每 100G,100G 流量可以满足 100 人同时在线直播 4 小时。这个数字是 2020 年的行情,现在的定价和赠送政策早就变了,只能当个数量级参考。

接下来选择腾讯云直播进行接入体验。

第一步,申请腾讯云账号,开通云直播权限。当时它会赠送 20GB 流量,超出需要自己花钱。开通流程请参考文档: https://cloud.tencent.com/document/product/454/12517

第二步,域名管理。在这里面会看到两个域名,一个是推流域名,一个是播放域名。域名可以用自己的,建议配置自己的域名,2019 年 2 月 26 日上线查看时发现赠送的播放域名已失效。具体看文档: https://cloud.tencent.com/document/product/267/20381

腾讯云直播控制台的域名管理界面

由于腾讯云不再赠送播放域名,所以需要租用或者使用自己的域名生成播放地址。自己的播放域名不能直接访问,需要完成 CNAME 配置。

播放域名的 CNAME 解析配置示意

CNAME 这一步是很多人卡住的地方。你在腾讯云控制台加了域名,它会给你一个 CNAME 目标值,你得去自己的 DNS 服务商那里把这条解析加上,流量才会真正走到腾讯云的节点。解析生效有延迟,配完先用 dig 或者 nslookup 确认一下再回来调代码,不然你会以为是自己的推流参数写错了。

还有一点,推流地址通常带有过期时间和鉴权签名。这套签名的生成一定要放在自己的后端,不要把密钥打进小程序包里。小程序的代码包是能被解出来的。

# 3.4 组件 API 接入

第一步,live-pusher 推流,也就是数据包实时上传。

使用 live-pusher 发布流,这里用到的参数是 min-bitrate="200" 最小码率,max-bitrate="400" 最大码率,mode="RTC" RTC 模式。加入房间之后我们需要调用 publish 返回一个 rtmp 推流地址。

<live-pusher
  autopush
  min-bitrate="200"
  max-bitrate="400"
  mode="RTC"
  url="{{publishPath}}">
</live-pusher>
@前端进阶之旅: 代码已经复制到剪贴板

先使用 wx.createLivePusherContext 创建 LivePusherContext,再使用 setData 设置好 publishPath 之后发布:

fe
  • 一、小程序直播功能目前有哪些实现方案
  • 二、小程序原生实现直播功能流程
    • 2.1 先过类目这一关
    • 2.2 整条链路长什么样
  • 三、小程序直播实现过程
    • 3.1 live-player
    • 3.2 live-pusher
    • 3.3 服务端的选择
    • 3.4 组件 API 接入
    • 3.5 直播回放功能
  • 四、即时通信 IM
  • 五、完整示例
  • 六、这几年变了什么
  • 总结
  • 参考

← 微信h5网页跳转小程序方案 开放标签实战H5之微信公众号分享 JS-SDK接入与二次分享失效排查 →