You need to enable JavaScript to run this app.
文档中心
视频直播

视频直播

复制全文
下载 pdf
Android
进阶功能
复制全文
下载 pdf
进阶功能

本文介绍拉流 SDK 进阶功能的接入方式,支持的进阶功能包括但不限于 RTM 协议拉流、QUIC 协议拉流、使用 IP 地址拉流、使用主备流、多档位手动切换、自适应码率(ABR)拉流、截图、画中画、SEI,以及订阅视频和音频数据。您可以根据实际业务需求,借助拉流 SDK 实现更复杂的功能。

前提条件

注意事项

真机调试:由于 SDK 使用了大量 Android 系统的音视频接口,这些接口在模拟器下可能会出现异常,推荐您使用真机进行代码调试。

流降级策略与主备流切换

如果您只配置一个拉流地址,一旦因网络等问题导致使用该地址拉流失败,直播可能会卡顿,甚至无法播放。为降低单个地址异常带来的播放失败风险,您可以为一次播放配置多个拉流地址,并按需选择以下配置方式:

  • 流降级策略:适用于希望播放器按优先级自动尝试多个拉流地址的场景。您可以为每个地址配置优先级和最大重试次数。播放器会优先尝试高优先级地址。如果该地址在重试次数用尽后仍不可用,播放器会切换到下一个优先级的地址。
  • 主备流切换:适用于业务上已有明确主流列表和备流列表的场景。播放器会先在主流列表内按流降级策略尝试播放。只有当主流列表中的所有地址都播放失败后,才会自动切换到备流列表继续尝试。

说明

仅高级版或试用版 License 支持主备流切换。流降级策略不受 License 版本限制。

  • 流降级策略
    主流或备流列表中的播放顺序如下所示:
    1. 播放最高优先级的流:播放器会根据您设置的 priority,从高到低尝试播放当前列表中的流。
    2. 失败重试:如果当前流播放失败,播放器会根据该流的 retryMaxCount 进行重试。
    3. 切换到降级流:如果所有重试次数用尽后依然失败,播放器会放弃该流,并切换到当前列表中下一个优先级的流进行尝试。
  • 主备流切换
    开启主备流后,播放器会按照以下顺序尝试播放流:
    1. 播放主流:播放器会首先尝试播放主流列表中的流。
    2. 切换到备流:如果主流列表中的所有流都播放失败,播放器会尝试播放备流列表中的流。
    3. 播放失败:如果备流列表中的所有流都播放失败,播放将彻底失败。

在此过程中,SDK 会通过以下回调通知您当前的状态:

  • onInfo:当一个流播放失败,且存在下一个可用流时触发。您可以通过该回调获取详细的错误信息,以便进行调试。
  • onStreamFormatSwitch:当播放器切换流的格式时触发(例如,从 RTM 切换到 FLV)。
  • onMainBackupSwitch:当主流列表全部播放失败,播放器成功切换到备流列表时触发。
  • onError:当所有主流和备流都播放失败,播放最终结束时触发。

前提条件

通过以下任一方式,获取 RTM、FLV 等协议的拉流地址,用于配置主流列表或备流列表。同一列表内的降级顺序由各拉流地址的优先级决定。

接入说明

步骤一:配置降级策略

您可以通过配置 VeLivePlayerStream 的 priority 和 retryMaxCount,来自定义降级策略。

  • priority:流的优先级。取值必须为 0(默认值)或正整数。取值越大,优先级越高。播放器会优先尝试播放高优先级的流。

    说明

    主流列表和备流列表的优先级是独立计算的,互不影响。

  • retryMaxCount:流的最大重试次数,即总播放尝试次数(包含首次尝试)。例如,若取值为 3,则在首次播放失败后,播放器最多会再重试 2 次。取值如下:
    • -1(默认值):使用 VeLivePlayerConfiguration 中 retryMaxCount 的取值。
    • 0:不会尝试播放当前流。
    • >0:具体次数。

以下示例代码演示了基础的流降级策略场景,其播放顺序如下:

  1. 首先,尝试播放 RTM 流(优先级 5),最多尝试 3 次。
  2. 如果失败,则降级播放 FLV 流(优先级 4),最多尝试 2 次。
  3. 如果最后依然失败,播放将停止。
// 创建 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();

步骤二:添加回调

