技术分享| 音视频与微信小程序互通实践

news2024/11/24 4:21:48

随着网络架构的变迁、媒体技术发展、音视频场景迭代,基于流媒体的技术也是推陈出新。WebRTC渐渐的成为了音视频互动场景的主流,而微信在6.5.21版本通过小程序开放了实时音视频能力,开发者们可以使用组件 < live-pusher > 实现基于 RTMP 的直播推流(录制),用于实时音视频通话上行,使用组件 < live-player > 实现基于 RTMP 的直播拉流(播放)。可以看出,微信小程序的音视频是基于 RTMP 协议的,但是微信小程序的音视频只是提供了终端上的能力,并没有实现媒体服务器,腾讯给出了2个方案,1是使用腾讯云的快直播服务,2是开发者自己实现一套媒体网关服务。方案1,需要完全使用腾讯云的服务,很显然不太适合我们这样的开发者;于是留给我们的之后方案2了。

一.什么是RTMP,什么是RTC

1.RTMP

RTMP是Real Time Messaging Protocol实时消息传输协议,是Adobe公司为Flash播放器和服务器之间开发的音视频数据传输的开放协议,一般传输flv或f4v格式的媒体流。RTMP是工作在TCP之上的协议,默认使用端口1935,能够保持长连接,并为用户提供低延时通信。RTMP是目前低延时直播应用最普遍的协议,几乎是全部编码器标准输出协议,是PC机打开浏览器就能播放(通常浏览器默认有Flash),也是全部CDN支持的最好的直播分发协议。

RTMP是基于TCP协议的,且通常只占用TCP一个通道来传输数据和指令,能保证了视频的传输质量。RTMP包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMPT封装在HTTP请求之上,可穿透防火墙;RTMPS类似RTMPT,增加了TLS/SSL的安全功能;RTMPE在RTMP的基础上增加了加密功能。

因为RTMP是基于TCP之上的,所以也存在三次握手的要求,另外RTMP还增加了C0/S0到C2/S2的三次握手。所以播放一个RTMP协议的流媒体需要经过:握手,建立连接,建立流,播放。

RTMP也有不可忽视的缺点,首先,RTMP协议太老,HEVC/H.265/AV1等视频格式都没有官方定义,另外就如刚刚所说,RTMP连接过程较长,存在TCP三次握手和本身的C0/S0到C2/S2的三次握手,再加上connection,createstream,play/publish,总地来说RTMP完成一次建连需要进行9次会话。而且RTMP的拥塞控制完全依赖传输层TCP的拥塞控制算法来进行拥塞管理,无法提供带宽自适应的算法。

在这里插入图片描述

2.WebRTC

WebRTC是Web Real-Time Communication网页实时通信,是一个支持网页浏览器进行实时语音对话或视频对话的技术而无需任何插件。由谷歌2010年以6820万美元收购Global IP Solutions公司而获得,如今WebRTC已经不仅仅局限于PC的网页浏览器,Android,iOS平台上很多应用都已经采用了这样技术。

WebRTC使用是RTP分装码流,跟视频监控,IPTV,会议电视一样都是RTP承载媒体流,只不过WebRTC信令遵守ICE框架,走自定义信令,IPTV领域走RTSP信令,视频监控走GB28181或者onvif信令,会议电视走h323或SIP协议。另外,WebRTC的码流采用SRTP进行加密,且WebRTC优先使用VP9、VP8、H.264、AV1,暂不支持H.265。

在这里插入图片描述

二.WebRTC如何跟小程序互通

1.如何互通大概分三步走:

A.微信小程序端使用 RTMP 协议,接入边缘媒体网关,即 Xcx网关;

B.Xcx网关支持 RTMP 协议接入和输出,完成微信小程序间的媒体转发;

C.同时Xcx网关将 RTMP 协议转换成 RTP 协议,转发给anyRTC的WebRTC服务器,完成与Native、标准 WebRTC 终端的互联互通。

在这里插入图片描述

anyRTC的Xcx网关的主要工作就是对RTMP和WebRTC的音视频格式进行转换。一般RTMP的视频是H264编码,音频是AAC编码;WebRTC的视频是H264编码,音频是Opus编码。所以我们可以看出,视频只需要转换封装格式,而音频则需要进行转码工作。

2.视频格式转换

anyRTC的Xcx网关收到视频帧之后,将帧进行RTP 封装 H.264。

WebRTC 选择了使用 RFC3984 的 Non-Interleaved 封装方案对H.264 进行封装。
在这里插入图片描述
Single NAL Unit Packet

Single NAL Unit Packet 是 RTP 最基本的打包方式,其中,
forbidden_bit:禁止位,初始为0,当网络发现 NAL 单元有比特错误时可设置该比特为 1,以便接收方纠错或丢掉该单元。

