实现实时无延迟的音频和视频组播传输方法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 极简音视频组播SDK
- 一、基本概念
- 1、单播、广播、组播:
- 2、音视频组播发送端:
- 3、音视频组播接收端:
- 4、FEC:
- 5、FEC相关参数:
- 6、NACK:
- 7、组播NACK支持:
- 8、Smooth平滑:
- 9、JitterBuff:
- 10、传输参数:
- 11、时间戳模式:
- 12、内部拆包传输:
- 二、API接口
- 1、系统环境初始化,仅需调用一次
- 2、系统退出时调用一次反初始化
- 3、创建SDK对象
- 4、销毁SDK对象
- 5、准备会话
- 6、结束会话
- 7、发送视频数据
- 8、发送音频数据
- 9、设置音视频传输参数
- 10、获取当前SDK版本信息
- 11、获取当前丢包率数据
- 12、设置时间戳工作机制
- 13、设置发送端Smooth机制
- 回调输出相关API接口
- 1、设置视频数据接收回调
- 2、设置音频数据接收回调
- 参考
- SDK下载
极简音视频组播SDK
提示:这里可以添加本文要记录的大概内容:
作为一种与单播(Unicast)和广播(Broadcast)并列的通信方式,组播(Multicast)技术能够有效地解决单点发送、多点接收的问题,从而实现了网络中点到多点的高效数据传送,能够节约大量网络带宽、降低网络负载。常见基于组播的音视频应用有同屏教学、校园广播等。组播基于UDP传输,因此同样面临UDP传输常见的乱序、丢包、重复等挑战,本SDK主要为传统UDP组播增加FEC前向纠错、NACK丢包重传、Qos、JitterBuff等功能,为开发音视频组播应用提供快速解决方案。
本音视频组播SDK,支持特性:
1、 支持基于RS编码的FEC前向纠错,专为音视频类应用量身定制。
2、 支持FEC动态Group分组,避免分组跨帧同时尽可能提升抗连续丢包能力。
3、 发送端传入单帧码流,内部自行拆分拼接,实现透传。
4、 发送端支持Smooth平滑发送,对视频大I帧场景进行优化。
5、 支持接收端自适应JitterBuff缓存技术。
6、 独有的NACK组播重传技术,为每个组播接收端提供个性化重传服务。
7、 两套独立SDK分别适应不同场景,一套仅负责传输层,外层应用负责编解码。一套负责编解码以及网络传输,外层负责采集、渲染。
8、 C++开发,性能强劲,无外部库依赖,支持Windows\Android\Linux,支持32位、64位系统。
9、 API接口简洁易用、完善的文档与DEMO参考。
提示:以下是本篇文章正文内容,下面案例可供参考
一、基本概念
1、单播、广播、组播:
作为一种与单播(Unicast)和广播(Broadcast)并列的通信方式,组播(Multicast)技术能够有效地解决单点发送、多点接收的问题,从而实现了网络中点到多点的高效数据传送,能够节约大量网络带宽、降低网络负载。利用组播技术可以方便地提供一些新的增值业务,包括在线直播、网络电视、远程教育、远程医疗、网络电台、实时视频会议等对带宽和数据交互的实时性要求较高的信息服务。
三种信息传输方式的比较
单播
如下图所示,在IP网络中若采用单播的方式,信息源(即Source)要为每个需要信息的主机(即Receiver)都发送一份独立的信息拷贝。
采用单播方式时,网络中传输的信息量与需要该信息的用户量成正比,因此当需要该信息的用户数量较大时,信息源需要将多份内容相同的信息发送给不同的用户,这对信息源以及网络带宽都将造成巨大的压力。从单播方式的信息传播过程可以看出,该传输方式不利于信息的批量发送。单播主要用于公网场景或无线局域网中,这类场景中广播与组播均无法应用或效果不佳。
广播
如下图所示,在一个网段中若采用广播的方式,信息源(即Source)将把信息传送给该网段中的所有主机,而不管其是否需要该信息。
假设只有Host B、Host D和Host E需要信息,若将该信息在网段中进行广播,则原本不需要信息的Host A和Host C也将收到该信息,这样不仅信息的安全性得不到保障,而且会造成同一网段中信息的泛滥。因此,广播方式不利于与特定对象进行数据交互,并且还浪费了大量的带宽。
组播
综上所述,传统的单播和广播的通信方式均不能以最小的网络开销实现单点发送、多点接收的问题,IP组播技术的出现及时解决了这个问题。
如下图所示,当IP网络中的某些主机(即Receiver)需要信息时,若采用组播的方式,组播源(即Source)仅需发送一份信息,借助组播路由协议建立组播分发树,被传递的信息在距离组播源尽可能远的网络节点才开始复制和分发。
假设只有Host B、Host D和Host E需要信息,采用组播方式时,可以让这些主机加入同一个组播组(Multicast group),组播源向该组播组只需发送一份信息,并由网络中各路由器根据该组播组中各成员的分布情况对该信息进行复制和转发,最后该信息会准确地发送给Host B、Host D和Host E。
组播的优势归纳如下:
相比单播来说,组播的优势在于:由于被传递的信息在距信息源尽可能远的网络节点才开始被复制和分发,所以用户的增加不会导致信息源负载的加重以及网络资源消耗的显著增加。相比广播来说,组播的优势在于:由于被传递的信息只会发送给需要该信息的接收者,所以不会造成网络资源的浪费,并能提高信息传输的安全性;另外,广播只能在同一网段中进行,而组播可以实现跨网段的传输。
组播的缺点:
由于无线组播报文的发送没有相应的确认机制(数据链路层ACK),因此设备无法对丢失的报文进行重传,导致链路质量差的情况下,无线环境下组播报文丢失严重。
2、音视频组播发送端:
作为组播源将自身音视频组播发送。
3、音视频组播接收端:
接收音视频组播流。
4、FEC:
前向纠错技术,通过增加冗余带宽方式,提高网络对于丢包的抵抗力。
5、FEC相关参数:
FEC相关参数包括FEC冗余度方法、FEC上行冗余度、FEC min group组大小、FEC max group组大小。FEC冗余度方法包括:固定冗余度(本SDK仅支持固定冗余度)、自动冗余度两种。固定冗余度即全程使用用户指定的冗余度进行FEC编码,自动冗余度则以用户指定的FEC冗余度为基础,根据网络情况进行调整,对于网络较好的场合使用低冗余尽量降低带宽。FEC是分组进行的,即多个拆分包组成一个group,产生其冗余包。group越大,同样冗余度的情况下,产生的冗余包越多,抵抗连续丢包能力越强,同时因丢包产生的抖动也会越大(因为FEC的group可能产生跨多帧的情况,前面包的丢失不得不等到后续包的到来才能恢复);FEC分组越大消耗CPU资源也越大。建议配置FEC min group大小16;建议根据芯片处理性能设置FEC max group,在性能足够的设备上建议设置为64(PC、主流Android手机均可设置为64,嵌入式平台则根据实际情况设置)。
6、NACK:
重传请求机制,与FEC配合,在预估FEC无法恢复时触发接收端到发送端的重传请求,发送端予以重发响应。NACK仅重传一次,不保证数据一定传输成功,优点是可以获得稳定的低延时,缺点是画面仍可能因丢包而卡顿。
7、组播NACK支持:
组播是一种单向的传输技术,正常情况下无法使用NACK重传机制,因为每一个接收端都可能有不同的丢包情况。我们使用单播作为组播的一种补充,从而实现了为不同组播接收端提供个性化的NACK服务。
8、Smooth平滑:
发送端对一帧较大的码流在时间窗口内平滑发送,避免一次性发出给网络带来的压力。
9、JitterBuff:
接收端为了抵消网络传输、丢包恢复、NACK重传引入的抖动,引入JitterBuff缓存。缓存时间越大,画面流畅度越高,但延时也同步增大。当需要极低延时时,可设置JitterBuff为0。
10、传输参数:
本SDK中传输相关参数包括:视频通道的上行FEC冗余度、上行FEC Group分组大小、NACK重传支持、接收端JitterBuff缓存时间。对于音视频组播接收端,同样可以设置上行FEC冗余度、上行FEC Group分组大小,只是没有实际意义(因为不会发送数据,当然也不会进行FEC编码)。
11、时间戳模式:
本SDK提供了内置时间戳(默认)和外部时间戳两种模式,当用户选择外部时间戳模式时,需在发送端提供音视频时间戳(1KHZ时基,即毫秒单位),该时间戳将在接收端透传露出。当用户选择内置时间戳模式时,SDK将在用户调用SDK发送接口时自动生成时间戳,以简化用户使用。
12、内部拆包传输:
外层传入一帧码流后,SDK内部将进行拆分发送,拆分包大小与FEC min group取值相关,原则上400~1000字节之间波动,拆分后的包大小加上私有头部、UDP\IP头部后不会超过1500字节。
二、API接口
所有API接口定义均位于SDTerminalMulticastSdk.h文件中。
1、系统环境初始化,仅需调用一次
void SDTerminalMulticast_Enviroment_Init (const char * outputPath, int outputLevel)
参数:
@param: outputPath:日志文件输出的目录,若目录不存在,SDK将自动创建,支持相对路径或绝对路径。日志对于问题定位非常重要,建议开启。
@param: outputLevel:日志输出的级别,只有等于或者高于该级别的日志会输出到文件,日志级别取值见LOG_OUTPUT_LEVEL_MULTICAST,有DEBUG、INFO、WARNING、ERROR、ALARM、FATAL、NONE几个级别可选,当指定为NONE时,将不会生成日志文件。
2、系统退出时调用一次反初始化
void SDTerminalMulticast_Enviroment_Free()
3、创建SDK对象
void* SDTerminalMulticast_Create();
4、销毁SDK对象
void SDTerminalMulticast_Delete(void** ppTerminal);
参数:
@ ppTerminal,模块指针的指针
说明:使用者应该做好与其他API之间的互斥保护
5、准备会话
int SDTerminalMulticast_Online(
void* pTerminal,
TERMINAL_TYPE_MULTICAST eUserType,
const char* strLocalIP,
const char* strMultiIp,
unsigned short shMultiPort
);
参数:
@pTerminal,模块指针
@eUserType: 客户端类型,有组播发送端与组播接收端两种。
@strLocalIp,组播绑定的本地IP地址,当设置为NULL时,内部将使用INADDR_ANY,交由操作系统选择一个网卡IP。建议指定IP以防多IP时系统选择错误。
@strMultiIp,组播IP地址。
@shMultiPort,组播端口号,将使用本端口发送音频数据 使用本端口+2发送视频数据。
返回值:返回大于等于0表示成功,返回负数则为失败,负数值为其错误码。
6、结束会话
void SDTerminalMulticast_Offline(void* pTerminal);
参数:
@pTerminal,模块指针
返回值:无
7、发送视频数据
void SDTerminalMulticast_SendVideoData(void* pTerminal, unsigned char *byBuf, unsigned int unLen, unsigned int unDts, BOOL bIsHevc);
参数:
@pTerminal,模块指针
@byBuf,码流存放区。
@unLen,码流长度。
@unDts, SDK默认使用内部时间戳模式,内部自动产生时间戳,此时本参数传入0即可。当用户调用SDTerminalMulticast_SetUseInternalTimeStamp API来指定外部时间戳模式时,在此传入外部时间戳。@bIsHevc,当前码流是否为HEVC(H265)码流,是则设置为TRUE,H264码流设置为FALSE,请务必按实际情况准确设置。
@ bIsHevc:传入码流是否为HEVC, H264时传入FALSE,请务必与实际情况相符。
返回值:无
说明:发送视频码流,一次传入一帧带起始码(0x 00 00 00 01或0x00 00 01)的码流。
8、发送音频数据
void SDTerminalMulticast_SendAudioData(void* pTerminal, unsigned char *byBuf, unsigned int unLen, unsigned int unDts);
参数:
@pTerminal,模块指针
@byBuf,码流存放区。
@unLen,码流长度。
@unDts, SDK默认使用内部时间戳模式,内部自动产生时间戳,此时本参数传入0即可。当用户调用SDTerminalMulticast_SetUseInternalTimeStamp API来指定外部时间戳模式时,在此传入外部时间戳。
返回值:无
说明:向请求的位置发送音频码流,一次传一帧ADTS码流。内部将校验ADTS头合法性。
9、设置音视频传输参数
void SDTerminalMulticast_SetTransParams(void* pTerminal, unsigned int unJitterBuffDelay, FEC_REDUN_TYPE_MULTICAST eFecRedunMethod, unsigned int unFecRedunRatio,
unsigned int unFecMinGroupSize, unsigned int unFecMaxGroupSize,
BOOL bEnableNack,
unsigned short usNackPort);
参数:
@pTerminal,模块指针
@unJitterBuffDelay,本客户端接收码流时的内部缓存时间(毫秒),范围0~600。设置为0时,将关闭内部接收JitterBuff功能,此时可以获得最低延时。
@eFecRedunMethod,为上行FEC冗余度方法,包括AUTO_REDUN自动冗余度、FIX_REDUN固定冗余度。自动冗余度将根据网络情况自行调整冗余。固定冗余度则全程使用固定值。
@unFecRedunRatio,上行冗余比率,比如设置为30,则表示使用30%冗余。自动冗余度时以该冗余度作为基础值,根据网络情况调整。
@unFecMinGroupSize,为上行FEC分组的下限值,建议设置为16。
@unFecMaxGroupSize,为上行FEC分组的上限值,根据终端CPU能力而定,最大不超过72,越大FEC所消耗的CPU越高,抗丢包能力也越强,建议性能足够的设备上设置为64。
@bEnableNack,是否启用组播NACK功能,当设置为TRUE时启用。收发两端均开启时生效。
@usNackPort,当开启NACK功能时,组播发送端用于NACK信令、媒体传输的单播端口,收发双方保持设置一致时生效。
返回值:无
说明:**注意,本函数需在Online之前调用。**
10、获取当前SDK版本信息
UINT SDTerminalP2P_GetVersion(void* pTerminal);
参数:
@pTerminal,模块指针
返回值:获得当前SDK的版本信息
11、获取当前丢包率数据
void SDTerminalMulticast_GetVideoAudioUpDownLostRatio(void* pTerminal,
float *pfVideoUpLostRatio, float *pfVideoDownLostRatio,
float *pfAudioUpLostRatio, float *pfAudioDownLostRatio);
参数:
@pTerminal,模块指针
@pfVideoUpLostRatio,获取视频上行丢包率
@pfVideoDownLostRatio,获取视频下行丢包率
@pfAudioUpLostRatio,获取音频上行丢包率
@pfAudioDownLostRatio,获取音频下行丢包率
返回值:无
说明:上述值内部已经乘100.0转换为百分比
12、设置时间戳工作机制
void SDTerminalMulticast_SetUseInternalTimeStamp(void* pTerminal,
BOOL bUseInternalTimestamp);
@pTerminal,模块指针
@bUseInternalTimestamp,是否采用内部时间戳模式,TRUE-内部,FALSE-外部。默认情况下未调用本API时,系统采用内部时间戳模式,此时将在每次调用Send接口时自动产生时间戳。当用户需要使用外部时间戳时,需调用本API指定FALSE。
返回值:无
说明:本函数需在Online之前调用。不调用本函数时,默认使用内部时间戳模式。
13、设置发送端Smooth机制
void SDTerminalMulticast_SetVideoFrameRateForSmoother(void* pTerminal,
unsigned int unFrameRate);
@pTerminal,模块指针
@unFrameRate,设置视频帧率信息,该值将作为内部发送时Smoother处理的参考。注意该帧率要符合实际帧率,可以高于实际帧率,但不能低于实际帧率,否则将导致发送速度不足,触发内部自行关闭Smooth功能。
返回值:无
说明:本函数需在Online之前调用。不调用本函数时,默认关闭smooth处理。
回调输出相关API接口
接收的远端音视频数据均通过回调函数的方式通知外层,SDK提供了相关的回调函数设置接口。
1、设置视频数据接收回调
void SDTerminalMulticast_SetRecvRemoteVideoCallback(void* pTerminal,
RecvMulticastRemoteVideoFunc pfRecvRemoteVideoCallback, void* pObject)
参数:
@pTerminal,模块指针
@pfRecvRemoteVideoCallback,回调函数指针
@pObject,透传指针,将透传给回调函数。
RecvMulticastRemoteVideoFunc的定义如下:
void (*RecvMulticastRemoteVideoFunc)(void* pObject, unsigned char* data, unsigned int unLen, unsigned int unPTS, VideoFrameInforMulticast* pFrameInfo);
其中,VideoFrameInforMulticas提供了当前帧以及当前流的重要信息:
typedef struct VideoFrameInforMulticast
{
unsigned int unWidth;
unsigned int unHeight;
unsigned int unFps;
BOOL bPacketLost;
BOOL bKeyFrame;
BOOL bInfoUpdated;
BOOL bIsHevc;
unsigned char byVps[512];
unsigned int unVpsSize;
unsigned char bySps[512];
unsigned int unSpsSize;
unsigned char byPps[512];
unsigned int unPpsSize;
} VideoFrameInforMulticast;
模块内部会获得当前码流的宽、高、帧率、VPS(HEVC时)、SPS、PPS告知外层,当其中某些参数发生变更时将置位bInfoUpdated以通知外层。
bPacketLost与bKeyFrame变量可用于外层实现丢帧冻结机制,bPacketLost表示当前帧是否接收完整,若网络丢包且FEC未能恢复时,该标志将置位。bKeyFrame表示当前帧是否为IDR关键帧。默认情况下内部已开启丢包冻结机制,外层可忽略bPacketLost与bKeyFrame。
当没有丢包发生时,本函数的输出与对方调用SDTerminalP2P_SendVideoData函数的输入完全一致。
返回值:无
说明:SDK内部将在独立于网络接收线程之外的线程中调用本接口,所以外层可以将相对耗时的操作(比如解码)放置在此回调中。
2、设置音频数据接收回调
void SDTerminalMulticast_SetRecvRemoteAudioCallback(void* pTerminal, RecvMulticastRemoteAudioFunc pfRecvRemoteAudioCallback, void* pObject);
参数:
@pTerminal,模块指针
@pfRecvRemoteVideoCallback,回调函数指针
@pObject,透传指针,将透传给回调函数。
RecvMulticastRemoteAudioFunc的定义如下:
void (*RecvMulticastRemoteAudioFunc)(void* pObject, unsigned char* data, unsigned int unLen, unsigned int unPTS, AudioFrameInforMulticast* pFrameInfo);
其中,AudioFrameInforMulticast提供了当前帧以及当前流的重要信息:
typedef struct AudioFrameInforMulticast
{
unsigned int unCodecType;
unsigned int unSampleRate;
unsigned int unChannelNum;
unsigned int unFrameNo;
BOOL bInfoUpdated;
} AudioFrameInforMulticast;
音频帧为ADTS格式,其每个包头部均附带了采样率、通道数、编码格式(目前固定0-AAC)等信息。
返回值:无
说明:SDK内部是在独立于网络接收线程之外的线程中调用本接口,所以外层可以将相对耗时的操作(比如解码)放置在此回调中。
参考
H3C路由器:20170420-H3C MSR WiNet系列路由器 配置指导(V7)-R0605-6W200
SDK下载
https://github.com/waterfoxfox/MulticastSDK
推荐阅读
-
实时音频和视频技术的发展与应用-1.1 双重音频和视频 从架构上看,双人音视频系统相对简单明了。红点代表房间信令服务,房间信令服务的主要功能是管理房间信息,实现容量协商和上下行链路的质量调节,例如当下行信道发生拥塞时,上行线路的码率和分辨率会降低。 在传输信道层面,我们的策略是优先直连,在跨区域、跨运营商的情况下,我们会选择单中转或双中转信道,在策略上尽量保持直连和中转信道同时存在,当其中一个信道的质量不好时,系统会自动切断到另一个信道的流量。 1.2 多人音视频 多人视频通话的产品形态是整个房间不超过 50 人,大盘平均房间规模约为 4.x 人,房间内部最多满足一个大视频和三个小视频(四屏)。根据这一条件,我们在架构中采用了典型的 SFU 小房间设计。 上图中的红点代表房间信令服务,主要用于房间管理和状态信息同步。房间管理主要包括用户列表的管理,例如哪些用户打开了视频/音频,我看了谁,谁看了我,这些都是基于房间管理的信息,然后房间信令服务会将这些信息同步到媒体传输服务进行数据分发。 房间服务的另一个作用是房间级容量协商和质量控制,例如,房间里的每个人一开始都支持 H.265 编码,当某个时刻进来一个只支持 H.264 编码的用户时,房间里所有的上游主播就必须把 H.265 切成 H.264。还有一种情况是,房间里有一定比例的人下行链路信道质量较差,这会导致上行链路房间质量下降。 在传输层面,我们采用的是单层分布式媒体传输网络,大家都选择中转方式,不区分双人和多人,采用 Full-Mesh 传输机制将所有数据推送过去,比如一个节点上的人并不都看另外两个人的视频,但还是会将视频推送给他们。
-
腾讯视频直播 02-推流-美颜滤镜 同样,腾讯云提供了 setBeautyFilter 方法来设置美颜风格、磨皮程度、美白程度和泛红程度 //style 磨皮风格:0:平滑 1:自然 2:朦胧 //美容级别:0-9。值为 0 时关闭美颜效果。默认值:0,关闭美颜效果。 //美白级别:取值 0-9。值为 0 时,将关闭美白效果。默认值:0,关闭美白效果。 //ruddyLevel:取值范围为 0-9。值为 0 时关闭美白效果。默认值:0,关闭美白效果。 public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel);; public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel) 滤镜 setFilter 方法可以设置滤镜效果,滤镜本身是一个直方图文件。setSpecialRatio 方法可以设置滤镜的程度,从 0 到 1,越大滤镜效果越明显,默认值为 0.5。 Bitmap bitmap = BitmapUtils.decodeResource(getResources, R.drawable.langman); if (mLivePusher) if (mLivePusher ! = null) { mLivePusher.setFilter(bmp); } 控制摄像头 腾讯云 sdk 默认为前置摄像头(可以通过修改 TXLivePushConfig 的配置函数 setFrontCamera 来修改默认值),调用一次 switchCamera 就切换一次,注意切换摄像头前要确保 TXLivePushConfig 和 TXLivePusher 对象已经初始化。 mLivePushConfig.setFrontCamera(true); // 默认前置摄像头。 mLivePusher.switchCamera; //切换摄像头。 ⑦ 设置徽标水印 腾讯视频云目前支持两种设置水印的方式:一种是在流媒体 SDK 中设置水印,原理是在 SDK 中对视频进行编码前在画面中设置水印。另一种方式是在云端设置水印,即由云端解析视频并添加水印标识。 建议使用 SDK 添加水印,因为在云端添加水印会有问题。下面是添加水印的 SDK 介绍: //设置视频水印 mLivePushConfig.setWatermark(BitmapFactory.decodeResource(getResources,R.drawable.watermark), 10, 10); // 最后两个参数是视频的水印。 //最后两个参数是水印位置的 X 轴和 Y 轴坐标。 mLivePusher.setConfig(mLivePushConfig); 如果需要对水印图像的位置进行模型适配,则需要调用水印规范化接口。 /设置视频水印 mLivePushConfig.setWatermark(mBitmap, 0.02f, 0.05f, 0.2f); //参数为水印图像。 //参数包括水印图像的位图、水印位置的 X 轴坐标、水印位置的 Y 轴坐标和水印宽度。后三个参数的范围是 [0,1]。 // 最后两个参数是水印位置的 X 轴坐标和 Y 轴坐标。 mLivePusher.setConfig(mLivePushConfig); TXLivePushConfig 中的 setHardwareAcceleration 方法可以启用或禁用硬件编码。 if (mHWVideoEncode){ if (mLivePushConfig ! = null) { if (Build.VERSION.SDK_INT < 18){ Toast.makeText(getApplicationContext, "Hardware acceleration failed, current phone API level is too low (min 18)"、 Toast.LENGTH_SHORT).show; mHWVideoEncode = false; } } } } mLivePushConfig.setHardwareAcceleration(mHWVideoEncode ? TXLiveConstants.ENCODE_VIDEO_HARDWARE : TXLiveConstants.ENCODE_VIDEO_SOFTWARE); mLivePusher.setConfig(mLivePushConfig); // 如果您不确定何时启用硬件加速,建议将其设置为 ENCODE_VIDEO_AUTO。 // 默认情况下启用软件编码,但如果手机的 CPU 使用率超过 80% 或帧速率为 10,SDK 将自动切换到硬件编码。 ⑨ 后台推流 在常规模式下,一旦应用程序进入后台,摄像头捕捉数据的能力就会被 Android 禁用,这意味着 SDK 无法继续捕捉和编码音频和视频数据。如果我们什么都不做,故事就会按照下面的脚本发展: 阶段 1(背景剪切后 10 秒 ->)- CDN 无法将视频流传输给观众,因为没有数据,观众看到的是主帧。 阶段 2(10 秒-> 70 秒)--观众一方的播放器因无法接收到直播流而退出,房间里空无一人。 第 3 阶段(70 秒后)--服务器直接断开了推送流媒体的 RTMP 链接,主播需要重新打开直播才能继续。 主播可能只是短暂地接了一个紧急电话,但各云提供商的安全措施会迫使主播的直播提前结束。 1) 设置 setPauseFlag 在开始推流之前,使用 TXLivePushConfig 的 setPauseImg 接口设置一个等待图像,其含义建议为 "主播将暂时离开,稍后再回来"。
-
实现实时无延迟的音频和视频组播传输方法