按需添加以下回调,监听降级过程中的事件。

  • 监听流格式切换,例如从 RTM 切换到 FLV。
    @Override
    public void onStreamFormatSwitch(
        VeLivePlayer player,
        VeLivePlayerFormat fromStreamFormat,
        VeLivePlayerFormat toStreamFormat,
        VeLivePlayerError error,
        Bundle extraInfo
    ) {
    }
    
  • 监听播放过程中遇到的可恢复问题。当一个流播放失败,但 SDK 即将执行恢复操作,例如切换到降级流时,会触发该回调。这表明播放仍在继续,您无需中断播放流程。您可以通过返回的错误信息了解流播放失败的具体原因,以便进行调试。
    @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 协议拉流

RTM 协议拉流可将直播延迟降低至 1-2 秒,为观众提供优质的直播体验。

然而,RTM 的超低延迟特性也对网络环境提出了更高要求。在网络不稳定的情况下,可能会出现播放延迟、卡顿或失败。如果您希望在 RTM 拉流地址不可用时自动尝试 FLV 等其他协议的拉流地址,可以结合流降级策略或主备流切换使用。详见流降级策略与主备流切换。

说明

仅高级版或试用版 License 支持 RTM 协议拉流。

前提条件

  • 确保您已集成 1.50.1 及以上版本的拉流 SDK。
  • 通过以下任一方式,获取 RTM、FLV 等协议的拉流地址。

接入说明

本文提供以下两个代码示例,分别对应了从简单到复杂的应用场景:

  • 基础场景:演示在主流列表内,当高优先级的 RTM 流播放失败后,如何自动降级到 FLV 等其他协议的流。
  • 进阶场景:在基础场景上,增加主备流切换机制。当主流列表中的所有流(包括 RTM 流和降级流)都不可用时,播放器会自动切换到备流列表进行重试。

建议您从基础场景开始了解。

以下示例代码演示了基础的流降级策略场景,其播放顺序如下:

  1. 首先,尝试播放 RTM 流(优先级 5),最多尝试 3 次。
  2. 如果失败,则降级播放 FLV 流(优先级 4),最多尝试 2 次。
  3. 如果最后依然失败,播放将停止。
// 创建 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 低延时后,FLV 协议拉流可将直播延迟降至 2-3 秒。

说明

使用 FLV 低延时功能时,请确保已集成 1.50.2 及以上版本的 SDK,并使用高级版或试用版 License。

接入说明

在开始播放前,您可通过播放器的 setProperty 高级接口开启 FLV 低延时。调用 setProperty 接口时,需传入一组 Key-Value 配置。

Key

参数名类型说明
VeLivePlayerKeySetParamsLowLatencyFLVVeLivePlayerPropertyFLV 低延时功能对应的属性 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);

QUIC 协议拉流

视频直播拉流 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 地址进行拉流,以降低播放首帧时间。

前提条件

请先获取直播播放地址并解析出 IP 地址。

注意事项

  • 使用 setUrlHostIP 对域名和 IP 地址进行映射时,需在初始化配置中关闭 DNS 预解析功能,即将 enableLiveDNS 设置为 false。
  • 需要在调用 play 开始播放前,调用本方法设置域名和 IP 的映射。

接入说明

使用播放器的 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

接入说明

  1. 配置多档位地址进行播放。代码示例如下所示。
    // 配置多档位流地址
    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();
    
    
  2. 通过调用播放器的 switchResolution 接口可以实现多个档位之间的手动切换。代码示例如下所示。
    mLivePlayer.switchResolution(new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD)); // 切换到超清档位
    
    
  3. 当档位切换成功时,会触发 VeLivePlayerObserver 的 onResolutionSwitch 回调。
    public void onResolutionSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerDef.VeLivePlayerResolutionSwitchReason reason) {
       // 档位切换回调
    }
    
    

自适应码率(ABR)拉流

自适应码率(ABR,adaptive bitrate)拉流可在网络变化时自动切换到更合适的清晰度档位,降低卡顿风险。

说明

  • ABR 拉流支持 RTM-ABR 流和 FLV 流。
  • 仅高级版或试用版 License 支持 ABR 拉流。
  • ABR 拉流支持配置降级流策略。对于 RTM-ABR 流,您可以将 RTM-ABR 拉流地址作为 RTM 流用于降级策略。对于 FLV 流,您可以配置多档位流降级策略:为同一组 ABR 多档位流设置相同的优先级,并配置低优先级降级流。当高优先级的 ABR 多档位流播放失败时,SDK 会自动尝试低优先级降级流。详见流降级策略与主备流切换。