在这里插入图片描述

nal_reference_bit:nal 重要性指示,标志该 NAL 单元的重要性,值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为 0 的 NALU。Type:NAL 单元中的 RBSP 数据结构的类型,其中 0 未指,1-19 在 H.264 协议中有定义,20-23 为 264 协议指定的保留位,24-29 在 RFC3984 中进行了指定。Type 后面的数据为 RBSP 的数据,需要注意的是:编码器的每个 slice 或者每帧头一般会有由0x000001 或者 0x00000001 作为起始头,在 RTP 封装中需要去掉。此外在 H.264 裸码流数据后面可能还会带有 padding 的数据由 RTP 头的 padding 位决定。

STAP-A

STAP-A 的作用是可以把多个 nal 单元封装在一个 RTP 包里面进行传输,需要注意:-A 的格式都是不允许跨帧的,也就是 nal 单元的时间戳必须是相同的。常见的场景是 sps 和 pps 两个小包被合并封装。
在这里插入图片描述
RTP 头后面仅跟着 STAP-A 的头,由 F、NRI 和 Type 组合而成,占一个字节,这里的 Type 为 24。后面两个字节为第一个 nalu 单元的长度,后面跟第一个 nalu 数据同 Single NAL Unit 的封装一致,第一个数据结束后,跟着第二个 nalu 的长度,占 2 个字节,依次类推。

FU-A

FU-A 的作用是把一个原始大的 nalu 切成多个数据包进行传输,主要使用场景在 slice 比较大的情况下。FU-A 比较特殊,有 FU-A 起始包、FU-A 包(如果只切两个包可能没有)和 FU-A 结束包组成。

在这里插入图片描述

FU indicator 占一个字节,由 F、NRI 和 Type 组合而成,这里的 Type 为28。FU header 占一个字节:

在这里插入图片描述

S: 占1位如果是1表示当前这个包是 FU-A 的起始包E: 占1位如果是1表示当前这个包是 FU-A 的结束包R: 占1位,保留位,为0Type: 实际包含 nalu 的类型。

音频转码

在Xcx网关中,我们采用了独立的音频转码线程组,减轻逻辑处理线程的压力的目的。每个转码任务将被分配到固定的音频转码线程,线程根据任务数量进行负载均衡。

在这里插入图片描述

三.总结

与小程序的互通相对来说还是比较容易实现,开发者可以选择anyRTC的小程序服务,避免过多的踩坑;也可以尝试自己实现一套服务来满足自身的业务诉求。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/65639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计讯物联数字乡村解决方案全力助推三农信息化建设

​2020年&#xff0c;中央网信办等七部门联合印发《关于开展国家数字乡村试点工作的通知》。《通知》提出&#xff0c;做好数字乡村发展整体规划设计&#xff0c;统筹推进乡村的新型基础设施、数字经济、数字农业农村、农村科技创新、乡村数字治理、信息惠民服务等建设和发展。…

类的加载过程(类的生命周期)详解

类的加载过程&#xff08;类的生命周期&#xff09;详解 1. 概述 在Java中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义&#xff0c;引用数据类型则需要进行类的加载。 按照Java虚拟机规范&#xff0c;从class文件到加载到内存中的类&#xff0c;到…

python全局和局部变量以及引用和装饰器

学习笔记 bilibili千峰python global关键字的添加 只有不可变的类型才需要添加global可变的类型不需要添加global不可变类型&#xff1a;当改变变量的值时候&#xff0c;地址发生了改变 类型&#xff1a;int&#xff0c;str&#xff0c;float&#xff0c;bool&#xff0c;tup…

[Spring Boot 6]企业级开发

本节内容主要就几个常用的模块进行解读&#xff0c;在众多企业级开发中常常用得到。 例如邮件发送这一功能其实非常常见&#xff0c;在一般的网站设计中会有对注册邮件的激活功能&#xff0c;此时就需要用到这个功能了&#xff0c;一般来说激活邮件需要设置UUID 来进行验证&…

【Python入门】Python入门必备思维导图,有方向的学习才是最实在的方法

前言 halo&#xff0c;包子们下午好 这篇文章主要是跟大家聊聊我们学习Python该怎么去学习 小编个人认为&#xff0c;学习Python一定要有一个好的学习方向&#xff0c;这样才知道自己该往什么方向去学习 今天小编主要给大家准备了我们学习Python的必备14张思维导图 赶快收藏起…

【SSM整合】SpringMVC + Spring + Mybatis整合详细教程

前言 本文为 SpringMVC Spring Mybatis整合教程 相关详细介绍&#xff0c;从数据库数据准备、相关依赖包添加、创建项目基本结构和配置框架&#xff0c;到Mybatis层的编写、Spring层的编写、SpringMVC层的编写&#xff0c;再到前端页面编写等&#xff0c;最后进行运行与测试&…

