本文介绍拉流 SDK 进阶功能的接入方式,支持的进阶功能包括但不限于 RTM 协议拉流、QUIC 协议拉流、使用 IP 地址拉流、使用主备流、多档位手动切换、自适应码率(ABR)拉流、截图、画中画、SEI,以及订阅视频和音频数据。您可以根据实际业务需求,借助拉流 SDK 实现更复杂的功能。
注意
试用版 License 仅用于项目测试,不支持续签。过期的试用版 License 会导致鉴权失败,进而中断服务。请在项目上线前升级为正式版 License。详见升级试用版 License 为基础版或高级版 License。
真机调试:由于 SDK 使用了大量 Android 系统的音视频接口,这些接口在模拟器下可能会出现异常,推荐您使用真机进行代码调试。
如果您只配置一个拉流地址,一旦因网络等问题导致使用该地址拉流失败,直播可能会卡顿,甚至无法播放。为降低单个地址异常带来的播放失败风险,您可以为一次播放配置多个拉流地址,并按需选择以下配置方式:
说明
仅高级版或试用版 License 支持主备流切换。流降级策略不受 License 版本限制。
priority,从高到低尝试播放当前列表中的流。retryMaxCount 进行重试。在此过程中,SDK 会通过以下回调通知您当前的状态:
通过以下任一方式,获取 RTM、FLV 等协议的拉流地址,用于配置主流列表或备流列表。同一列表内的降级顺序由各拉流地址的优先级决定。
您可以通过配置 VeLivePlayerStream 的 priority 和 retryMaxCount,来自定义降级策略。
priority:流的优先级。取值必须为 0(默认值)或正整数。取值越大,优先级越高。播放器会优先尝试播放高优先级的流。说明
主流列表和备流列表的优先级是独立计算的,互不影响。
retryMaxCount:流的最大重试次数,即总播放尝试次数(包含首次尝试)。例如,若取值为 3,则在首次播放失败后,播放器最多会再重试 2 次。取值如下:
-1(默认值):使用 VeLivePlayerConfiguration 中 retryMaxCount 的取值。0:不会尝试播放当前流。>0:具体次数。以下示例代码演示了基础的流降级策略场景,其播放顺序如下:
// 创建 VeLivePlayerStreamData 实例。 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); List<VeLivePlayerStreamData.VeLivePlayerStream> mainStreams = new ArrayList<>(); // 添加 RTM 主流 (最高优先级)。 VeLivePlayerStreamData.VeLivePlayerStream rtmStream = new VeLivePlayerStreamData.VeLivePlayerStream(); rtmStream.url = "https://xxx.sdp"; // 替换为实际 RTM 拉流地址。 rtmStream.format = VeLivePlayerFormatRTM; rtmStream.streamType = VeLivePlayerDef.VeLivePlayerStreamType.VeLivePlayerStreamTypeMain; rtmStream.retryMaxCount = 3; rtmStream.priority = 5; mainStreams.add(rtmStream); // 添加 FLV 主流作为降级流。 VeLivePlayerStreamData.VeLivePlayerStream flvStream = new VeLivePlayerStreamData.VeLivePlayerStream(); flvStream.url = "https://xxx.flv"; // 替换为实际 FLV 拉流地址。 flvStream.format = VeLivePlayerFormatFLV; flvStream.streamType = VeLivePlayerDef.VeLivePlayerStreamType.VeLivePlayerStreamTypeMain; flvStream.retryMaxCount = 2; flvStream.priority = 4; mainStreams.add(flvStream); streamData.mainStreamList = mainStreams; // 配置播放源。 mLivePlayer.setPlayStreamData(streamData); // 开始播放。 mLivePlayer.play();
按需添加以下回调,监听降级过程中的事件。
@Override public void onStreamFormatSwitch( VeLivePlayer player, VeLivePlayerFormat fromStreamFormat, VeLivePlayerFormat toStreamFormat, VeLivePlayerError error, Bundle extraInfo ) { }
@Override public void onInfo( VeLivePlayer player, VeLivePlayerError error ) { }
@Override public void onMainBackupSwitch( VeLivePlayer player, VeLivePlayerStreamType streamType, VeLivePlayerError error ) { }
@Override public void onError( VeLivePlayer player, VeLivePlayerError error ) { }
RTM 协议拉流可将直播延迟降低至 1-2 秒,为观众提供优质的直播体验。
然而,RTM 的超低延迟特性也对网络环境提出了更高要求。在网络不稳定的情况下,可能会出现播放延迟、卡顿或失败。如果您希望在 RTM 拉流地址不可用时自动尝试 FLV 等其他协议的拉流地址,可以结合流降级策略或主备流切换使用。详见流降级策略与主备流切换。
说明
仅高级版或试用版 License 支持 RTM 协议拉流。
本文提供以下两个代码示例,分别对应了从简单到复杂的应用场景:
建议您从基础场景开始了解。
以下示例代码演示了基础的流降级策略场景,其播放顺序如下:
// 创建 VeLivePlayerStreamData 实例。 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); List<VeLivePlayerStreamData.VeLivePlayerStream> mainStreams = new ArrayList<>(); // 添加 RTM 主流 (最高优先级)。 VeLivePlayerStreamData.VeLivePlayerStream rtmStream = new VeLivePlayerStreamData.VeLivePlayerStream(); rtmStream.url = "https://xxx.sdp"; // 替换为实际 RTM 拉流地址。 rtmStream.format = VeLivePlayerFormatRTM; rtmStream.streamType = VeLivePlayerDef.VeLivePlayerStreamType.VeLivePlayerStreamTypeMain; rtmStream.retryMaxCount = 3; rtmStream.priority = 5; mainStreams.add(rtmStream); // 添加 FLV 主流作为降级流。 VeLivePlayerStreamData.VeLivePlayerStream flvStream = new VeLivePlayerStreamData.VeLivePlayerStream(); flvStream.url = "https://xxx.flv"; // 替换为实际 FLV 拉流地址。 flvStream.format = VeLivePlayerFormatFLV; flvStream.streamType = VeLivePlayerDef.VeLivePlayerStreamType.VeLivePlayerStreamTypeMain; flvStream.retryMaxCount = 2; flvStream.priority = 4; mainStreams.add(flvStream); streamData.mainStreamList = mainStreams; // 配置播放源。 mLivePlayer.setPlayStreamData(streamData); // 开始播放。 mLivePlayer.play();
开启 FLV 低延时后,FLV 协议拉流可将直播延迟降至 2-3 秒。
说明
使用 FLV 低延时功能时,请确保已集成 1.50.2 及以上版本的 SDK,并使用高级版或试用版 License。
在开始播放前,您可通过播放器的 setProperty 高级接口开启 FLV 低延时。调用 setProperty 接口时,需传入一组 Key-Value 配置。
Key
| 参数名 | 类型 | 说明 |
|---|---|---|
| VeLivePlayerKeySetParamsLowLatencyFLV | VeLivePlayerProperty | FLV 低延时功能对应的属性 Key。 |
Value
Value 为 JSONObject 类型,表示需要传入一个 Key-Value 形式的对象,用于配置 FLV 低延时功能。
Key:String 类型。固定取值为 EnableLowLatencyFLV,表示是否开启 FLV 低延时。Value:Integer 类型。取值为 1 表示开启 FLV 低延时,取值为 0 表示关闭 FLV 低延时。默认值为 0。示例代码如下所示。
JSONObject flv2s = new JSONObject(); flv2s.put("EnableLowLatencyFLV", 1); mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsLowLatencyFLV, flv2s);
视频直播拉流 SDK 支持 QUIC 协议拉流,该功能需要配合火山引擎视频直播服务使用。
说明
仅高级版或试用版 License 支持 QUIC 协议拉流。
使用视频直播控制台的地址生成器,生成 FLV 拉流地址。
配置 QUIC 拉流地址进行播放。代码示例如下所示。
VeLivePlayerStreamData.VeLivePlayerStream playStreamFLV = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamFLV.url = "https://pull.example.com/live/stream.flv"; // 替换为实际 FLV 拉流地址。 playStreamFLV.format = VeLivePlayerFormatFLV; playStreamFLV.protocol = VeLivePlayerProtocolQUIC; playStreamFLV.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); playStreamFLV.streamType = VeLivePlayerStreamTypeMain; // 创建播放源 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); streamData.mainStreamList = new ArrayList<>(); // 添加 FLV 流 streamData.mainStreamList.add(playStreamFLV); // 配置播放源 mLivePlayer.setPlayStreamData(streamData); // 开始播放 mLivePlayer.play();
说明
拉流 SDK 默认开启了 QUIC 协议拉流的失败降级策略,无需额外配置。如果 QUIC 协议拉流失败,SDK 将自动降级为 TCP 协议拉流。
播放器支持通过设置播放域名的 IP 地址进行拉流,以降低播放首帧时间。
请先获取直播播放地址并解析出 IP 地址。
false。使用播放器的 setUrlHostIP 接口将 IP 地址与域名关联起来,播放器将直接根据 IP 地址进行拉流播放。代码示例如下所示。
mLivePlayer.setPlayUrl("https://pull.example.com/live/stream.flv"); // 替换为实际直播播放地址。 // 配置直播播放地址中的域名与其解析出的 IP 地址的映射关系。 List<String> valueList = new ArrayList<>(); valueList.add("xxx.xxx.xxx.xxx"); // 替换为该域名解析出的实际 IP 地址。 Map<String, List<String>> map = new HashMap<>(); map.put("pull.example.com", valueList); // 将 pull.example.com 替换为实际直播播放地址中的域名。 // 设置域名与 IP 地址的映射关系。 mLivePlayer.setUrlHostIP(map); // 开始播放。 mLivePlayer.play();
播放器支持配置多档位的直播拉流地址,通过接口可以实现多档位直播流的切换。
说明
多档位手动切换支持配置降级流策略。您可以为同一组多档位流设置相同的优先级,并配置低优先级降级流,当高优先级多档位流播放失败时,SDK 会自动尝试降级流。详见流降级策略与主备流切换。
获取源流和各档位转码流拉流地址。如您使用了火山引擎视频直播服务,请先登录控制台完成转码配置,再获取拉流地址,获取方法如下所示。
本文的接入说明以下列拉流地址为例。
| 档位 | 拉流地址 |
|---|---|
| 原始(Origin) | https://pull.example.com/live/123456.flv |
| 超清(UHD) | https://pull.example.com/live/123456_uhd.flv |
| 高清(HD) | https://pull.example.com/live/123456_hd.flv |
| 标清(SD) | https://pull.example.com/live/123456_sd.flv |
| 流畅(LD) | https://pull.example.com/live/123456_ld.flv |
// 配置多档位流地址 VeLivePlayerStreamData.VeLivePlayerStream playStreamOrigin = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamOrigin.url = "https://pull.example.com/live/123456.flv"; // 替换为实际原始档位拉流地址。 playStreamOrigin.format = VeLivePlayerFormatFLV; playStreamOrigin.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); // 原始档位 playStreamOrigin.streamType = VeLivePlayerStreamTypeMain; VeLivePlayerStreamData.VeLivePlayerStream playStreamUHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamUHD.url = "https://pull.example.com/live/123456_uhd.flv"; // 替换为实际超清档位拉流地址。 playStreamUHD.format = VeLivePlayerFormatFLV; playStreamUHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD); // 超清档位 playStreamUHD.streamType = VeLivePlayerStreamTypeMain; VeLivePlayerStreamData.VeLivePlayerStream playStreamHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamHD.url = "https://pull.example.com/live/123456_hd.flv"; // 替换为实际高清档位拉流地址。 playStreamHD.format = VeLivePlayerFormatFLV; playStreamHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionHD); // 高清档位 playStreamHD.streamType = VeLivePlayerStreamTypeMain; VeLivePlayerStreamData.VeLivePlayerStream playStreamSD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamSD.url = "https://pull.example.com/live/123456_sd.flv"; // 替换为实际标清档位拉流地址。 playStreamSD.format = VeLivePlayerFormatFLV; playStreamSD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionSD); // 标清档位 playStreamSD.streamType = VeLivePlayerStreamTypeMain; VeLivePlayerStreamData.VeLivePlayerStream playStreamLD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamLD.url = "https://pull.example.com/live/123456_ld.flv"; // 替换为实际流畅档位拉流地址。 playStreamLD.format = VeLivePlayerFormatFLV; playStreamLD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionLD); // 流畅档位 playStreamLD.streamType = VeLivePlayerStreamTypeMain; // 创建播放源 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); // 添加多档位流 streamData.mainStreamList = new ArrayList<>(); streamData.mainStreamList.add(playStreamOrigin); streamData.mainStreamList.add(playStreamUHD); streamData.mainStreamList.add(playStreamHD); streamData.mainStreamList.add(playStreamSD); streamData.mainStreamList.add(playStreamLD); // 配置默认启播档位 streamData.defaultResolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); // 配置播放源 mLivePlayer.setPlayStreamData(streamData); // 开始播放 mLivePlayer.play();
mLivePlayer.switchResolution(new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD)); // 切换到超清档位
public void onResolutionSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerDef.VeLivePlayerResolutionSwitchReason reason) { // 档位切换回调 }
自适应码率(ABR,adaptive bitrate)拉流可在网络变化时自动切换到更合适的清晰度档位,降低卡顿风险。
说明
Android 拉流 SDK 支持以下 ABR 拉流模式:
注意
仅 1.51.1 及以上版本支持 RTM-ABR 流。
StreamType 设置为 abr,动态生成 RTM-ABR 拉流地址。不同后缀对应不同的起播清晰度档位,请从返回结果中选择一个 Protocol 取值为 rtm-abr、Tag 取值为 RTM-ABR-NativeSDK 的地址起播。注意
不要在普通 RTM 拉流地址后手动追加 rtmabr=true。只有完成 RTM-ABR 配置并使用生成的 RTM-ABR 地址时,RTM-ABR 才会生效。
设置 RTM-ABR 拉流地址并开始播放。
mLivePlayer.setPlayUrl("https://pull.example.com/live/test_uhd.sdp?rtmabr=true"); // 替换为实际 RTM-ABR 拉流地址。 // 开始播放。 mLivePlayer.play();
获取源流和各档位转码流拉流地址。如您使用了火山引擎视频直播服务,请先登录控制台完成转码配置,再获取拉流地址,获取方法如下所示。
本文的接入说明以下列拉流地址为例。
| 档位说明 | 拉流地址 | 码率(kbps) |
|---|---|---|
| 原始(Origin) | https://pull.example.com/live/123456.flv | 2500 |
| 超清(UHD) | https://pull.example.com/live/123456_uhd.flv | 2500 |
| 高清(HD) | https://pull.example.com/live/123456_hd.flv | 1000 |
| 标清(SD) | https://pull.example.com/live/123456_sd.flv | 800 |
| 流畅(LD) | https://pull.example.com/live/123456_ld.flv | 500 |
// 配置多档位流地址 VeLivePlayerStreamData.VeLivePlayerStream playStreamOrigin = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamOrigin.url = "https://pull.example.com/live/123456.flv"; // 替换为实际原始档位拉流地址。 playStreamOrigin.format = VeLivePlayerFormatFLV; playStreamOrigin.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); // 原始档位 playStreamOrigin.streamType = VeLivePlayerStreamTypeMain; playStreamOrigin.bitrate = 2500; VeLivePlayerStreamData.VeLivePlayerStream playStreamUHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamUHD.url = "https://pull.example.com/live/123456_uhd.flv"; // 替换为实际超清档位拉流地址。 playStreamUHD.format = VeLivePlayerFormatFLV; playStreamUHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD); // 超清档位 playStreamUHD.streamType = VeLivePlayerStreamTypeMain; playStreamUHD.bitrate = 2500; VeLivePlayerStreamData.VeLivePlayerStream playStreamHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamHD.url = "https://pull.example.com/live/123456_hd.flv"; // 替换为实际高清档位拉流地址。 playStreamHD.format = VeLivePlayerFormatFLV; playStreamHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionHD); // 高清档位 playStreamHD.streamType = VeLivePlayerStreamTypeMain; playStreamHD.bitrate = 1000; VeLivePlayerStreamData.VeLivePlayerStream playStreamSD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamSD.url = "https://pull.example.com/live/123456_sd.flv"; // 替换为实际标清档位拉流地址。 playStreamSD.format = VeLivePlayerFormatFLV; playStreamSD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionSD); // 标清档位 playStreamSD.streamType = VeLivePlayerStreamTypeMain; playStreamSD.bitrate = 800; VeLivePlayerStreamData.VeLivePlayerStream playStreamLD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamLD.url = "https://pull.example.com/live/123456_ld.flv"; // 替换为实际流畅档位拉流地址。 playStreamLD.format = VeLivePlayerFormatFLV; playStreamLD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionLD); // 流畅档位 playStreamLD.streamType = VeLivePlayerStreamTypeMain; playStreamLD.bitrate = 500; // 创建播放源 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); // 添加多档位流 streamData.mainStreamList = new ArrayList<>(); streamData.mainStreamList.add(playStreamOrigin); streamData.mainStreamList.add(playStreamUHD); streamData.mainStreamList.add(playStreamHD); streamData.mainStreamList.add(playStreamSD); streamData.mainStreamList.add(playStreamLD); // 配置默认启播档位 streamData.defaultResolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); // 开启 ABR streamData.enableABR = true; // 配置播放源 mLivePlayer.setPlayStreamData(streamData); // 开始播放 mLivePlayer.play();
public void onResolutionSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerDef.VeLivePlayerResolutionSwitchReason reason) { // 档位切换回调 }
平滑切档功能可确保在观众手动切换直播清晰度(如超清、高清、标清)时,音画能够无缝衔接,从而避免出现黑屏或卡顿,提升观看体验。
要使用此功能,您需要为播放器配置一个包含多档位清晰度的同源流列表,并开启平滑切档开关。配置后,当观众手动切换清晰度档位时,播放器会在不同码率的流之间平滑过渡,保障直播音画的连续性和稳定性。
说明
平滑切档支持配置降级流策略。您可以为同一组平滑切档流设置相同的优先级,并配置低优先级降级流,当高优先级平滑切档流播放失败时,SDK 会自动尝试降级流。详见流降级策略与主备流切换。
注意
准备同一源流不同清晰度档位的拉流地址。
如使用视频直播的推流地址进行推流,请确保已完成:
AppName 和 StreamName。例如推流地址为 rtmp://push.example.com/live/test?authinfo,则 AppName 为 live,StreamName 为 test。| 档位 | FLV 拉流地址 | 码率(kbps) |
|---|---|---|
| 原始(Origin) | https://pull.example.com/live/123456.flv | 2500 |
| 超清(UHD) | https://pull.example.com/live/123456_uhd.flv | 2500 |
| 高清(HD) | https://pull.example.com/live/123456_hd.flv | 1000 |
| 标清(SD) | https://pull.example.com/live/123456_sd.flv | 800 |
| 流畅(LD) | https://pull.example.com/live/123456_ld.flv | 500 |
true,开启平滑切档。// 配置各清晰度档位的流。 // 原始档位。 VeLivePlayerStreamData.VeLivePlayerStream playStreamOrigin = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamOrigin.url = "https://pull.example.com/live/123456.flv"; // 替换为实际原始档位拉流地址。 playStreamOrigin.format = VeLivePlayerFormatFLV; // 流格式。 playStreamOrigin.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionOrigin); // 清晰度档位标识。 playStreamOrigin.streamType = VeLivePlayerStreamTypeMain; // 主备流类型,用于区分主流和备流。 playStreamOrigin.bitrate = 2500; // 码率。单位:kbps。 // 超清档位。 VeLivePlayerStreamData.VeLivePlayerStream playStreamUHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamUHD.url = "https://pull.example.com/live/123456_uhd.flv"; // 替换为实际超清档位拉流地址。 playStreamUHD.format = VeLivePlayerFormatFLV; // 流格式。 playStreamUHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD); // 清晰度档位标识。 playStreamUHD.streamType = VeLivePlayerStreamTypeMain; // 主备流类型,用于区分主流和备流。 playStreamUHD.bitrate = 2500; // 码率。单位:kbps。 // 高清档位。 VeLivePlayerStreamData.VeLivePlayerStream playStreamHD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamHD.url = "https://pull.example.com/live/123456_hd.flv"; // 替换为实际高清档位拉流地址。 playStreamHD.format = VeLivePlayerFormatFLV; // 流格式。 playStreamHD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionHD); // 清晰度档位标识。 playStreamHD.streamType = VeLivePlayerStreamTypeMain; // 主备流类型,用于区分主流和备流。 playStreamHD.bitrate = 1000; // 码率。单位:kbps。 // 标清档位。 VeLivePlayerStreamData.VeLivePlayerStream playStreamSD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamSD.url = "https://pull.example.com/live/123456_sd.flv"; // 替换为实际标清档位拉流地址。 playStreamSD.format = VeLivePlayerFormatFLV; // 流格式。 playStreamSD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionSD); // 清晰度档位标识。 playStreamSD.streamType = VeLivePlayerStreamTypeMain; // 主备流类型,用于区分主流和备流。 playStreamSD.bitrate = 800; // 码率。单位:kbps。 // 流畅档位。 VeLivePlayerStreamData.VeLivePlayerStream playStreamLD = new VeLivePlayerStreamData.VeLivePlayerStream(); playStreamLD.url = "https://pull.example.com/live/123456_ld.flv"; // 替换为实际流畅档位拉流地址。 playStreamLD.format = VeLivePlayerFormatFLV; // 流格式。 playStreamLD.resolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionLD); // 清晰度档位标识。 playStreamLD.streamType = VeLivePlayerStreamTypeMain; // 主备流类型,用于区分主流和备流。 playStreamLD.bitrate = 500; // 码率。单位:kbps。 // 创建播放源。 VeLivePlayerStreamData streamData = new VeLivePlayerStreamData(); // 添加各清晰度档位的流。 streamData.mainStreamList = new ArrayList<>(); streamData.mainStreamList.add(playStreamOrigin); streamData.mainStreamList.add(playStreamUHD); streamData.mainStreamList.add(playStreamHD); streamData.mainStreamList.add(playStreamSD); streamData.mainStreamList.add(playStreamLD); // 配置默认启播档位。 streamData.defaultResolution = new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionSD); // 开启平滑切档功能。 streamData.enableSmoothSwitchResolution = true; // 配置播放源。 mLivePlayer.setPlayStreamData(streamData); // 开始播放。 mLivePlayer.play();
mLivePlayer.switchResolution(new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD)); // 切换到超清档位。
@Override public void onResolutionSwitch( VeLivePlayer player, VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerResolutionSwitchReason reason ) { }
截图功能允许您在播放器中截取当前直播画面并生成一张图片。
int result = mLivePlayer.snapshot();
public void onSnapshotComplete(VeLivePlayer player, Bitmap bitmap) { // 截图成功回调,参数 bitmap 为截图的图片数据 }
SEI(Supplemental Enhancement Information)是直播流中的附加信息,可用于传递自定义数据或元数据。
说明
仅高级版或试用版 License 支持 SEI。
// 创建播放器初始化配置。 VeLivePlayerConfiguration config = new VeLivePlayerConfiguration(); // 开启字符串 SEI 消息接收功能。 config.enableSei = true; // 初始化配置。 mLivePlayer.setConfig(config);
public void onReceiveSeiMessage(VeLivePlayer player, String message) { // 字符串 SEI 消息回调。 }
// 创建播放器初始化配置。 VeLivePlayerConfiguration config = new VeLivePlayerConfiguration(); // 开启二进制 SEI 消息接收功能。 config.enableBinarySei = true; // 初始化配置。 mLivePlayer.setConfig(config);
public void onReceiveBinarySeiMessage(VeLivePlayer player, byte[] message) { // 二进制 SEI 消息回调。 }
通过订阅解码后的视频数据,您可以获取视频帧数据并进行自定义的处理和渲染操作。播放器支持多种视频帧数据的回调,并提供了相应的参数和格式选项。
视频帧像素格式和视频数据封装格式的枚举和含义如下表所示。
| 格式类型 | 枚举 | 说明 |
|---|---|---|
视频帧像素格式 | VeLivePlayerPixelFormatRGBA32 | RGBA32 |
| VeLivePlayerPixelFormatTexture | 2D 纹理 | |
视频数据封装格式 | VeLivePlayerVideoBufferTypeByteBuffer | ByteBuffer |
| VeLivePlayerVideoBufferTypeByteArray | ByteArray | |
| VeLivePlayerVideoBufferTypeTexture | 纹理 |
配置订阅视频数据前,请您根据需要选择格式组合。格式组合需要遵循下表中提供的 VeLivePlayerPixelFormat 和 VeLivePlayerVideoBufferType 的对应关系。
| 像素格式/封装格式 | VeLivePlayerPixelFormatRGBA32 | VeLivePlayerPixelFormatTexture |
|---|---|---|
| VeLivePlayerVideoBufferTypeByteBuffer | √ | × |
| VeLivePlayerVideoBufferTypeByteArray | √ | × |
| VeLivePlayerVideoBufferTypeTexture | × | √(性能最优) |
| 参数 | 类型 | 说明 |
|---|---|---|
| enable | boolean | 是否开启视频帧回调。 |
| pixelFormat | VeLivePlayerPixelFormat | 视频帧像素格式。 |
| bufferType | VeLivePlayerVideoBufferType | 视频数据封装格式。 |
mLivePlayer.enableVideoFrameObserver(true, VeLivePlayerPixelFormatRGBA32, VeLivePlayerVideoBufferTypeByteBuffer);
VeLivePlayerVideoFrame 参数说明如下表所示。public void onRenderVideoFrame(VeLivePlayer player, VeLivePlayerVideoFrame videoFrame) { // 视频帧数据回调 }
| 参数 | 类型 | 说明 |
|---|---|---|
| bufferType | VeLivePlayerVideoBufferType | 视频帧数据封装格式 |
| pixelFormat | VeLivePlayerPixelFormat | 视频帧像素格式 |
| width | int | 视频帧的宽度,单位为 px |
| height | int | 视频帧的高度,单位为 px |
| pts | long | 视频帧的渲染时间戳,单位为 ms |
| texture | VeLivePlayerVideoTexture | 当 bufferType 为 VeLivePlayerVideoBufferTypeTexture 时的视频数据,承载用于 OpenGL 渲染的纹理数据 |
| buffer | ByteBuffer | 当 bufferType 为 VeLivePlayerVideoBufferTypeByteBuffer 时的视频数据,承载用于 JNI 层的 Direct Buffer |
| data | byte[] | 当 bufferType 为 VeLivePlayerVideoBufferTypeByteArray 时的视频数据,承载用于 Java 层的字节数组数据 |
通过订阅解码后的音频数据,您可以获取音频帧数据并进行自定义的处理和渲染操作。
播放器支持的音频帧数据格式为 PCM Float32,数据封装格式为 ByteArray。
| VeLivePlayerAudioBufferType | 音频数据封装格式 |
|---|---|
| VeLivePlayerAudioBufferTypeByteArray | ByteArray |
| 参数 | 类型 | 说明 |
|---|---|---|
| enable | boolean | 是否开启音频帧回调。 |
| enableRendering | boolean | 是否开启播放器渲染。当不需要播放器内部进行音频播放时,可以将该参数值配置为 false。 |
// 订阅音频帧数据,打开播放器内部音频渲染 mLivePlayer.enableAudioFrameObserver(true, true);
VeLivePlayerAudioFrame 参数说明如下表所示。void onRenderAudioFrame(VeLivePlayer player, VeLivePlayerAudioFrame audioFrame) { // 音频帧数据回调 }
| 参数 | 数据类型 | 说明 |
|---|---|---|
| bufferType | VeLivePlayerAudioBufferType | 音频帧数据封装格式 |
| sampleRate | int | 音频采样率,单位为 Hz |
| channels | int | 声道数 |
| bitDepth | int | 音频位深度 |
| pts | long | 音频渲染时间戳,单位为 ms |
| buffer | byte[] | PCM 音频数据 |
| samples | int | 音频采样点个数 |
超分,即超分辨率技术(Super-Resolution, SR)是指从观测到的低分辨率图像重建出相应的高分辨率图像的过程,移动端实时超分,是指利用算法技术在端上对低分辨率的帧进行实时重建,产生高分辨率的帧显示在屏幕上,从而改善视频内容的细节与对比度,全面提升视频的播放清晰度和观看体验的优化手段。
说明
仅高级版或试用版 License 支持拉流超分。
mLivePlayer.setEnableSuperResolution(true);
| 参数名 | 类型 | 说明 |
|---|---|---|
enable | boolean | 是否开启超分。默认值为
|
开启超分失败的常见原因如下:void onStreamFailedOpenSuperResolution(VeLivePlayer player, VeLivePlayerError error);
直播拉流 SDK 支持调用火山引擎 HTTPDNS 服务对拉流地址的预解析,以此来降低播放首帧时长。

VeLiveCommon.setVeHttpDNSAuth(getApplicationContext(), "http_dns_serviceID", "http_dns_key"); // 分别替换为实际的 Service ID 和 Secret Key。
List<String> domains = new ArrayList<String>(); domains.add("xxx.pull.com"); // 替换为实际拉流域名。 domains.add("yyy.pull.com"); // 替换为实际拉流域名。 VeLiveCommon.prefetchDomains(domains);
设置播放器发起 HTTP 请求时携带的自定义请求头。常用于传递鉴权令牌(Token)、Cookie 或业务追踪标识等额外信息。
说明
仅 1.50.2 及以上版本支持自定义 HTTP 请求头。
在开始播放前,您可通过播放器的 setProperty 高级接口设置自定义 HTTP 请求头。调用 setProperty 接口时,需传入一组 Key-Value 配置。
Key
| 参数名 | 类型 | 说明 |
|---|---|---|
| VeLivePlayerKeySetParamsHttpHeaders | VeLivePlayerProperty | 自定义 HTTP 请求头功能对应的属性 Key。 |
Value
Value 为 Map<String, String> 类型,表示需要传入一个 Key-Value 形式的映射对象,用于设置自定义 HTTP 请求头。
Key:String 类型,请求头名称。Value:String 类型,请求头值。示例代码如下所示。
Map<String, String> headerMap = new HashMap<>(); headerMap.put("key", "value"); // 分别替换为实际的请求头名称和请求头值。 mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsHttpHeaders, headerMap);
Map<String, String> headerMap = new HashMap<>(); headerMap.put("key1", "value1"); // 分别替换为实际的请求头名称和请求头值。 headerMap.put("key2", "value2"); // 分别替换为实际的请求头名称和请求头值。 headerMap.put("key3", "value3"); // 分别替换为实际的请求头名称和请求头值。 mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsHttpHeaders, headerMap);
SDK 高级版或试用版 License 默认开启 H.265 硬解(硬件解码)和软解(软件解码)功能。播放 H.265 编码的视频流时,SDK 会优先尝试使用 H.265 硬解。如果 H.265 硬解失败,SDK 会自动切换为 H.265 软解。
请在调用 play 前,通过播放器初始化配置开启或关闭硬解。示例代码如下所示。
VeLivePlayerConfiguration config = new VeLivePlayerConfiguration(); config.enableHardwareDecode = true; mLivePlayer.setConfig(config);
true:开启硬解。false:关闭硬解,只使用软解。您可以通过监听 onStatistics 回调,并结合 VeLivePlayerStatistics 的 isHardwareDecode 属性,判断当前播放的流是否使用了硬解。
SDK 高级版或试用版 License 默认开启 H.266 软解,无需额外配置。
视频锐化指在设备本地对视频画面进行增强处理,从而提升画面边缘和纹理细节表现的能力。播放视频时,SDK 可以实时增强画面边缘和纹理细节,从而让画面看起来更清晰,提升观看体验。
说明
仅高级版或试用版 License 支持视频锐化。
mLivePlayer.setEnableSharpen(true);
| 参数名 | 类型 | 说明 |
|---|---|---|
enable | boolean | 是否开启视频锐化。默认值为
|
开启视频锐化失败的常见原因如下:void onStreamFailedOpenSharpen(VeLivePlayer player, VeLivePlayerError error);
画中画功能通过将播放器窗口缩小并置于界面一角,允许观众在观看直播的同时浏览其他内容或打开其他应用,从而提升用户体验。
Android 6.0 及以上系统。
vepicutureinpicture/live/build.gradle 中依赖的 SDK 版本号。请将 x.x.x.x 替换为您实际集成的 SDK 版本号。版本号详见 Android 拉流 SDK 发布历史。implementation 'com.bytedanceapi:ttsdk-ttlivepull_premium:x.x.x.x'
vepicutureinpicture module。可参考 VeLiveQuickStartDemo 进行配置。include ':vepicutureinpicture:live' include ':vepicutureinpicture:base' api project(path: ':vepicutureinpicture:live')
// mLivePlayer 为播放器实例。 VeLivePictureInPicturePlayerManager mPipManager = new VeLivePictureInPicturePlayerManager(mLivePlayer, context);
XXXActivity 请替换为您工程中承载直播播放页的 Activity。mPipManager.setObserver(new VeLivePictureInPicturePlayerManager.VeLivePictureInPicturePlayerManagerObserver() { @Override public void onClickResumeAction() { // 从画中画恢复正常播放。 try { Class<?> cls = Class.forName(XXXActivity.class.getName()); Intent intent = new Intent(getBaseContext(), cls); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } catch (ClassNotFoundException e) { } } });
如未获取系统悬浮窗权限,可参考以下示例代码申请该权限,并引导用户根据界面提示前往系统设置页开启系统悬浮窗权限。boolean isPermission = mPipManager.isPermissionGranted();
if (!isPermission) { mPipManager.requestPermission(new VePictureInPictureManager.VePictureInPicturePermissionCallback() { @Override public void onGranted(boolean granted) { // 权限申请结果回调。true 表示已获得系统悬浮窗权限,false 表示未获得系统悬浮窗权限。 } @Override public void onRequestPermission(Context context, VePictureInPictureManager.VePictureInPicturePermissionResult result) { // 引导用户前往系统设置页开启系统悬浮窗权限。 new AlertDialog.Builder(context) .setMessage("尚未开启系统悬浮窗,请去设置中开启 [显示悬浮窗] 权限") .setPositiveButton("去开启", (dialog, which) -> { // 用户同意开启系统悬浮窗权限。 result.accept(); }) .setNegativeButton("取消", (dialog, which) -> { // 用户未同意开启系统悬浮窗权限。 result.cancel(); }) .setCancelable(false) .show(); } }); }
Surface 或 SurfaceHolder 上。接入画中画功能后,也要把同一个 Surface 或 SurfaceHolder 传给画中画实例(即 mPipManager),这样进入画中画模式后才能继续显示当前直播画面。// 设置 Surface。 mLivePlayer.setSurface(surface); mPipManager.setSurface(surface);
mPipManager)。这样画中画会按视频实际宽高比显示画面。代码示例如下所示。mLivePlayer.setVeLivePlayerObserver(new VeLivePlayerObserver() { @Override public void onVideoSizeChanged(VeLivePlayer player, int width, int height) { mPipManager.setVideoSize(width, height); } });
VeLivePictureInPictureConfiguration configuration = new VeLivePictureInPictureConfiguration(); // 设置画中画窗口最大宽度为 720 px。最小宽度默认为最大宽度的 0.5 倍。高度按照视频宽高比自动计算。 configuration.maxWidth = 720; VeLivePictureInPicturePlayerManager.setConfiguration(configuration);
您也可以按照手机屏幕宽度占比设置画中画窗口大小。
VeLivePictureInPictureConfiguration configuration = new VeLivePictureInPictureConfiguration(); // 设置画中画窗口最大宽度为手机屏幕宽度的 0.5 倍。最小宽度默认为最大宽度的 0.5 倍。高度按照视频宽高比自动计算。 configuration.maxWidthRatio = 0.5; VeLivePictureInPicturePlayerManager.setConfiguration(configuration);
mPipManager.startPictureInPicture();
如当前已进入画中画模式,可停止画中画。
mPipManager.stopPictureInPicture();
boolean showing = mPipManager.isPictureInPictureShowing();
mPipManager.destroy();
拉流 SDK 可能会在拉流地址后追加 Query 参数,例如 session_id。这类参数用于标识同一次拉流会话,方便排查播放问题时,在客户端日志和 CDN 日志中定位同一次拉流。如需保持实际请求地址不增加由 SDK 自动追加的 Query 参数,可以开启该功能。开启后,会从实际请求地址中去除 SDK 自动拼接的 Query 参数,但原始拉流地址中已存在的 Query 参数会被保留。
说明
仅 1.52.1 及以上版本支持去除 SDK 自动拼接的 Query 参数。
在开始播放前,您可通过播放器的 setProperty 高级接口设置是否去除 SDK 自动拼接的 Query 参数。调用 setProperty 接口时,需传入一组 Key-Value 配置。
Key
| 参数名 | 类型 | 说明 |
|---|---|---|
| VeLivePlayerKeySetParamsRemoveQueryParams | VeLivePlayerProperty | 去除 SDK 自动拼接的 Query 参数功能对应的属性 Key。 |
Value
Value 为 Boolean 类型,表示是否去除 SDK 自动拼接的 Query 参数。默认值为 false。
true:去除 SDK 自动拼接的 Query 参数。false:保留 SDK 自动拼接的 Query 参数。示例代码如下所示。
mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsRemoveQueryParams, true);
效果示例
例如拉流地址为:
https://pull.example.com/live/test.flv?auth_key=1779891783-0-0-e1f5a2a****4b5fe21cb3efdc89af901
SDK 发起播放请求时自动拼接了 session_id:
https://pull.example.com/live/test.flv?auth_key=1779891783-0-0-e1f5a2a****4b5fe21cb3efdc89af901&session_id=xxx
开启该功能后,实际请求会去除 session_id,并保留原始拉流地址中的鉴权参数 auth_key:
https://pull.example.com/live/test.flv?auth_key=1779891783-0-0-e1f5a2a****4b5fe21cb3efdc89af901