Android 拉流 SDK 支持以下 ABR 拉流模式:

  • RTM-ABR 流:面向 RTM 播放的服务端 ABR 能力。播放器只需使用一个 RTM-ABR 拉流地址,服务端会根据观众的网络状况自动选择并切换清晰度档位,在弱网环境下减少卡顿,同时保留 RTM 的低延迟播放体验。
  • FLV 流:客户端 ABR 能力。您需要提供多个 FLV 拉流地址及对应的码率信息,SDK 会根据网络状况在这些地址之间自动切换。

RTM-ABR 流

注意

仅 1.51.1 及以上版本支持 RTM-ABR 流。

前提条件

  • 添加 ABR 配置时,配置多个 ABR 子流,并在协议类型中选择 RTM-ABR。详见 ABR 配置。
  • 通过以下任一方式获取 RTM-ABR 拉流地址:
    • 功能调试阶段:使用地址生成器,选择起播清晰度档位(后缀)后,在 ABR多码率地址页签获取 RTM 地址。详见地址生成器。
    • 功能正式上线:调用 GeneratePlayURL 或使用服务端 SDK,将 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();

FLV 流

前提条件

获取源流和各档位转码流拉流地址。如您使用了火山引擎视频直播服务,请先登录控制台完成转码配置,再获取拉流地址,获取方法如下所示。

本文的接入说明以下列拉流地址为例。

档位说明拉流地址码率(kbps)
原始(Origin)https://pull.example.com/live/123456.flv2500
超清(UHD)https://pull.example.com/live/123456_uhd.flv2500
高清(HD)https://pull.example.com/live/123456_hd.flv1000
标清(SD)https://pull.example.com/live/123456_sd.flv800
流畅(LD)https://pull.example.com/live/123456_ld.flv500

注意

ABR 功能需要配置多档位拉流地址时,SDK 中每个档位的编码码率需要与转码配置时填写的编码码率一致,配置方法可参考转码配置文档。

接入说明

  1. 配置多档位地址进行播放。代码示例如下所示。
// 配置多档位流地址
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();

  1. ABR 档位自动切换时,会触发 VeLivePlayerObserver 的 onResolutionSwitch 回调。
public void onResolutionSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerDef.VeLivePlayerResolutionSwitchReason reason) {
   // 档位切换回调
}

平滑切档

平滑切档功能可确保在观众手动切换直播清晰度(如超清、高清、标清)时,音画能够无缝衔接,从而避免出现黑屏或卡顿,提升观看体验。

要使用此功能,您需要为播放器配置一个包含多档位清晰度的同源流列表,并开启平滑切档开关。配置后,当观众手动切换清晰度档位时,播放器会在不同码率的流之间平滑过渡,保障直播音画的连续性和稳定性。

说明

平滑切档支持配置降级流策略。您可以为同一组平滑切档流设置相同的优先级,并配置低优先级降级流,当高优先级平滑切档流播放失败时,SDK 会自动尝试降级流。详见流降级策略与主备流切换。

注意

  • 目前平滑切档功能仅适用于 FLV 流。
  • 确保您已集成 1.50.1 及以上版本的拉流 SDK。

前提条件

准备同一源流不同清晰度档位的拉流地址。

如使用视频直播的推流地址进行推流,请确保已完成:

  • 添加域名:在同一域名空间下,添加推流域名和拉流域名。详见添加域名。
  • 配置转码:在该域名空间下,为不同清晰度档位添加转码配置。详见转码配置。
  • 获取拉流地址:获取源流和各档位转码流的拉流地址。
    • 功能调试阶段:使用地址生成器生成拉流地址。
      • 地址类型: 选择拉流地址。
      • 选择域名: 选择添加转码配置时使用的域名空间下的拉流域名。
      • AppName 和 StreamName:填写与推流地址一致的 AppName 和 StreamName。例如推流地址为 rtmp://push.example.com/live/test?authinfo,则 AppName 为 live,StreamName 为 test。
    • 功能正式上线:调用 GeneratePlayURL 或使用服务端 SDK 动态生成拉流地址。
      示例
      下表列出了不同档位的 FLV 拉流地址及对应码率的示例值。
    档位FLV 拉流地址码率(kbps)
    原始(Origin)https://pull.example.com/live/123456.flv2500
    超清(UHD)https://pull.example.com/live/123456_uhd.flv2500
    高清(HD)https://pull.example.com/live/123456_hd.flv1000
    标清(SD)https://pull.example.com/live/123456_sd.flv800
    流畅(LD)https://pull.example.com/live/123456_ld.flv500