新生报到小程序毕业设计,新生报到管理系统设计与实现,毕设作品参考

功能清单 【后台管理员功能】 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 录入资讯&#xff1a;录入资讯标题、内容等信息 管理资讯&#xff1a;查看已录入资讯列表&#xff0c;支持删除和修改 学校…

MySQL——表的约束

文章目录表的约束空属性默认值列描述zerofill主键&#x1f60a;自增长唯一键&#x1f60a;外键&#x1f60a;表的约束 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑…

前端给数字添加横线贯穿

效果 实现方法 1、给这个数字添加css属性&#xff1a;text-decoration: line-through; 2、给这个数字添加标签&#xff1a;del。如&#xff1a;<del>9999</del>。 text-decoration详解&#xff1a; text-decoration : none || underline || blink || overline |…

使用RMI实现RPC

1 RMI简介 RMI(Remote Method Invocation) 远程方法调用。 RMI是从JDK1.2推出的功能&#xff0c;它可以实现在一个Java应用中可以像调用本地方法一样调用另一个服务器中Java应用&#xff08;JVM&#xff09;中的内容。 RMI 是Java语言的远程调用&#xff0c;无法实现跨语言。…

LVGL自定义组件__页面指示器

前言 LVGL对硬件的要求非常低&#xff0c;使用其自带的组件能够搭建出精美的界面&#xff0c;动效也很棒。但是如过移植到Linux平台下&#xff0c;开发稍微复杂的应用项目&#xff0c;那些组件就远远不够用了。为此需要自己自定义一些组件&#xff0c;以方便实用。 效果 为此…

D-star Lite算法及相关思考

一、D-star Lite算法简介 1994年 Anthony Stentz在论文Optimal and Efficient Path Planning for Partially-known Environments中提出了D*算法 D * 算法采用逆向搜索&#xff0c;从目标点向起始点搜索规划&#xff0c;可以处理环境部分未知或全部未知以及动态障碍的一些情况。…

神经网络入门(一)

神经网络入门&#xff08;一&#xff09; 文章目录神经网络入门&#xff08;一&#xff09;1. 神经元2. 网络结构3. 激活函数2.1 激活函数的作用与性质2.2 Sigmoid型函数2.3 Hard-Logistic函数和 Hard-Tanh函数2.4 ReLU函数2.5 常见的激活函数及其导数4. 前馈神经网络4.1 前馈神…

DAY05-网页布局实战选择器CSS样式

文章目录网页布局实战一 CSS选择器a.基本选择器1.元素选择器2.类选择器3.id选择器b.复杂选择器c 伪选择器d 伪元素选择器二 CSS常用样式1.文本相关属性2.背景属性1)背景颜色2)背景图片3)背景平铺4)背景位置5)设置背景图片大小&#xff1a;6)background 背景复合属性案例1案例2案…

Session的使用

Session的使用Session概述Session特性Session原理Session对象操作获取Session对象-----getSession获取SessionID------getId向Session对象存储/修改数据-----setAttribute获取数据------getAttribute删除数据----removeAttributeSession对象失效Session概述 Session对象&#…

rust编程-rust所有权理解(chapter 4.2 引用实质是借用)

目录 2. 引用与借用 2.1 可变(mutable)引用 2.2 悬空&#xff08;dangling&#xff09;引用 2.3 引用的规则总结 2. 引用与借用 上一章节中提到&#xff0c;所有权在函数调用中的转移&#xff0c;函数返回必须同时返还所有权&#xff0c;才能使函数调用后能继续使用某个变量…

[附源码]计算机毕业设计勤工助学管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

jquery 登录-记住密码

jquery 登录-记住密码在登录时&#xff0c;添加记住密码功能&#xff1a;用的 localStorage 存储和获取登录信息 //存储 var username $("input[nameusername]").val(); var password $("input[namepassword]").val(); var validateCode $("inpu…

自动驾驶:2022 apollo day 观后感(一)

2022 apollo day 观后感&#xff08;一&#xff09;注&#xff1a; ppt来自apollo day&#xff0c;结合ppt&#xff0c;讲述一些自己的想法&#xff0c;欢迎批评指正&#xff01;Topic One -- 打造安全、智能、高效的自动驾驶技术体系&#xff08;陈竞凯&#xff09;无人驾驶技…

Ruby ERB模板注入检测

了解Ruby ERB模板注入,Ruby ERB模板注入检测。 ERB是Ruby自带的 <% 写逻辑脚本(Ruby语法) %><%= 直接输出变量值或运算结果 %>require erbtemplate = "text to be generated: <%= x %>" erb_object = ERB.new(template) x = 5 puts erb_object.r…