接入说明

  1. 配置各清晰度档位的流并将 enableSmoothSwitchResolution 属性设置为 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();
    
  2. 在直播期间,当观众手动切换清晰度档位时,您可以调用 switchResolution 方法切换清晰度档位,并实现平滑切档。示例代码如下所示。
    mLivePlayer.switchResolution(new VeLivePlayerDef.VeLivePlayerResolution(VeLivePlayerDef.VeLivePlayerResolution.VeLivePlayerResolutionUHD)); // 切换到超清档位。
    
  3. 添加清晰度档位切换回调 onResolutionSwitch,监听清晰度档位切换结果。当清晰度档位发生变化时,SDK 可触发该回调,并返回切换后的清晰度档位、档位切换原因等信息。
    @Override
    public void onResolutionSwitch(
        VeLivePlayer player,
        VeLivePlayerResolution resolution,
        VeLivePlayerError error,
        VeLivePlayerResolutionSwitchReason reason
    ) {
    }
    

截图

截图功能允许您在播放器中截取当前直播画面并生成一张图片。

接入说明

  1. 通过调用播放器的 snapshot 接口可以实现截图功能。截图仅在播放器播放成功后可以生效。代码示例如下所示。
    int result = mLivePlayer.snapshot();
    
  2. 截图成功后,会触发 VeLivePlayerObserver 的 onSnapshotComplete 回调,并将截取的图片数据传递给回调方法。代码示例如下所示。
    public void onSnapshotComplete(VeLivePlayer player, Bitmap bitmap) {
       // 截图成功回调,参数 bitmap 为截图的图片数据
    }
    

SEI

SEI(Supplemental Enhancement Information)是直播流中的附加信息,可用于传递自定义数据或元数据。

说明

仅高级版或试用版 License 支持 SEI。

接入说明

  • 字符串 SEI 消息
    1. 在调用 play 方法前,开启播放器的 enableSei 属性。开启后,播放器将接收字符串 SEI 消息。代码示例如下所示。
      // 创建播放器初始化配置。
      VeLivePlayerConfiguration config = new VeLivePlayerConfiguration();
      
      // 开启字符串 SEI 消息接收功能。
      config.enableSei = true;
              
      // 初始化配置。
      mLivePlayer.setConfig(config);
      
    2. 当播放器接收到字符串 SEI 消息时,会触发 onReceiveSeiMessage 回调。代码示例如下所示。
      public void onReceiveSeiMessage(VeLivePlayer player, String message) {
         // 字符串 SEI 消息回调。
      }
      
  • 二进制 SEI 消息
    1. 在调用 play 方法前,开启播放器的 enableBinarySei 属性。开启后,播放器将接收二进制 SEI 消息,且不再触发字符串 SEI 消息回调。代码示例如下所示。
      // 创建播放器初始化配置。
      VeLivePlayerConfiguration config = new VeLivePlayerConfiguration();
      
      // 开启二进制 SEI 消息接收功能。
      config.enableBinarySei = true;
              
      // 初始化配置。
      mLivePlayer.setConfig(config);
      
    2. 当播放器接收到二进制 SEI 消息时,会触发 onReceiveBinarySeiMessage 回调。代码示例如下所示。
      public void onReceiveBinarySeiMessage(VeLivePlayer player, byte[] message) {
         // 二进制 SEI 消息回调。
      }
      

订阅视频数据

通过订阅解码后的视频数据,您可以获取视频帧数据并进行自定义的处理和渲染操作。播放器支持多种视频帧数据的回调,并提供了相应的参数和格式选项。

前提条件

视频帧像素格式和视频数据封装格式的枚举和含义如下表所示。

格式类型枚举说明

视频帧像素格式

VeLivePlayerPixelFormat

VeLivePlayerPixelFormatRGBA32

RGBA32

VeLivePlayerPixelFormatTexture2D 纹理

视频数据封装格式

VeLivePlayerVideoBufferType

VeLivePlayerVideoBufferTypeByteBuffer

ByteBuffer

VeLivePlayerVideoBufferTypeByteArrayByteArray
VeLivePlayerVideoBufferTypeTexture纹理

配置订阅视频数据前,请您根据需要选择格式组合。格式组合需要遵循下表中提供的 VeLivePlayerPixelFormat 和 VeLivePlayerVideoBufferType 的对应关系。

像素格式/封装格式VeLivePlayerPixelFormatRGBA32VeLivePlayerPixelFormatTexture
VeLivePlayerVideoBufferTypeByteBuffer√×
VeLivePlayerVideoBufferTypeByteArray√×
VeLivePlayerVideoBufferTypeTexture×√(性能最优)

接入说明

  1. 您可以调用播放器的 enableVideoFrameObserver 接口开启或关闭视频帧数据订阅功能。接口参数说明如下表所示。
    参数类型说明
    enableboolean是否开启视频帧回调。
    pixelFormatVeLivePlayerPixelFormat视频帧像素格式。
    bufferTypeVeLivePlayerVideoBufferType视频数据封装格式。
    代码示例如下所示。
    mLivePlayer.enableVideoFrameObserver(true, VeLivePlayerPixelFormatRGBA32, VeLivePlayerVideoBufferTypeByteBuffer);
    
  2. 解码后的视频帧数据会通过 VeLivePlayerObserver 的 onRenderVideoFrame 回调返回。代码示例如下所示。
    public void onRenderVideoFrame(VeLivePlayer player, VeLivePlayerVideoFrame videoFrame) {
       // 视频帧数据回调
    }
    
    
    VeLivePlayerVideoFrame 参数说明如下表所示。
    参数类型说明
    bufferTypeVeLivePlayerVideoBufferType视频帧数据封装格式
    pixelFormatVeLivePlayerPixelFormat视频帧像素格式
    widthint视频帧的宽度,单位为 px
    heightint视频帧的高度,单位为 px
    ptslong视频帧的渲染时间戳,单位为 ms
    textureVeLivePlayerVideoTexture当 bufferType 为 VeLivePlayerVideoBufferTypeTexture 时的视频数据,承载用于 OpenGL 渲染的纹理数据
    bufferByteBuffer当 bufferType 为 VeLivePlayerVideoBufferTypeByteBuffer 时的视频数据,承载用于 JNI 层的 Direct Buffer
    databyte[]当 bufferType 为 VeLivePlayerVideoBufferTypeByteArray 时的视频数据,承载用于 Java 层的字节数组数据

订阅音频数据

通过订阅解码后的音频数据,您可以获取音频帧数据并进行自定义的处理和渲染操作。

播放器支持的音频帧数据格式为 PCM Float32,数据封装格式为 ByteArray。

VeLivePlayerAudioBufferType音频数据封装格式
VeLivePlayerAudioBufferTypeByteArrayByteArray

接入说明

  1. 您可以调用播放器的 enableAudioFrameObserver 接口开启或关闭音频帧数据订阅功能。接口参数说明如下表所示。
    参数类型说明
    enableboolean是否开启音频帧回调。
    enableRenderingboolean是否开启播放器渲染。当不需要播放器内部进行音频播放时,可以将该参数值配置为 false。
    代码示例如下所示。
    // 订阅音频帧数据,打开播放器内部音频渲染
    mLivePlayer.enableAudioFrameObserver(true, true);
    
  2. 解码后的音频帧数据会通过 VeLivePlayerObserver 的 onRenderAudioFrame 回调返回。代码示例如下所示。
    void onRenderAudioFrame(VeLivePlayer player, VeLivePlayerAudioFrame audioFrame) {
       // 音频帧数据回调
    }
    
    VeLivePlayerAudioFrame 参数说明如下表所示。
    参数数据类型说明
    bufferTypeVeLivePlayerAudioBufferType音频帧数据封装格式
    sampleRateint音频采样率,单位为 Hz
    channelsint声道数
    bitDepthint音频位深度
    ptslong音频渲染时间戳,单位为 ms
    bufferbyte[]PCM 音频数据
    samplesint音频采样点个数

拉流超分

超分,即超分辨率技术(Super-Resolution, SR)是指从观测到的低分辨率图像重建出相应的高分辨率图像的过程,移动端实时超分,是指利用算法技术在端上对低分辨率的帧进行实时重建,产生高分辨率的帧显示在屏幕上,从而改善视频内容的细节与对比度,全面提升视频的播放清晰度和观看体验的优化手段。

说明

仅高级版或试用版 License 支持拉流超分。

接入说明

  1. 调用播放器的 setEnableSuperResolution 方法开启或关闭拉流超分。
    mLivePlayer.setEnableSuperResolution(true);
    
    参数名类型说明

    enable

    boolean

    是否开启超分。默认值为 false。

    • true:开启。
    • false:关闭。
  2. 开启超分时,如果开启失败,播放器会通过 VeLivePlayerObserver 中的 onStreamFailedOpenSuperResolution 回调进行通知。回调方法签名如下所示。
    void onStreamFailedOpenSuperResolution(VeLivePlayer player, VeLivePlayerError error);
    
    开启超分失败的常见原因如下:
    • 流的实际分辨率不在超分支持范围内。
    • 流的实际帧率不在超分支持范围内。
    • 当前机型不支持超分。

域名解析

直播拉流 SDK 支持调用火山引擎 HTTPDNS 服务对拉流地址的预解析,以此来降低播放首帧时长。

接入说明

  1. 开通云解析 DNS 服务。
  2. 登录移动解析 HTTPDNS 控制台。
  3. 左侧导航栏选择实例信息,记录您的鉴权密钥,包含 SERVICE ID 和 SECRET KEY。
    Image
  4. 在拉流客户端调用 setVeHttpDNSAuth 方法配置调用 HTTPDNS 服务需要使用的鉴权密钥,代码示例如下所示。
    VeLiveCommon.setVeHttpDNSAuth(getApplicationContext(), "http_dns_serviceID", "http_dns_key"); // 分别替换为实际的 Service ID 和 Secret Key。
    
  5. 调用 prefetchDomains 方法进行域名解析,解析成功后的 IP 地址会自动设置给播放器,代码示例如下所示。
    List<String> domains = new ArrayList<String>();
    domains.add("xxx.pull.com"); // 替换为实际拉流域名。
    domains.add("yyy.pull.com"); // 替换为实际拉流域名。
    VeLiveCommon.prefetchDomains(domains);
    

自定义 HTTP 请求头

设置播放器发起 HTTP 请求时携带的自定义请求头。常用于传递鉴权令牌(Token)、Cookie 或业务追踪标识等额外信息。

说明

仅 1.50.2 及以上版本支持自定义 HTTP 请求头。

接入说明

在开始播放前,您可通过播放器的 setProperty 高级接口设置自定义 HTTP 请求头。调用 setProperty 接口时,需传入一组 Key-Value 配置。

Key

参数名类型说明
VeLivePlayerKeySetParamsHttpHeadersVeLivePlayerProperty自定义 HTTP 请求头功能对应的属性 Key。

Value

Value 为 Map<String, String> 类型,表示需要传入一个 Key-Value 形式的映射对象,用于设置自定义 HTTP 请求头。

  • Key:String 类型,请求头名称。
  • Value:String 类型,请求头值。

示例代码如下所示。

  • 如需设置一个 HTTP 请求头
    Map<String, String> headerMap = new HashMap<>();
    headerMap.put("key", "value"); // 分别替换为实际的请求头名称和请求头值。
    mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsHttpHeaders, headerMap);
    
  • 如需设置多个 HTTP 请求头
    Map<String, String> headerMap = new HashMap<>();
    headerMap.put("key1", "value1"); // 分别替换为实际的请求头名称和请求头值。
    headerMap.put("key2", "value2"); // 分别替换为实际的请求头名称和请求头值。
    headerMap.put("key3", "value3"); // 分别替换为实际的请求头名称和请求头值。
    mLivePlayer.setProperty(VeLivePlayerProperty.VeLivePlayerKeySetParamsHttpHeaders, headerMap);
    

H.265 软解和硬解

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 属性,判断当前播放的流是否使用了硬解。

H.266 软解

SDK 高级版或试用版 License 默认开启 H.266 软解,无需额外配置。

视频锐化

视频锐化指在设备本地对视频画面进行增强处理,从而提升画面边缘和纹理细节表现的能力。播放视频时,SDK 可以实时增强画面边缘和纹理细节,从而让画面看起来更清晰,提升观看体验。

说明

仅高级版或试用版 License 支持视频锐化。

接入说明

  1. 调用播放器的 setEnableSharpen 方法开启或关闭视频锐化。
    mLivePlayer.setEnableSharpen(true);
    
    参数名类型说明

    enable

    boolean

    是否开启视频锐化。默认值为 false。

    • true:开启。
    • false:关闭。
  2. 开启视频锐化时,如果开启失败,播放器会通过 VeLivePlayerObserver 的 onStreamFailedOpenSharpen 回调进行通知。回调方法签名如下所示。
    void onStreamFailedOpenSharpen(VeLivePlayer player, VeLivePlayerError error);
    
    开启视频锐化失败的常见原因如下:
    • 流的实际分辨率不在视频锐化支持范围内。
    • 流的实际帧率不在视频锐化支持范围内。
    • 当前机型不支持视频锐化。
    • 当前 License 不支持视频锐化。

画中画

画中画功能通过将播放器窗口缩小并置于界面一角,允许观众在观看直播的同时浏览其他内容或打开其他应用,从而提升用户体验。

前提条件

Android 6.0 及以上系统。

接入说明

  1. 复制 vepicutureinpicture module 代码到您主工程的根目录下。
  2. 修改 vepicutureinpicture/live/build.gradle 中依赖的 SDK 版本号。请将 x.x.x.x 替换为您实际集成的 SDK 版本号。版本号详见 Android 拉流 SDK 发布历史。
    implementation 'com.bytedanceapi:ttsdk-ttlivepull_premium:x.x.x.x'
    
  3. 在工程中引入 vepicutureinpicture module。可参考 VeLiveQuickStartDemo 进行配置。
    include ':vepicutureinpicture:live'
    include ':vepicutureinpicture:base'
    
    api project(path: ':vepicutureinpicture:live')
    
  4. 初始化画中画功能。
    // mLivePlayer 为播放器实例。
    VeLivePictureInPicturePlayerManager mPipManager = new VeLivePictureInPicturePlayerManager(mLivePlayer, context);
    
  5. 设置画中画 Observer,用于处理从画中画恢复正常播放的逻辑。示例代码如下,其中 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) {
                
            }
        }
    });
    
  6. 判断当前 App 是否已获取系统悬浮窗权限。
    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();
            }
        });
    }
    
  7. 在页面内播放直播画面时,画面会显示在 Surface 或 SurfaceHolder 上。接入画中画功能后,也要把同一个 Surface 或 SurfaceHolder 传给画中画实例(即 mPipManager),这样进入画中画模式后才能继续显示当前直播画面。
    // 设置 Surface。
       mLivePlayer.setSurface(surface);
       mPipManager.setSurface(surface);
    
  8. 将播放器回调返回的当前视频宽高传给画中画实例(即 mPipManager)。这样画中画会按视频实际宽高比显示画面。代码示例如下所示。
    mLivePlayer.setVeLivePlayerObserver(new VeLivePlayerObserver() {
        @Override
        public void onVideoSizeChanged(VeLivePlayer player, int width, int height) {
            mPipManager.setVideoSize(width, height);
        }
    });
    
  9. 如需自定义画中画窗口大小,可参考以下示例代码进行配置。
    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);
    
  10. 在开始拉流播放并确认已获取悬浮窗权限后,可开启画中画。
mPipManager.startPictureInPicture();

如当前已进入画中画模式,可停止画中画。

mPipManager.stopPictureInPicture();
  1. 如需判断当前是否已成功显示画中画窗口,可调用以下方法。
boolean showing = mPipManager.isPictureInPictureShowing();
  1. 当不再使用画中画功能时,销毁画中画实例。
mPipManager.destroy();

高级接口配置

去除 SDK 自动拼接的 Query 参数

拉流 SDK 可能会在拉流地址后追加 Query 参数,例如 session_id。这类参数用于标识同一次拉流会话,方便排查播放问题时,在客户端日志和 CDN 日志中定位同一次拉流。如需保持实际请求地址不增加由 SDK 自动追加的 Query 参数,可以开启该功能。开启后,会从实际请求地址中去除 SDK 自动拼接的 Query 参数,但原始拉流地址中已存在的 Query 参数会被保留。

说明

仅 1.52.1 及以上版本支持去除 SDK 自动拼接的 Query 参数。

接入说明

在开始播放前,您可通过播放器的 setProperty 高级接口设置是否去除 SDK 自动拼接的 Query 参数。调用 setProperty 接口时,需传入一组 Key-Value 配置。

Key

参数名类型说明
VeLivePlayerKeySetParamsRemoveQueryParamsVeLivePlayerProperty去除 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
最近更新时间:2026.10.16 00:36:24
这个页面对您有帮助吗?
有用
有用
无用
无用